Skip to content

feat: verify resident apartment-scoped authz + fail-safe approval#40

Merged
ankitsejwal merged 2 commits into
mainfrom
feat/verify-resident-authz
Jul 2, 2026
Merged

feat: verify resident apartment-scoped authz + fail-safe approval#40
ankitsejwal merged 2 commits into
mainfrom
feat/verify-resident-authz

Conversation

@ankitsejwal

Copy link
Copy Markdown
Member

Verifies the resident-apartment visitor authorization (#36) end-to-end and hardens the approval endpoint. No new feature surface — onboarding was already built; this closes the verification gap and fixes a robustness bug found along the way.

Changes

  • Seed a demo PENDING resident (DEV_RESIDENT_ID, no residency) so the admin approval flow and the apartment-scoped authz can be exercised locally.
  • Fail-safe user approval: the approve endpoint used to flip the user to APPROVED then insert the residency, so a bad apartmentId left a half-approved user (APPROVED, no residency). Now it validates the user + apartment exist, inserts the residency, and flips status last — a failure leaves the user PENDING and retryable. (neon-http has no interactive transactions, hence the ordering.)

Verified E2E (Chrome DevTools + live Neon)

  • Onboarding: approved the demo resident via /admin/residents → assigned B-201 → status went PENDING→APPROVED, residency created.
  • Authz (fix(api): scope resident approve/deny to their own apartment #36), acting as the resident via x-user-id:
    • approve own apartment (B-201) → 200
    • approve other apartment (A-101) → 403 not a resident of this apartment
    • deny other apartment → 403
    • admin override on A-101 → 200
  • Approval fail-safe (probe users, then cleaned up): valid apartment → 200, APPROVED + 1 residency; bogus apartment → 404, user stays PENDING + 0 residencies.
  • Full gate green (check-types, lint, test).

Adds DEV_RESIDENT_ID — a PENDING resident with no residency — so the admin
approval flow (assign apartment -> create residency) and the apartment-scoped
visitor authz can be exercised end-to-end locally.
Approve validated nothing and flipped the user to APPROVED before inserting the
residency, so a bad apartmentId left a half-approved user (APPROVED, no
residency). Now it checks the user and apartment exist, inserts the residency,
and flips status last — a failure leaves the user PENDING and retryable. The
neon-http driver has no interactive transactions, hence the careful ordering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant