Case ownership (master spec §4.5, branch feature/case-ownership) narrows who may
write a signal's status. The three deploys have to happen in an order that is the
reverse of the usual one, or already-released clients break.
Why
firestore.rules currently lets any signed-in non-anonymous user change any
signal's status (isStatusOnlyUpdate). The branch replaces that with
isCaseHolderUpdate, gated on isCaseHolder() — so status becomes reporter-or-holder
only, and a volunteer who wants to move a case takes responsibility for it first
("claim-to-act").
Every already-released build predates that idea. It offers the status dropdown to
everyone and has no way to claim a case. If the rules land first, a user who is
neither the reporter nor the holder taps the dropdown and gets permission-denied,
surfaced as a bare errorUpdatingStatus snackbar — "Failed to update status. Please
try again." — which is untrue and unactionable. Retrying never works.
Order
- Deploy functions first.
caseOwnership, the four takeover triggers, the
events.ts vocabulary. All additive; nothing calls them yet, and the ownership
branch of handleSignalUpdated cannot fire because no caseHolder ever changes.
- Ship the app release. It understands holders, offers claim-to-act, and renders
the ownership timeline rows and inbox entries. During this window both the old and
the new behaviour are permitted — the rules have not narrowed yet — so nothing
breaks while adoption catches up, and the UI is already guiding people to claim.
- Deploy the rules last, once the release has propagated.
Deploy safety
help-a-paw-dev is production despite the name. Treat both deploys as
production deploys.
- Run
cd firestore-tests && npm test before the rules deploy (227 tests, Firestore
and Storage).
- A rules deploy replaces the whole ruleset. Deploy from the merged branch and
re-read the live ruleset afterwards — parallel branches have silently reverted each
other's rules in this repo before (docs/SPECIFICATION.md §13.3).
How we know it's done
Open a pre-existing signal that has no caseHolder field and confirm its reporter
can still change the status. That is the absent-⇒-reporter derivation
(docs/SPECIFICATION.md §12.5d), it is the path that covers every signal in
production today, and it is the one that fails silently if the derivation is wrong.
Recorded in docs/SPECIFICATION.md §4.8 (rollout note) and §14.
Case ownership (master spec §4.5, branch
feature/case-ownership) narrows who maywrite a signal's
status. The three deploys have to happen in an order that is thereverse of the usual one, or already-released clients break.
Why
firestore.rulescurrently lets any signed-in non-anonymous user change anysignal's status (
isStatusOnlyUpdate). The branch replaces that withisCaseHolderUpdate, gated onisCaseHolder()— so status becomes reporter-or-holderonly, and a volunteer who wants to move a case takes responsibility for it first
("claim-to-act").
Every already-released build predates that idea. It offers the status dropdown to
everyone and has no way to claim a case. If the rules land first, a user who is
neither the reporter nor the holder taps the dropdown and gets
permission-denied,surfaced as a bare
errorUpdatingStatussnackbar — "Failed to update status. Pleasetry again." — which is untrue and unactionable. Retrying never works.
Order
caseOwnership, the four takeover triggers, theevents.tsvocabulary. All additive; nothing calls them yet, and the ownershipbranch of
handleSignalUpdatedcannot fire because nocaseHolderever changes.the ownership timeline rows and inbox entries. During this window both the old and
the new behaviour are permitted — the rules have not narrowed yet — so nothing
breaks while adoption catches up, and the UI is already guiding people to claim.
Deploy safety
help-a-paw-devis production despite the name. Treat both deploys asproduction deploys.
cd firestore-tests && npm testbefore the rules deploy (227 tests, Firestoreand Storage).
re-read the live ruleset afterwards — parallel branches have silently reverted each
other's rules in this repo before (
docs/SPECIFICATION.md§13.3).How we know it's done
Open a pre-existing signal that has no
caseHolderfield and confirm its reportercan still change the status. That is the absent-⇒-reporter derivation
(
docs/SPECIFICATION.md§12.5d), it is the path that covers every signal inproduction today, and it is the one that fails silently if the derivation is wrong.
Recorded in
docs/SPECIFICATION.md§4.8 (rollout note) and §14.