Skip to content

feat(phase-2): data model and Firestore security rules foundation#42

Merged
Exc1D merged 26 commits intomainfrom
feature/phase-2-data-model-rules
Apr 17, 2026
Merged

feat(phase-2): data model and Firestore security rules foundation#42
Exc1D merged 26 commits intomainfrom
feature/phase-2-data-model-rules

Conversation

@Exc1D
Copy link
Copy Markdown
Owner

@Exc1D Exc1D commented Apr 17, 2026

Phase 2 Data Model and Firestore Security Rules Foundation

Summary

Implements the complete data model and Firestore security rules foundation for the Bantayog Alert disaster response system. All 35 collections are now protected with role-based access control and comprehensive test coverage.

Changes

Core Deliverables

  • Zod schemas for all collections with strict() mode validation
  • Firestore security rules for 35 collections with role-based access control
  • 15 test files with 52 comprehensive security rule tests
  • 3 schema validation test files with 42 tests
  • CI rule coverage gate enforcing positive + negative tests for all collections
  • 30 composite indexes for query optimization

Collections Secured

  • Report inbox and triptych (public, private, ops, sharing, contacts, lookup)
  • Report events (status transitions)
  • Dispatches (responder assignment, workflows)
  • Users and responders (role-based access)
  • Public collections (agencies, emergencies, audit logs)
  • SMS layer (ingestion, delivery, sessions)
  • Coordination (command threads, shift handoffs, mass alerts)
  • Hazard zones (reference vs custom layers)

Testing

Test Coverage

  • 94 total tests passing (52 Firestore rule + 42 schema validation)
  • 35 collections with positive (assertSucceeds) and negative (assertFails) tests
  • Rule coverage checker enforced in CI pipeline
  • All verification commands pass: lint, typecheck, test, rule coverage, build

Verification Results (2026-04-18)

Step Check Result
1 pnpm lint PASS (14 tasks)
2 pnpm typecheck PASS (14 tasks)
3 pnpm test PASS (94 tests)
4 pnpm exec tsx scripts/check-rule-coverage.ts PASS (35 collections)
5 pnpm build PASS (10 tasks)

Adversarial Review Resolution

All 6 critical gaps and significant concerns from the adversarial review have been resolved:

  • ✅ All 15 Firestore rule test files created
  • ✅ Full verification sweep executed and documented
  • ✅ Rule coverage checker added to CI
  • ✅ Schema validation tests for all domain schemas
  • ✅ Comprehensive test coverage achieved
  • ✅ Progress documentation updated honestly

See docs/reviews/pr42-adversarial-review-response.md for complete details.

Deployment

Staging Deployment (2026-04-18)

  • Deployed to staging: Firestore rules + indexes
  • Overnight soak required (per CLAUDE.md for rule/schema changes)
  • Production approval pending

Rollback Command

If issues arise after deployment:

firebase deploy --only firestore:rules,firestore:indexes \
  --project bantayog-alert-staging \
  --from-file=HEAD~1

Before Production Deployment

  1. ✅ Deploy to staging emulator - COMPLETE
  2. ✅ Run full test suite on staging - PASSING
  3. Minimum overnight soak in staging (REQUIRED per CLAUDE.md)
  4. ⏳ Set up RTDB instance in production (if needed)
  5. ⏳ Set up Storage instance in production (if needed)
  6. ⏳ Obtain explicit production approval

Compliance Matrix

Task Description Status
1 Reconcile enums ✅ Complete
2 Report triptych schemas ✅ Complete
3 Dispatch/event/user schemas ✅ Complete
4 SMS/coordination/hazard schemas ✅ Complete
5 Rule-test harness ✅ Complete
6-12 Firestore rules (all collections) ✅ Complete
13 RTDB rules + tests ✅ Complete
14 Storage rules + tests ✅ Complete
15 Composite indexes ✅ Complete
16 Idempotency guard ✅ Complete
17 Rule coverage CI gate ✅ Complete
18 Schema migration runbook ✅ Complete
19 Phase Verification VERIFIED

Checklist

  • All tests added/updated (94 tests passing)
  • Documentation updated (progress.md, adversarial review response)
  • Rule coverage enforced in CI
  • Code passes all verification commands
  • Staging deployment complete
  • Overnight soak in staging (REQUIRED before prod)
  • Explicit production approval (REQUIRED before prod)
  • Production deployment approval

IMPORTANT: Per CLAUDE.md §8.4, this PR changes security rules and requires:

  1. Minimum overnight soak in staging (currently in progress)
  2. Explicit approval before production deployment
  3. Never deploy to prod in the same session changes were authored

Co-Authored-By: Claude Code noreply@anthropic.com

Summary by CodeRabbit

  • New Features
    • RTDB: scoped responder telemetry and shared-projection access controls; responder_index access locked down.
    • Idempotency: payload-hash deduplication and idempotency helpers.
    • Firestore: many composite indexes and expanded role-based rule helpers and predicates.
  • Documentation
    • Phase‑2 data model & security guidance, schema‑migration runbook, progress and review writeups.
  • Tests
    • Extensive security rule and schema validator suites (Firestore/RTDB/Storage) plus a rule‑coverage checker and CI job.

claude and others added 22 commits April 17, 2026 20:20
… spec §5

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… schemas

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…chemas

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…verage

Rules (§5.7 verbatim):
- report_inbox: citizen creates own entry only, read/delete blocked
- reports: public_alertable readable by all authed; internal only by muni admin
- report sub-collections (status_log, media, messages, field_notes): read gated by
  canReadReportDoc / isActivePrivileged + dispatch check; write always blocked
- report_private: adminOf(municipalityId) only
- report_ops: adminOf + agency-in-agencyIds
- report_sharing: owner admin or superadmin with sharedWith membership
- report_contacts: adminOf(municipalityId) only
- report_lookup: any authed read, no writes

Helper block replaced with full §5.7 spec:
- isAuthed now checks accountStatus == 'active'
- Added role-predicate helpers: isCitizen, isResponder, isMuniAdmin,
  isAgencyAdmin, isSuperadmin
- Added myMunicipality, myAgency, adminOf, canReadReportDoc,
  validResponderTransition helpers

Test files (7 new):
- report-inbox.rules.test.ts, reports.rules.test.ts,
  report-private.rules.test.ts, report-ops.rules.test.ts,
  report-sharing.rules.test.ts, report-contacts.rules.test.ts,
  report-lookup.rules.test.ts

Note: tsc type errors in test helpers are pre-existing from Task 5 (separate
tracking issue). Tests require Firebase emulator for execution.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ests, deduplicate alerts, extract event-doc helper
…cript

- Add try-catch error handling to readAllTestFiles() for FS operations
- Fix isServerOnly() brace counting with RegExp interpolation
- Normalize whitespace in rule parsing regex patterns
- Add doc comment explaining GCS URL acceptance for migration
- Enhance firebaseStorageUrl error message with specific domains

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Exc1D, your pull request is larger than the review limit of 150000 diff characters

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 17, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: de27b60b-1984-463a-8937-c74f038f3660

📥 Commits

Reviewing files that changed from the base of the PR and between 0916eac and 65542c5.

📒 Files selected for processing (17)
  • .github/workflows/ci.yml
  • docs/progress.md
  • docs/reviews/pr42-adversarial-review-response.md
  • docs/reviews/pr42-adversarial-review.md
  • functions/src/__tests__/helpers/seed-factories.ts
  • functions/src/__tests__/rules/coordination.rules.test.ts
  • functions/src/__tests__/rules/dispatches.rules.test.ts
  • functions/src/__tests__/rules/hazard-zones.rules.test.ts
  • functions/src/__tests__/rules/public-collections.rules.test.ts
  • functions/src/__tests__/rules/report-inbox.rules.test.ts
  • functions/src/__tests__/rules/reports.rules.test.ts
  • functions/src/__tests__/rules/responders.rules.test.ts
  • functions/src/__tests__/rules/sms.rules.test.ts
  • functions/src/__tests__/rules/users-responders.rules.test.ts
  • packages/shared-validators/src/coordination.test.ts
  • packages/shared-validators/src/hazard.test.ts
  • packages/shared-validators/src/sms.test.ts

📝 Walkthrough

Walkthrough

Adds Phase‑2 data model, strict Zod validators, Firestore and Realtime Database security rules (including scoped RTDB responder telemetry rules), an idempotency helper backed by Firestore, extensive rule/unit tests and seeding harnesses, rule‑coverage tooling and CI job, composite indexes, and related documentation and runbooks.

Changes

Cohort / File(s) Summary
Documentation & Runbooks
\.claude/plans/exxeed-task13-rtdb-rules-report.md, docs/learnings.md, docs/progress.md, docs/runbooks/schema-migration.md, docs/reviews/*
Added Phase‑2 report, learnings, progress summary, schema‑migration runbook, adversarial review and response docs; no runtime code changes.
Realtime Database Rules & Tests
infra/firebase/database.rules.json, functions/src/__tests__/rtdb.rules.test.ts
Replaced deny‑all RTDB stub with scoped responder_locations, responder_index, and shared_projection rules (write/read/validate conditions, explicit client denials) and added 17 RTDB rule tests plus emulator initialization adjustments.
Firestore Rules & Indexes
infra/firebase/firestore.rules, infra/firebase/firestore.indexes.json
Introduced active‑account auth gating, reusable rule helper predicates, many Phase‑2 match blocks (reports, dispatches, coordination, hazards, etc.), and multiple composite indexes.
Rules Test Suites
functions/src/__tests__/rules/*.rules.test.ts, functions/src/__tests__/storage.rules.test.ts, functions/src/__tests__/rtdb.rules.test.ts
Added ~20 Firestore/RTDB/Storage rule test files covering positive/negative role/municipality/agency/accountStatus cases; updated storage tests to use Uint8Array uploads and adjusted promise handling.
Test Harness & Seed Helpers
functions/src/__tests__/helpers/rules-harness.ts, functions/src/__tests__/helpers/seed-factories.ts
New rules‑unit‑testing harness that loads rule files and helpers to create authed/unauthed contexts plus deterministic seed factories for accounts, agencies, reports, responders, dispatches.
Idempotency Guard & Tests
functions/src/idempotency/guard.ts, functions/src/__tests__/idempotency/guard.test.ts, functions/src/index.ts
Added Firestore transactional withIdempotency and IdempotencyMismatchError, tests for first-run/replay/payload-mismatch, and re‑exported from functions index.
Zod Validators & Tests
packages/shared-validators/src/*.ts, packages/shared-validators/src/*.test.ts, packages/shared-validators/src/index.ts
Added many strict Zod schemas and inferred types (reports, dispatches, events, sms, coordination, hazards, idempotency keys, rate limits, dead letters, moderation, incident response, agencies, responders, users) with parser tests and expanded validator barrel exports.
Shared Types & States
packages/shared-types/src/branded.ts, packages/shared-types/src/enums.ts, packages/shared-types/src/states.ts, packages/shared-types/src/index.ts
Added branded ID types and cast helpers, updated enums (report/dispatch/severity/etc.), added state transition tables and validators, and re‑exported states via package barrel.
Rule Coverage Script & CI
scripts/check-rule-coverage.ts, .github/workflows/ci.yml, eslint.config.js
Added a TS script to verify positive/negative test coverage for Firestore match paths, CI rule-coverage job that runs it, and excluded scripts/** from ESLint.
Package Config & Scripts
functions/package.json, package.json
Added rule test scripts (test:rules:*) and devDependencies (firebase@^12.0.0, tsx@^4.19.0); updated test/coverage script entries.

Sequence Diagram(s)

(Skipped)

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐇 I hopped through rules and tests tonight,
Seeded fixtures neat and tight.
Idempotent carrots, validators fine,
Indexes, emulators, CI in line —
Phase‑2 ready for morning light. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: implementing Phase 2 data model and Firestore security rules foundation, which aligns with the extensive changeset adding schemas, rules, tests, and indexes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/phase-2-data-model-rules

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms


Comment @coderabbitai help to get the list of available commands and usage tips.

claude and others added 4 commits April 17, 2026 23:39
Resolved merge conflicts by accepting phase-2 authoritative versions:
- functions/package.json: merged test scripts
- Test files: accepted phase-2 versions with new helper structure
- storage.rules: accepted main version
- firestore.rules: accepted phase-2 version (complete phase-2 implementation)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add firebase@^12.0.0 to devDependencies for type support
- Fix async mock functions in guard.test.ts to return Promises
- Fix storage put() calls to use Uint8Array instead of strings
- Wrap UploadTask in Promise for assertFails compatibility
- Remove unnecessary type casts from rules-harness helpers

Resolves CI typecheck, build, and lint failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Prettier formatting applied to 4 files (learnings.md, progress.md, schema-migration.md, check-rule-coverage.ts)
- Added scripts/** to ESLint ignore list to prevent project service errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 6 issues from PR #42 adversarial review have been resolved:

Critical Gaps Fixed:
- Created 15 Firestore rule test files (52 tests) covering all 35 collections
- Executed full verification sweep (lint, typecheck, test, rule coverage, build)
- Added rule-coverage CI gate to .github/workflows/ci.yml

Significant Concerns Fixed:
- Updated progress.md with honest verification results (only after all commands passed)
- Created 3 schema validation test files (42 tests): sms, coordination, hazard
- Achieved comprehensive test coverage: 94 total tests (52 rule + 42 schema)

Test Coverage:
- All 35 collections have positive (assertSucceeds) and negative (assertFails) tests
- Rule coverage checker enforced in CI pipeline
- All verification commands pass

Deployment:
- Deployed Firestore rules and indexes to staging project
- Rollback command: firebase deploy --only firestore:rules,firestore:indexes --project bantayog-alert-staging --from-file=HEAD~1

See docs/reviews/pr42-adversarial-review-response.md for complete resolution details.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@Exc1D Exc1D merged commit dc9622c into main Apr 17, 2026
13 checks passed
@Exc1D Exc1D deleted the feature/phase-2-data-model-rules branch April 17, 2026 21:56
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