| Domain | Tables | Purpose |
| Tenancy & Auth | tenants, users | Multi-tenant isolation, user roles |
| Core Precedents | precedent_objects, precedent_version_history, precedent_audit_log, payer_plans | Clinical denial precedents, versioning, compliance logging |
| Marketplace & Credit | marketplace_clusters, credit_ledger, contribution_scores, marketplace_queries | Network effect clustering, event-sourced credit system |
| Appeals Workflow | appeals, appeal_versions, appeals_audit_log | Appeal submissions, versioning, audit trail |
Total: 13 tables. Connection: Fly Postgres 16. Row count estimate: 0 (seed data), ~10K precedents (production projection).
Entity Relationship Diagram
┌─────────────────────────────────────────────────────────────────┐
│ TENANCY & AUTHENTICATION LAYER │
├─────────────────────────────────────────────────────────────────┤
│ │
│ tenants (id, name, is_active) │
│ ↓ 1:N │
│ users (id, tenant_id, email, name, role) │
│ │
└─────────────────────────────────────────────────────────────────┘
↓ (every table has tenant_id)
┌─────────────────────────────────────────────────────────────────┐
│ CORE PRECEDENT INFRASTRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ precedent_objects │
│ (id, payer, denial_type, loc, cluster_id, status, ...) │
│ ├─ 1:N → precedent_version_history (full state snapshots) │
│ ├─ 1:N → precedent_audit_log (compliance events) │
│ └─ N:M → appeals (precedent referenced in appeal evidence) │
│ │
│ payer_plans (id, payer_name, plan_year, state, coverage_data) │
│ └─ reference for precedent payer/coverage lookup │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ MARKETPLACE & CREDIT SYSTEM │
├─────────────────────────────────────────────────────────────────┤
│ │
│ marketplace_clusters │
│ (cluster_id, payer, denial_type, loc, maturity_tier, ...) │
│ ├─ derived from precedent_objects (cluster_id grouping) │
│ ├─ 1:N → contribution_scores (per tenant, per cluster) │
│ └─ 1:N → marketplace_queries (audit log of cluster access) │
│ │
│ credit_ledger (event-sourced, immutable) │
│ (id, tenant_id, event_type, amount, reference_id, receipt_hash) │
│ ├─ contribution_mint (when precedent created) │
│ ├─ query_burn (when cluster accessed) │
│ ├─ membership_allocation (monthly baseline) │
│ └─ bonus_mint (high-quality contributions) │
│ │
│ contribution_scores (tenant_id, cluster_id, gap_score, total) │
│ └─ computed from credit_ledger and precedent outcomes │
│ │
│ marketplace_queries (tenant_id, cluster_id, credits_spent) │
│ └─ audit log of who queried what and when │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ APPEAL WORKFLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ appeals (id, tenant_id, denial_id, narrative, status, ...) │
│ ├─ created_by: user (who is building the appeal) │
│ ├─ selected_precedent_ids: UUID[] (evidence from precedents) │
│ ├─ 1:N → appeal_versions (draft history, auto-save snapshots) │
│ └─ 1:N → appeals_audit_log (submission events) │
│ │
│ appeal_versions (appeal_id, version_number, snapshot) │
│ └─ immutable full-state snapshots (like precedent_versions) │
│ │
│ appeals_audit_log (appeal_id, event_type, user_id, timestamp) │
│ └─ events: created, saved_draft, validation_run, submitted │
│ │
└─────────────────────────────────────────────────────────────────┘
Key Relationships
1. Multi-Tenancy (Every Table)
Every table has tenant_id except tenants and tenants itself. The tenant middleware in Express ensures all queries filter by tenant automatically.
Pattern: All queries include WHERE tenant_id = $1
2. Precedent Versioning (Immutable History)
When a precedent is created or updated:
Current state is stored in precedent_objects
Full snapshot is written to precedent_version_history (immutable)
Events logged to precedent_audit_log
Why: Compliance audit trail. Investigators can see exactly what changed when.
3. Marketplace (Clustering + Contribution)
Precedents are grouped by cluster_id (format: "Payer | Denial Type |
LOC"):