Skip to main content

Parivar — Data Model & Schema Reference

Companion to the Technical Architecture blueprint. Authoritative source for tables, columns, enums, and relationships in the NestJS + Postgres rebuild.

This document is reconstructed from the live-database exports (database_enums.csv, database_constraints.csv) and the entity-relationship diagram (Parivar_ERD.mmd), cross-checked against the role-based API reference and the implementation guides. Where the older API reference disagreed with the live schema, the live schema wins and the discrepancy is flagged with ⚠️.

Scope note: only application tables are documented. Supabase-internal schemas (auth.*, storage.*, realtime, vault) are replaced wholesale in the rebuild — see §9.


1. How the data model maps to the rebuild​

ConcernCurrent (Supabase)Rebuild (NestJS + Postgres)
Schema ownershippublic schema + Supabase-managed auth/storageSingle app-owned Postgres; one ORM schema (Prisma or TypeORM)
Identity tableauth.users (Supabase)Own users table (or external IdP) + profiles 1:1
EnumsPostgres enum typesKeep as Postgres enums or ORM-level enums + check constraints
FKs / cascadesAs listed in §8Preserve every FK; make cascade/SET NULL explicit per §8
Soft deletedeleted_at, is_disabled, is_active, status columnsSame columns; enforce in repository base query (global scope)
Auditcustomer_activity_log, location_audit_log, assessment_versions, visit_eventsKeep; consider an append-only audit module

🔁 Migration note. In Supabase the client queried public.* directly under RLS. In the rebuild no table is client-reachable; every read/write goes through a NestJS service. The ownership columns below (user_id, client_user_id, nurse_id, parent_id, created_by) stop being RLS predicates and become explicit where clauses in services.


2. Domain map (table inventory)​

41 application tables, grouped into nine bounded contexts. Each maps to the NestJS module noted.

DomainTablesModule
Identity & Accessprofiles, user_roles, otp_verifications, staff_applications, customer_admin_details, nurses, doctors, reactivation_requestsAuthModule, UsersModule, NurseModule, DoctorModule
Patientsparents, parent_health_info, parent_emergency_contacts, admission_formsParentsModule
Visits & Schedulingvisits, visit_events, nurse_working_hours, nurse_leave_requests, monthly_contractsVisitsModule, NurseModule
Clinicalassessments, assessment_versions, first_visit_assessments, wound_care_forms, clinical_modules, email_notificationsClinicalModule
Escalations & Safetyescalations, sos_alerts, nurse_locations, location_audit_logEscalationsModule, NurseModule, AlertsModule
Hospital Coordinationhospital_requests, escort_tasksHospitalModule
Communicationconversations, conversation_participants, messages, voice_messages, notifications, admin_alertsNotificationsModule, PariAIModule, AlertsModule
Nurse Operationsnurse_certifications, nurse_document_signatures, nurse_preferences, nurse_bank_details, didit_webhook_eventsNurseModule
Billing & Referralssubscription_plans, subscriptions, payments, withdrawal_requests, referral_accounts, referrals, referral_commissions, referral_settings, referral_wallet_transactions, customer_activity_logBillingModule, ReferralsModule

3. Enumerated types (application domain)​

These are the real enum values from database_enums.csv. Use them verbatim — several differ from the older API reference.

EnumValuesUsed by
app_rolecustomer, nurse, admin, doctoruser_roles.role, RBAC guards
visit_statuspending_admin_assignment, assigned_to_nurse, in_progress, completed, cancelled, report_submitted, approvedvisits.status
visit_typeroutine, follow_upvisits.visit_type
escalation_typedoctor_review, urgent_health, medication_issue, fall_risk, hospital_support, family_followup, admin_supportescalations.escalation_type
escalation_statusopen, under_review, actioned, closedescalations.status
escalation_severitylow, medium, high, criticalescalations.severity, admin_alerts.severity
general_conditionnormal, weak, dizzy, other, stable, improving, deteriorating, criticalassessments.general_condition
blood_sugar_typefasting, randomassessments.blood_sugar_type, first_visit_assessments.blood_sugar_type
appetite_statusnormal, reduced, poorfirst-visit / clinical intake

⚠️ Discrepancy vs. the old API reference.

  • visit_type is routine / follow_up — not regular / first_assessment / on_demand. "First visit" is determined by the absence of a first_visit_assessments row for the parent (see Clinical Reporting doc §2), not by a visit_type. On-demand bookings are a billing path, not an enum value.
  • escalation_type is the seven clinical categories above — not clinical / safety / logistical.
  • escalation_status is open → under_review → actioned → closed — not open → in_review → resolved.
  • general_condition is a richer set than the old stable/improving/deteriorating/critical.

Update DTOs, validators, and any UI dropdowns to these values.

Supabase-internal enums to drop: aal_level, factor_status, factor_type, code_challenge_method, oauth_*, one_time_token_type, equality_op, buckettype, request_status, action are Supabase/Postgres system types and have no place in the rebuilt app schema (their concerns are handled by the Auth module, object storage, and framework layers).


4. Identity & Access​

profiles — 1:1 with the auth user​

Primary user record. user_id is unique and FKs the auth identity.

ColumnTypeNotes
iduuid PK
user_iduuid FK→users, uniqueAuth identity
nametext
emailtext
phonetext
is_disabledboolMaster disable flag (see Account Lifecycle doc)
disabled_attimestamptz
disabled_reasontexte.g. self_deactivation
review_request_countintReactivation requests counter

user_roles — role assignment (1:many)​

Unique on (user_id, role). A user may hold multiple roles. RBAC reads from here.

ColumnTypeNotes
iduuid PK
user_iduuid FK→profiles
roleapp_rolecustomer / nurse / admin / doctor

nurses — workforce record​

Unique on email and user_id. Scoping key for most nurse data (nurses.user_id = auth.uid()).

ColumnTypeNotes
iduuid PKReferenced as nurse_id everywhere
user_iduuid FK→profiles, unique
nametext
emailtext, unique
statustexte.g. available, on_visit, deactivated
is_activebool
deactivated_attimestamptz

doctors — clinical-oversight record​

Unique on user_id. PK id referenced as doctor_id.

staff_applications — nurse/doctor onboarding​

Unique on email and user_id. Application + KYC pipeline source; supports a reactivation application type (Account Lifecycle doc §7).

customer_admin_details — admin-managed customer metadata​

Unique on user_id.

otp_verifications — login/2FA codes​

6-digit code, 10-min TTL, max 5/email/hour (move rate-limit to Redis — see Architecture doc).

reactivation_requests — disabled-user review requests​

Tracks user_id, email, status (pending/approved), created_at. Enforces the 3-requests-per-7-days rule.


5. Patients​

parents — the patient (elder in Nepal)​

Owned by a customer via user_id. Soft-deleted via deleted_at.

ColumnTypeNotes
iduuid PKparent_id everywhere
user_iduuid FK→profilesOwning customer
nametext
ageint(ERD shows age; old ref showed date_of_birth — confirm which is stored)
relationshiptextmother/father/…
deleted_attimestamptzSoft delete

Likely additional columns from the API reference: city, landmark, lat, lng.

admission_forms — long-form intake (1:many on parent, typically 1)​

FK parent_id. Holds conditions, medications, allergies (jsonb), and is_diabetic (boolean) which drives conditional blood-sugar capture in reports.

parent_health_info — structured health summary​

FK parent_id, unique on parent_id (1:1).

parent_emergency_contacts — contacts (1:many)​

FK parent_id.


6. Visits & Scheduling​

visits — the booking + execution record​

Central table. FKs parent_id, nurse_id (null until assigned). client_user_id denormalises the owning customer for scoping.

ColumnTypeNotes
iduuid PK
parent_iduuid FK→parents
nurse_iduuid FK→nursesNull until assigned
client_user_iduuidOwning customer (scoping key)
statusvisit_statusLifecycle (see §3)
visit_typevisit_typeroutine / follow_up
scheduled_datedate

Lifecycle: pending_admin_assignment → assigned_to_nurse → in_progress → report_submitted → approved; plus completed (ended without report) and cancelled. Admin rejection of a report sends report_submitted → in_progress.

visit_events — append-only timeline​

FK visit_id. One row per status transition / actor action.

nurse_working_hours — weekly availability​

FK nurse_id. day_of_week (0–6), start_time < end_time.

nurse_leave_requests — leave​

FK nurse_id. Full-day/partial; overlap with active visits blocked (409 LEAVE_CONFLICT). Admins may create on behalf of nurses.

monthly_contracts — recurring engagement​

FK nurse_id. Recurring/contracted visit arrangement.


7. Clinical, Escalations, Hospital, Communication, Nurse Ops, Billing​

The clinical tables (assessments, assessment_versions, first_visit_assessments, wound_care_forms, clinical_modules, email_notifications) carry the richest field sets and a full submission/versioning workflow — they are documented in detail in the Clinical Reporting Module companion doc. Summary here:

TableCardinalityKey columnsNotes
assessmentsper visit (regular report)visit_id, parent_id, nurse_id, approval_status, is_draft, version_countMandatory report; draft + 24h edit window
assessment_versionsper editassessment_id, nurse_id, version_number, snapshot jsonbAudit of each submit/edit
first_visit_assessmentsone per parentparent_id, nurse_id, visit_id, is_lockedComprehensive intake; lock-once
wound_care_formsmany per visitparent_id, visit_id, nurse_id, wound_typeAdditive wound records
clinical_modulesoptional per visitvisit_id, nurse_id, parent_idOptional clinical add-ons
email_notificationsper assessment eventassessment_id, parent_id, visit_idOutbound report emails log

Escalations & safety

TableFKsNotes
escalationsvisit_id, parent_id, nurse_idescalation_type (7 values), status (open→under_review→actioned→closed), severity
sos_alertsnurse_id, patient_parent_idNurse SOS with lat/lng; fans out admin email + realtime
nurse_locationsnurse_id (unique, 1 row/nurse)Live GPS; >5 min stale → admin alert
location_audit_lognurse_idHistorical GPS trail

⚠️ The old API reference's standalone incidents table is not in the live schema. Risk/safety events are modelled via escalations (fall_risk, urgent_health, etc.) and admin_alerts. Drop the incidents concept unless a new table is intentionally added.

Hospital coordination

TableFKsNotes
hospital_requestsparent_idCustomer-raised coordination request
escort_taskshospital_request_id, parent_idAdmin-managed escort task

Communication

TableFKsNotes
conversations—Chat thread (PariAI + human)
conversation_participantsconversation_id, user_idUnique (conversation_id, user_id)
messagesconversation_id, voice_message_id, sender_id→profilesText + voice
voice_messages—Transcribed audio (Whisper)
notificationsrelated_visit_id, user_idPer-user in-app feed
admin_alerts7 related_* FKs (visit, admission_form, assessment, escalation, escort_task, hospital_request, parent)Deduped ops alerts; severity-tagged

Nurse operations

TableFKsNotes
nurse_certificationsnurse_idUnique (nurse_id, certification_name)
nurse_document_signaturesnurse_idUnique (nurse_id, document_type); 3 mandatory docs
nurse_preferencesnurse_idSettings
nurse_bank_detailsnurse_idConnectIPS payout details ⚠️ (old ref called this user_bank_details)
didit_webhook_eventsnurse_idKYC webhook log

Billing, payments & referrals

TableFKs / uniqueNotes
subscription_plans—Stripe price catalogue (stripe_price_id)
subscriptionsuser_id, stripe_price_idActive subscription per customer
paymentsuser_idPayment records
withdrawal_requests—Nurse/referrer payouts
referral_accountsuser_id unique, referral_code uniqueReferral wallet summary
referralsreferrer_user_id, referred_user_id (unique)Referral edges
referral_commissionsreferral_id5% commission rows
referral_settings—Commission config
referral_wallet_transactionsuser_idWallet ledger
customer_activity_log—Customer audit trail

8. Foreign keys & referential integrity​

Every FK from database_constraints.csv. Decide a delete policy per relationship (the right column is the recommended rebuild behaviour).

Child tableFK column→ ParentRecommended on-delete
parentsuser_idprofilesRESTRICT (soft-delete parent instead)
admission_formsparent_idparentsCASCADE
parent_health_infoparent_idparentsCASCADE
parent_emergency_contactsparent_idparentsCASCADE
visitsparent_idparentsRESTRICT
visitsnurse_idnursesSET NULL (reassign on nurse removal)
visit_eventsvisit_idvisitsCASCADE
assessmentsvisit_id / parent_id / nurse_idvisits / parents / nursesCASCADE (visit) / RESTRICT / SET NULL
assessment_versionsassessment_id / nurse_idassessments / nursesCASCADE / SET NULL
first_visit_assessmentsparent_id / nurse_id / visit_idparents / nurses / visitsRESTRICT / SET NULL / CASCADE
clinical_modulesvisit_id / nurse_id / parent_idvisits / nurses / parentsCASCADE / SET NULL / RESTRICT
wound_care_formsparent_id / visit_id / nurse_idparents / visits / nursesRESTRICT / CASCADE / SET NULL
email_notificationsassessment_id / parent_id / visit_idassessments / parents / visitsCASCADE
escalationsvisit_id / parent_id / nurse_idvisits / parents / nursesSET NULL / RESTRICT / SET NULL
sos_alertsnurse_id / patient_parent_idnurses / parentsSET NULL / RESTRICT
nurse_locationsnurse_idnursesCASCADE
location_audit_lognurse_idnursesCASCADE
hospital_requestsparent_idparentsRESTRICT
escort_taskshospital_request_id / parent_idhospital_requests / parentsCASCADE / RESTRICT
conversation_participantsconversation_id / user_idconversations / profilesCASCADE
messagesconversation_id / voice_message_idconversations / voice_messagesCASCADE / SET NULL
notificationsrelated_visit_id / user_idvisits / profilesSET NULL / CASCADE
admin_alertsrelated_{visit,admission_form,assessment,escalation,escort_task,hospital_request,parent}_idrespectiveSET NULL (alerts are historical)
nurse_certificationsnurse_idnursesCASCADE
nurse_document_signaturesnurse_idnursesCASCADE
referralsreferrer_user_id / referred_user_idprofilesRESTRICT
referral_commissionsreferral_idreferralsCASCADE
referral_wallet_transactionsuser_idreferral_accountsCASCADE
subscriptionsuser_id / stripe_price_idprofiles / subscription_plansRESTRICT
user_rolesuser_idprofilesCASCADE
profilesuser_idusers (auth)CASCADE

Unique constraints to preserve: profiles.user_id, nurses.email, nurses.user_id, doctors.user_id, customer_admin_details.user_id, staff_applications.email, staff_applications.user_id, referral_accounts.referral_code, referral_accounts.user_id, referrals.referred_user_id, nurse_locations.nurse_id, parent_health_info.parent_id, user_roles(user_id, role), nurse_certifications(nurse_id, certification_name), nurse_document_signatures(nurse_id, document_type), conversation_participants(conversation_id, user_id).

⚠️ The CSV lists user_roles_user_id_role_key as UNIQUE but splits it across two rows; treat it as a composite unique on (user_id, role).


9. What replaces the Supabase-managed schemas​

Supabase schemaPurposeRebuild replacement
auth.*Users, sessions, OAuth, MFA, OTP tokensAuthModule: own users table + JWT (access/refresh), Passport OAuth strategies, OTP in otp_verifications + Redis throttle
storage.*Buckets/objects (reports, wound-photos, staff-documents)S3-compatible storage + StorageService with pre-signed URLs
realtimePostgres CDC channelsSocket.IO gateway emitting curated domain events
vault / secretsFunction secretsEnvironment variables / secret manager

10. Indexing & performance recommendations​

Add these in the rebuild (beyond PK/unique/FK indexes):

  • visits(status), visits(nurse_id, status), visits(client_user_id), visits(scheduled_date) — dashboard and roster queries.
  • assessments(visit_id), assessments(nurse_id, is_draft), assessments(approval_status, admin_viewed) — nurse/admin report lists.
  • escalations(status, created_at desc), escalations(assigned_doctor_id) — doctor queue.
  • admin_alerts(status, severity, created_at desc) — ops dashboard.
  • nurse_locations(nurse_id) (already unique) + a TTL/cleanup job into location_audit_log.
  • notifications(user_id, created_at desc) — feed.
  • Partial index WHERE deleted_at IS NULL on soft-deletable tables (parents).

Cache hot, rarely-changing reads in Redis: app_config/feature flags, maps key, subscription status, on-call doctor lookup, and OTP/SOS/AI rate-limit counters.


End of Data Model & Schema Reference.