You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Owner portal: in-portal annual registration request for owned animals #297
An authenticated owner can see that an animal needs its annual registration, but the only offered path is the generic public /animal-registration intake form — re-entering name, contact details, and animal information the system already knows. Follow-up from #295.
Goal
Portal-native registration request: an owner submits a current-year registration request for a linked animal, prefilled from canonical owner/animal data, routed into the existing registration_submissions staff-review queue. Staff remain the authority — approval still creates the authoritative registrations row through the existing flow.
Design (from architecture audit)
Reuse registration_submissions — one canonical staff review queue, one receipt pipeline (claimReceiptSlot + /api/receipts/[submissionId] unchanged), registrations.submission_id evidence link preserved.
Duplicate prevention: partial unique index on (animal_id, requested_year) WHERE status='pending' AND animal_id IS NOT NULL — mirrors owner_requests_pending_dedup; exactly one concurrent submit wins.
Blocks: any registrations row for (animal, year) — active or cancelled; cancelled means the slot is permanently held by staff workflow.
Rejected request → owner sees declined state + contact path (matches public semantics: staff may reopen, owner can't spam).
Owner experience
Register {name} for {year} on unregistered animals opens a prefilled dialog (canonical animal + contact info on file, optional corrections note, optional receipt upload).
After submit: card shows Request submitted — Awaiting SFPCA review; after staff registration, normal registration state.
Owner-scoped rate limit on top of the unique-index dedup.
Receipt path-claim and byte validation unchanged; portal requests use the same route.
Out of scope
Direct owner-created registrations, fee overrides, canonical data mutation, notification channels, production reseed.
Acceptance
Owner can request current-year registration for an eligible animal; staff review it in the existing Intake submissions queue with portal provenance and pre-linked animal; one-click register creates the authoritative row; duplicate/IDOR/already-registered attempts are rejected server-side.
Shipped in #298 (merged as 5811dad): portal-native registration requests land in the existing registration_submissions staff queue with canonical linkage, DB-enforced single-pending dedup, owner-scoped idempotency, and unchanged staff authority over registration creation.
Activity
fix(admin): never create a registration from a rejected submission (#297
fix(portal): scope request idempotency to the caller's person (#297)
feat(portal): authenticated owner registration requests routed into s…
spizeck commentedon Oct 5, 2026
Shipped in #298 (merged as 5811dad): portal-native registration requests land in the existing registration_submissions staff queue with canonical linkage, DB-enforced single-pending dedup, owner-scoped idempotency, and unchanged staff authority over registration creation.