← System Map
Parental Care Guide · Internal
System Registries
Collections · Claims · Endpoints
Updated: May 2026
Collections
14
Total
11
OK
3
Warnings
Claims
6
Total
4
OK
2
Orphaned
Endpoints
25
Total
7
Wired
17
Orphaned
1
Missing
Core — User & Family Data
`users`
✓ OK
Practitioner / admin / family user profiles.
Schema
uid · email · full_name · role · profession
license_states[] · plan · monthly_rate · beta
status · baa_accepted · created_at · active_at
Producers
  • users.py:69 — register (full write)
  • users.py:271 — set_user_status (status + ts)
  • admin-approvals.html:433 — updateDoc status (legacy client-side)
Consumers
  • dashboard.html:562 — own profile, status gate
  • admin-approvals.html:335 — list practitioners (role+created_at)
  • family.html:524 — read practitioner profile by id
  • users.py:241 — read in set_user_status
  • auth_verification.py:86 — read for full_name
Rule / Index
  • Rule: self read/write + admin read/write
  • Index: role ASC, created_at DESC
`family_groups`
✓ OK
Top-level family group document. Owned by a practitioner; family members reference via family_group_id claim.
Schema
name · practitioner_id · care_level · status
urgent_flags[] · overdue_task_count · updated_at
Producers
  • new-client.html:748 — addDoc on client create
  • client.html:882,913,922 — updateDoc (flags, etc.)
Consumers
  • dashboard.html:872 — list by practitioner_id
  • client.html:698, crisis-card.html:411, family.html:402, intake.html:454, care-plan.html:328, medications.html:353 — getDoc by id
Rule / Index
  • Rule: owner / family-claim / admin
  • Index: practitioner_id ASC, created_at DESC
`parents`
✓ OK
Parent records, one per parent within a family group. Top-level, keyed by family_group_id.
Schema
family_group_id · practitioner_id · first_name
last_name · care_level · dob · state · invite_email
Producers
  • new-client.html:773 — addDoc on client create
  • client.html:865 — updateDoc parent details
Consumers
  • client.html:699, crisis-card.html:412, family.html:403 — list by family_group_id
Rule / Index / API
  • Rule: canAccessFamilyData / canWriteFamilyData
  • Indexes: none (no orderBy queries)
  • API: routers/parents.py CRUD — correct schema, no client caller
`medications`
✓ OK
Top-level medication records keyed by family_group_id.
Schema
family_group_id · name · dose · frequency · created_at
Producers
  • medications.html:451 — addDoc
Consumers
  • client.html:700, crisis-card.html:413, family.html:404 — list by family_group_id
  • medications.html:354 — list by family_group_id orderBy created_at desc
Rule / Index
  • Rule: canAccessFamilyData / canWriteFamilyData
  • Index: family_group_id ASC, created_at DESC
`session_notes`
✓ OK
Practitioner clinical notes per family group. Top-level, keyed by family_group_id.
Schema
family_group_id · practitioner_id · body · created_at
Producers
  • client.html:960 — addDoc (direct Firestore)
Consumers
  • client.html:701 — list by family_group_id orderBy created_at desc
Rule / Index
  • Rule: practitioner (owns group) + admin only. No family read.
  • Index: family_group_id ASC, created_at DESC
`care_plans`
✓ OK
One care plan per family group. Document id = family_group_id.
Schema
family_group_id · goals · interventions · (TBD sections)
created_at · updated_at
Producers
  • care-plan.html:447,456 — setDoc (merge)
  • intake.html:563 — setDoc (merge from intake)
Consumers
  • care-plan.html:329 — getDoc by family id
  • family.html:405 — getDoc by family id
Rule / Index
  • Rule: practitioner full access, family read, admin full access
  • Indexes: none (doc-id reads only)
Clinical Supplementary
`intake_data`
⚠ Orphan
Practitioner intake form data per family group. Document id = family_group_id.
Schema
family_group_id · intake fields (TBD) · created_at · updated_at
Producers
  • intake.html:575,591 — setDoc (merge)
Consumers
  • None — written but never read
Rule
  • Practitioner-only (no family access)
Producer with no consumer. Either add a reader or remove the producer.
`crisis_info`
✓ OK
Crisis card data per family group. Document id = family_group_id.
Schema
family_group_id · contacts · escalation_steps (TBD)
created_at · updated_at
Producers
  • crisis-card.html:500 — setDoc (merge)
Consumers
  • crisis-card.html:414 — getDoc by family id
Rule
  • Practitioner full access, family read (emergency), admin full access
Messaging & Invitations
`family_messages`
Note
Family-side messaging channel (family.html flow).
Producers
  • family.html:549 — addDoc (family member side)
Consumers
  • None on practitioner side — inbox UI not yet built
Rule
  • Both practitioner and family member can read/write within their group; only sender/admin can edit/delete
Family flow reachable (claim setter + accept page built). Practitioner-side reader UI still to come.
`family_invitations`
✓ OK
Pending invitations from practitioner to family-member email.
Schema
family_group_id · invited_email (lc) · invited_relationship
expires_at · status · invited_by_uid · invited_at
accepted_at · accepted_by_uid · revoked_at
Producers
  • family_groups.py invite — Admin SDK write
  • family_groups.py revoke — Admin SDK update
  • auth_verification.py accept_invite — Admin SDK status update
Consumers
  • auth_verification.py accept_invite — lookup by invited_email + status
Rule / Indexes
  • Rule: practitioner (owns group) read/write; admin full; family never
  • Index: invited_email ASC, status ASC (accept lookup)
  • Index: family_group_id ASC, invited_at DESC (practitioner list)
`care_updates`
✓ OK
Practitioner-posted updates broadcast to the family portal.
Schema
family_group_id · author_uid · body · posted_at · (attachment refs)
Producers
  • client.html postCareUpdate — addDoc (direct Firestore)
Consumers
  • client.html renderCareUpdates — list ordered by posted_at desc
  • family.html renderCareUpdates — list ordered by posted_at desc
Rule / Index
  • Rule: practitioner full access (owned group), family read, admin full
  • Index: family_group_id ASC, posted_at DESC
System & Internal
`email_verification_tokens`
✓ OK
One-time email verification tokens. Server-only; bypasses Firestore rules via Admin SDK.
Producers / Consumers
  • auth_verification.py:98,120,138 — set / delete / get (Admin SDK)
Rule
  • Not needed — Admin SDK bypasses rules (intentional)
`waitlist`
✓ OK
Pre-launch email waitlist. Public create, admin read.
Producers
  • waitlist.html — public create (field-shape constrained)
Consumers
  • waitlist.html:337 — admin-only list orderBy joinedAt desc
Rule
  • Public create with field shape constraint; admin read/update/delete
`aiConversations`
⚠ Dead
AI chat history per user. Rule exists but no code path uses it.
Producers / Consumers
  • None — no producer or consumer in codebase
Rule
  • Own-conversation only
Dead code — no producer or consumer. Remove the rule or wire it up when AI chat ships.
Role Claims
admin
✓ OK
Platform administrator. Granted manually — no UI for provisioning.
Setters
  • scripts/set-claims.mjs — manual CLI
  • scripts/set-admin.js — alternate manual script
Checkers — Client
  • login.html:268 — redirect to /index.html (admin home)
  • dashboard.html:549,554 — gate access; admins skip status check
  • admin-approvals.html:309 — required to view page
  • care-plan.html:312, intake.html:447, crisis-card.html:396, medications.html:337, new-client.html:651, client.html:681 — allowed alongside practitioner
  • family.html:365 — redirected away to dashboard
Checkers — Rules
  • /users — admin read/write on any user doc
  • /family_groups — admin read/update/delete
  • /parents, /medications — via canAccessFamilyData / canWriteFamilyData
  • /waitlist — admin read/update/delete
practitioner
✓ OK
Approved practitioner. Set at signup (pending_activation); re-set / cleared on approve / reject.
Setters
  • users.py:58 — set on /users/register (immediately; status = pending)
  • users.py:254 — re-set on approve → active
  • users.py:260 — cleared (set to {}) on reject
Checkers — Client
  • login.html:271 — redirect to /dashboard.html
  • dashboard.html:549 — required to view page
  • care-plan.html:312, intake.html:447, crisis-card.html:396, medications.html:337, new-client.html:651, client.html:681
  • family.html:365 — redirected away to dashboard
Checkers — Rules
  • isPractitioner() — /family_groups create rule
Edge case (handled)
  • Reject + re-approve: users.py calls revoke_refresh_tokens(uid) on rejection and on re-approval, forcing re-auth.
family
✓ OK
Marks an approved family member with access to family.html.
Setters
  • auth_verification.py accept_invite — set on first invite acceptance; remains set even if all groups later revoked
Checkers
  • login.html:273 — redirect to /family.html
  • crisis-card.html:396, medications.html:337, care-plan.html:312 — allowed alongside practitioner/admin
  • family.html:368 — required (else show waiting state)
Data Claims
family_group_ids
✓ OK
Array of family group ids the family-member has accepted invitations into. Replaced the never-used singular family_group_id.
Setters
  • auth_verification.py accept_invite — appends new group id (dedup)
  • family_groups.py revoke — removes a group id; revokes refresh tokens
Checkers
  • family.html — populates group switcher (fallback to legacy singular for pre-migration accounts)
  • Rules: inFamilyGroups(groupId) helper — /family_groups read, canAccessFamilyData (parents, medications, care_plans, crisis_info), family_messages read
profession
⚠ Orphan
The practitioner's discipline: gcm · elder_law · social_work · financial.
Setters
  • users.py:60,256 — set alongside practitioner claim
Checkers
  • None — never read from the token. UI reads from Firestore user profile instead.
Orphaned: producer with no consumer. Either remove the claim, or use it for client-side gating (would avoid an extra Firestore read).
beta
⚠ Orphan
Beta-tester flag. Defaults to True for all registrations.
Setters
  • users.py:61,257 — defaults to True
Checkers
  • None currently.
Orphaned: intended for future billing gating. Safe to leave, but document the plan before shipping paid tiers.
Summary
Claim Producers Consumers Status
admin Manual scripts Many — client + rules ✓ OK
practitioner API Many — client + rules ✓ OK
profession API None ⚠ Orphan
beta API None ⚠ Orphan (planned)
family API Many — client ✓ OK
family_group_ids API Many — client + rules ✓ OK
Base URL:
Users
POST /users/register
users.py:42
✓ Wired
Auth
require_auth
Callers
signup.html:847
Request → Response
{full_name, profession, license_states[], beta?}
→ {success, uid, role, profession, beta}
Side effects
  • Sets practitioner / profession / beta claims
  • Writes users/{uid} with status: pending_activation
  • Sends welcome email via Brevo
POST /users/{uid}/status
users.py:229
✓ Wired
Auth
require_admin
Callers
admin-approvals.html:441
Request → Response
{status: "active" | "rejected"}
→ {success, uid, status}
Side effects
  • Updates users/{uid}.status + timestamp
  • Sets or clears claims; revokes refresh tokens on reject
  • Sends approval / rejection email via Brevo
Auth & Verification
POST /auth/send-verification
auth_verification.py:60
✓ Wired
Auth / Callers
require_auth signup.html:859
Request → Response
(none) → {success, email} or {success, already_verified: true}
Side effects
  • Creates token in email_verification_tokens
  • Sends verification email via Brevo
POST /auth/verify-email?token=…
auth_verification.py:128
✓ Wired
Auth / Callers
token is the credential verify-email.html:186
Request → Response
?token= query param → {success, uid}
Side effects
  • Marks Firebase Auth email_verified = true
  • Deletes the token doc
POST /auth/accept-invite
auth_verification.py accept_invite
✓ Wired
Auth / Callers
require_auth accept-invite.html
Request → Response
(uses signed-in user's email)
→ {success, accepted, family_group_ids}
Side effects
  • Appends group id to family_group_ids claim
  • Sets family: true claim; writes users doc role: "family"
  • Marks invitations accepted
Family Groups
POST /family-groups/{group_id}/invite
family_groups.py invite_family_member
✓ Wired
Auth / Callers
require_practitioner new-client.html:779
Request → Response
{email, relationship}
→ {success, invitation_id, email_sent}
Side effects
  • Creates / refreshes a family_invitations doc
  • Generates Firebase email-link sign-in URL via Admin SDK
  • Sends invite via Brevo. Requires Firebase email-link sign-in enabled.
POST /family-groups/{group_id}/revoke
family_groups.py revoke_family_member
⚠ Orphan
Auth / Callers
require_practitioner no caller yet
Request → Response
{uid}
→ {success, uid, revoked, remaining_groups}
Side effects
  • Removes group_id from family_group_ids claim; revokes refresh tokens
  • Updates user doc; marks family_invitations records as revoked
No UI calls this yet. To be wired when manage-family-members page is built.
GET POST /family-groups/
family_groups.py:21,30
⚠ Orphan
Auth
require_practitioner
Callers
none
Correct schema; available when client switches to API-mediated reads (currently uses direct Firestore).
GET /family-groups/{group_id}
family_groups.py:49
⚠ Orphan
Auth / Callers
require_practitioner none
Reads top-level family_groups with ownership check. No client caller.
Parents · Medications · Session Notes — Orphaned CRUD
POST GET GET PATCH DELETE
/parents/ & /parents/{parent_id}
⚠ Orphan
Auth
require_practitioner
Callers
none
Create request shape
{family_group_id, first_name, last_name, care_level?, dob?, state?, invite_email?}
Endpoints are correct; live path is direct Firestore write from new-client.html:773.
POST GET GET PATCH DELETE
/medications/ & /medications/{med_id}
⚠ Orphan
Auth
require_practitioner
Callers
none
Create request shape
{family_group_id, name, dosage?, frequency?, prescriber?, start_date?, status?, notes?}
Endpoints correct; live path is direct Firestore write from medications.html.
POST GET GET PATCH DELETE
/session-notes/ & /session-notes/{id}
⚠ Orphan
Auth
require_practitioner
Callers
none
Create request shape
{family_group_id, type?, text, billable_minutes?}
Endpoint is correct; live path is direct Firestore write from client.html.
AI
POST /ai/intake
⚠ ENDPOINT NOT IMPLEMENTED
⚠ Missing
Callers
intake.html:548
Expected request → response
{family_group_id, intake}
→ {sections} or {care_plan}
CRITICAL — caller exists, endpoint not implemented. The intake → AI care plan flow on intake.html is broken.
POST /ai/care-plan-draft
ai.py:15
⚠ Orphan
Auth / Callers
require_practitioner none
Request → Response
{transcript} → {draft}
Wired for future use.
POST /ai/session-note-draft
ai.py:19
⚠ Orphan
Auth / Callers
require_practitioner none
Wired for future use.
POST /ai/ask
ai.py:23
⚠ Orphan
Auth / Callers
require_auth none
Wired for future use.
Notifications
POST /notifications/email
notifications.py:36
⚠ Orphan
Callers
none (may be server-side only)
POST /notifications/sms
notifications.py:53
⚠ Orphan
Callers
none
POST /notifications/reminder
notifications.py:64
⚠ Orphan
Callers
none
Other
POST /contact
contact.py:28
✓ Wired
Auth / Callers
public contact.html:433
GET /health
health.py:5
✓ Wired
Callers
uptime checks only
Summary
Endpoint Served Called Status
POST /users/registerOK
POST /users/{uid}/statusOK
POST /auth/send-verificationOK
POST /auth/verify-emailOK
POST /auth/accept-inviteOK
POST /family-groups/{id}/inviteOK
POST /contactOK
GET /healthOK
POST /family-groups/{id}/revokeorphan (no UI yet)
GET/POST /family-groups/orphan (correct schema)
GET /family-groups/{id}orphan
/parents/ (CRUD ×5)orphan (direct Firestore)
/medications/ (CRUD ×5)orphan (direct Firestore)
/session-notes/ (CRUD ×5)orphan (direct Firestore)
POST /ai/care-plan-draftorphan (planned)
POST /ai/session-note-draftorphan (planned)
POST /ai/askorphan (planned)
POST /notifications/email,/sms,/reminderorphan
POST /ai/intake⚠ MISSING