Skip to content

Allow staff to read/manage patient docs and referrals - #61

Open
naasanov wants to merge 3 commits into
mainfrom
nick/firestore-staff-rules
Open

Allow staff to read/manage patient docs and referrals#61
naasanov wants to merge 3 commits into
mainfrom
nick/firestore-staff-rules

Conversation

@naasanov

Copy link
Copy Markdown
Collaborator

Problem

The Patient Dashboard failed to load with "Failed to load patients. Please try again." after the last firestore rules deploy. The rules restricted users reads to a user's own doc (isCurrentUser(uid)), but the dashboard and member page query the users collection for other people's docs. Firestore rejects a list query outright unless the rule permits every doc it could return, so the whole query was denied. The same rules also blocked staff writes (assignment/status/verification) and all referral reads/writes.

Changes (backend/firestore.rules)

  • isStaff() helper — social workers/admins, resolved from the requester's own user doc, guarded by signedIn().
  • /users read — own doc, or staff reading a patient/social_worker doc. Admin docs stay private. (List queries must constrain role, which the existing dashboard queries all do.)
  • /users update — existing self-update branches, or isStaffUserUpdate() limited to assignedSocialWorkerId, assignedSocialWorkerName, status, isVerified, isBanned, updatedAt.
  • /referrals — read for patient owner or staff; create/update for staff (covers Add/Edit and soft-delete via isDeleted); hard delete stays blocked.

Notes / follow-ups

  • isStaff() costs one get() per rule evaluation. If the dashboard gets read-heavy, promote role to a custom auth claim to drop the extra reads.
  • Referral writes are not yet schema-validated (staff can write any shape) — could be tightened like the checklist rules later.

🤖 Generated with Claude Code

The Patient Dashboard and member page query the users collection for
other people's docs (patients, social workers) and write to them
(assignment, status, verification), and manage patient referrals. The
firestore rules only permitted reading/writing one's own user doc and
blocked all referral writes, so these queries were denied with
permission errors.

- Add isStaff() helper (social_worker/admin) via requester's user doc
- Let staff read patient and social_worker user docs (never admin)
- Let staff update assignment/status/verification fields on user docs
- Let staff read/create/update referrals (hard delete still blocked)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
aryavenkatesan and others added 2 commits July 26, 2026 19:31
firestore.rules forked at 85d8674 and the two lines never merged. This
branch has the staff line (isStaff, staff user/referral access); main has
the events line (16a607d), and arya/unverified-patient-changes has the
verify gate (6e0b291). Whichever side was deployed last silently broke
the other, which is why the staff portal looked flaky rather than broken.

Takes the union, plus three fixes that were in neither line:

- events create/update/delete now require isStaff(). The web calendar's
  add/edit/delete form writes client-side (calendar.tsx:224/229/242) and
  every write was hitting `if false`.
- messages update allows an isRead flip on messages you did not send.
  Both lineages had `allow update: if false`, so the web's read receipts
  (member.tsx:394) failed regardless of which side was deployed.
- isChatParticipant guards with exists(). It dereferenced a possibly
  missing chat doc, which errors the rule out instead of evaluating false.

From the staff line, the users read stays widened to plain isStaff()
rather than the role-narrowed form: staff_admin.tsx:139 queries
role in ['social_worker','admin'], and a per-document role condition
makes Firestore reject that list query outright.

From the events/verify line, isOwnEmailVerificationMirrorUpdate stays
deleted so a patient cannot self-approve; isVerified is writable only via
isStaffUserUpdate and admin Cloud Functions.

Also adds isOwnPhoneNumberUpdate so mobile signup (auth.dart:53) can set
its own phoneNumber. users create stays closed on purpose: the
onAuthUserCreated trigger skips seeding when a doc already exists, so an
open create would let a client self-issue role:'admin' and win the race
against the trigger. The residual race that drops the phone number needs
an app-side fix.

Note: this branch predates 16a607d, so firestore.indexes.json here still
lacks the events index and the messages.timestamp fieldOverrides that the
events rules and chat search depend on. Merge main before deploying.

Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants