crm_accounts.organization_id -> organizations.id; contacts/tasks/opportunities all hang from crm_accounts; documents can also point to quotes, work_orders, and generated_reports
This is the real source behind the Customers desk, account activity tabs, commercial follow-up, and SLA/service-policy snapshots.
Service contracts and routines
service_contracts, routines
Both hang from organization_id and crm_account_id; routines can point to service contract, site, system, asset, and default engineer
Explains the Routines account tab, routine health prompts, and why generated work can become either inspections or scheduler tasks.
This is the central office-to-field handoff record. The inspection owns schedule state, completion state, certificates, checklist rows, and visit-note timelines.
pds_system_configs.system_id -> systems.id; pds_test_sessions.inspection_id -> inspections.id; floors hang from sessions; readings/tests hang from floors
This is the specialist pressure-differential data model behind the wizard/config/test flows.
work_orders.quote_id -> quotes.id; work_orders.site_id -> sites.id; work_order_items.work_order_id -> work_orders.id; assignments hang off work orders and users
Work orders are not separate “draft documents”; they are live operational rows with schedule and deployment state.
Receivables and invoice records
crm_invoices, crm_invoice_payments
crm_invoices.account_id -> crm_accounts.id; invoices optionally point to quotes.id or work_orders.id; crm_invoices.source_key identifies the source; payments point to invoices
This is the finance desk’s AR model, ready-to-invoice candidate dedupe layer, and bridge from commercial/execution work into billing state.
Contractors and grants are org-scoped; grants point to work orders and optional recipient users; submissions point to grants, contractors, and work orders
This model lets an external app user receive a native job pack without joining the sending organization, then submit staged evidence for admin review.
deployment items hang off batches and optionally point to engineers; notifications hang off batches and engineers
These tables explain how draft scheduling becomes engineer-visible deployed work.
Customer appointment notifications
scheduler_customer_notifications
Notifications hang from organization plus scheduler entity type/id and optional customer contact
Explains customer appointment notification history for exact-dated offered or confirmed visits.
Embedded scheduling state on live work
inspections.deployment_state, work_orders.deployment_state, booking status, engineer visibility, bucket, and routine fields
live work rows track deployer, last deployment batch, booking status, field visibility, and routine generation identity
These fields explain why work can exist but still not be field-live yet, why locked visits block movement, and why generated routine work can be traced.
Packages point to organization, site, account, and creator; items point to source records by source type/id; grants point to CRM contact, customer user, or invited email
CRM, org-admin, policy, and most billing/admin tables are hard tenant-scoped and usually cascade on org delete.
Nullable organization_id tables
Many personal-first operational tables such as sites, work_orders, scheduler tables, AI tables, reports, and collaboration tables can survive outside an org or remain after org detachment.
User-owned operational records
sites.user_id, quotes.user_id, work_orders.user_id, and many AI/API records explain why personal and org workflows coexist.
Role resolution lives in membership, not in the core user row
organization_members.role, can_manage_schedule, and can_be_scheduled are what matter for workspace behavior.
Deucalion does not rely on one big customer-facing media table for core inspection evidence. Instead, evidence is usually embedded on the owning records:
Draft Manager represents local unsynced inspection work before it hardens into server-side inspection, note, defect, or evidence records.
Pending photo uploads are a sync-state concern first; once uploaded, their references are stored on the owning row rather than in a separate evidence table.
Certificate generation is mostly inspection-backed plus template-backed, not a separate certificate-record family.