Skip to content

Owner portal: in-portal annual registration request for owned animals #297

Closed

Description

@spizeck

Problem

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.
  • Additive columns: source ('public' default / 'portal'), animal_id, ownership_id, auth_identity_id, requested_year, owner_note (bounded corrections text); populate existing person_id.
  • 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.

Security

  • requireOwner + getOwnedOwnership reauthorization server-side (no client-trusted ids); fabricated/foreign animal ids rejected.
  • 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.

Activity

  1. spizeck commented on Oct 5, 2026

    @spizeck
    OwnerAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions