← Back to Platform Architecture
Precedent Objects — Core Domain Model
The precedent_objects table is the heart of Stratum Platform. It stores clinical denial decisions with full context: what was denied, why, what evidence supports an appeal, and what the outcome was.
Schema Definition
CREATE TABLE precedent_objects (
id UUID PRIMARY KEY,
-- Core Identification
precedent_name TEXT NOT NULL,
cluster_id TEXT NOT NULL, -- "Payer | Denial Type |
LOC"
-- Payer & Clinical Context
payer TEXT NOT NULL, -- Constraint: Anthem, UHC, Cigna, Aetna, BCBS, Magellan, Optum, Other
denial_type TEXT NOT NULL, -- Medical Necessity, Level of Care, Frequency Limit, etc.
loc TEXT, -- Level of Care: PHP, IOP, SUD Residential, SUD Outpatient, ED
criteria_source TEXT[], -- Array of criteria sources (e.g., ["parity law", "medical necessity guidelines"])
-- Evidence & Narrative (JSONB)
policy_reference JSONB NOT NULL, -- What specific policy denied this?
denial_trigger TEXT NOT NULL, -- Exact trigger for denial (e.g., "Frequency limit exceeded")
evidence_kit JSONB NOT NULL, -- {"required": [], "recommended": [], "optional": []}
narrative_template JSONB NOT NULL, -- Appeal narrative structure
traceability_ledger JSONB NOT NULL, -- Array of decision trace entries
-- Outcome Data
outcome TEXT, -- Won, Lost, Partial, Pending, Abandoned
win_reason TEXT, -- Evidence Combination, Narrative Framing, Escalation Path, etc.
time_to_resolution_days INTEGER, -- Days from denial to resolution
outcome_notes TEXT,
-- Evidence Strength
evidence_score TEXT, -- Minimal, Moderate, Strong
-- Versioning
version INTEGER NOT NULL DEFAULT 1, -- Current version number
last_validated_date DATE,
version_notes TEXT,
-- Reuse Tracking
reuse_count INTEGER NOT NULL DEFAULT 0,
-- Workflow State
status TEXT NOT NULL DEFAULT 'New', -- New, Evidence Gathering, Under Review, Complete, Archived
-- Confidence & Attribution (§11)
confidence JSONB NOT NULL, -- {"expert_consensus": "low| medium |
high", "number_of_validated_cases": N}
-- Compliance (§12 — 42 CFR Part 2 + HIPAA)
data_origin_type TEXT NOT NULL DEFAULT 'non-SUD', -- SUD or non-SUD
consent_basis TEXT, -- Reference to patient consent record (SUD only)
sharing_restrictions TEXT NOT NULL DEFAULT 'none', -- none, consent_required, originator_only
-- Attribution & Audit
owner_id UUID REFERENCES users(id),
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_by UUID REFERENCES users(id),
updated_at TIMESTAMPTZ DEFAULT NOW(),
-- Tenant Isolation
tenant_id UUID NOT NULL REFERENCES tenants(id),
-- Notes
notes TEXT,
-- Marketplace
marketplace_credited_at TIMESTAMPTZ
);
Core Fields Explained
Identification
precedent_name — Human-readable name (e.g., "Cigna IOP Frequency Limit Victory 2024")
cluster_id — Deterministic cluster key: "${payer} | ${denial_type} | ${loc}" or "${payer} | ${denial_type} |
" for null LOC
Used to group related precedents for marketplace
Denial Context
payer — Insurance company that denied the claim
denial_type — Category of denial (Medical Necessity, Level of Care, Frequency Limit, etc.)
loc — Level of care denied (PHP, IOP, SUD Residential, etc.) or NULL for non-LOC denials
criteria_source — Array of regulatory/policy sources (e.g., ["parity law", "state BH standards"])
Evidence & Narrative (JSONB Fields)
These are flexible JSONB to allow schema evolution:
policy_reference
{
"policy_section": "Section 2.3.1",
"plan_year": 2024,
"document_url": "https://...",
"exact_language": "Prior authorization required for IOP > 60 days"
}
evidence_kit (what evidence appeals must include)
{
"required": [
"Clinical progress notes from past 30 days",
"Psychiatric evaluation documenting ongoing need",
"Functional assessment (GAF or equivalent)"
],
"recommended": [
"Collateral contact documentation",
"Medication list and psychiatric history"
],
"optional": [
"Research articles on treatment efficacy"
]
}
narrative_template (how to structure appeal narrative)
{
"title": "Appeal for Cigna IOP Level of Care",
"sections": [
{
"name": "Clinical Justification",
"description": "Why is IOP medically necessary?"
},
{
"name": "Evidence of Functional Impact",
"description": "How would step-down harm the patient?"
}
]
}
traceability_ledger (audit trail of decisions)
[
{
"step": 1,
"action": "Denial issued",
"date": "2024-01-15",
"actor": "UnitedHealthcare",
"reason": "Frequency limit exceeded"
},
{
"step": 2,
"action": "Appeal filed",
"date": "2024-01-20",
"actor": "Provider RCM staff",
"evidence": ["clinical notes", "GAF"]
}
]
Outcome
outcome — Result of appeal (Won, Lost, Partial, Pending, Abandoned)
win_reason — Why appeal succeeded (Evidence Combination, Narrative Framing, etc.)
time_to_resolution_days — How long appeal took
evidence_score — Strength of evidence in this precedent (Minimal, Moderate, Strong)
Versioning
version — Current version (increments on each update)
last_validated_date — Last date a clinician reviewed this
version_notes — What changed in this version
Compliance (§12 — Critical for HIPAA/42 CFR Part 2)
data_origin_type — "SUD" (Substance Use Disorder) or "non-SUD"
consent_basis — Reference to patient consent record (required for SUD)
sharing_restrictions — "none" (can share freely), "consent_required" (need explicit consent), "originator_only" (only original provider can access)
Critical Constraint: If data_origin_type = 'SUD', then sharing_restrictions must be 'consent_required' or 'originator_only'. Cannot share SUD data freely.
Indexes
-- Exact match lookups
idx_precedent_tenant -- Filter by tenant first
idx_precedent_payer -- Search by payer
idx_precedent_denial_type -- Search by denial type
idx_precedent_loc -- Search by level of care
idx_precedent_status -- Filter by status (New, Complete, etc.)
idx_precedent_cluster -- Grouping for marketplace
-- Range queries
idx_precedent_last_validated DESC -- Find outdated precedents
idx_precedent_data_origin -- Filter SUD vs non-SUD
-- JSONB queries
idx_evidence_kit_gin -- Search evidence kit contents
idx_traceability_gin -- Search traceability ledger
Constraints
Role enforcement: Payer, denial_type, loc must match allowlist
SUD compliance: SUD data MUST have non-'none' sharing_restrictions
Status machine: status must be New, Evidence Gathering, Under Review, Complete, or Archived
Outcome states: Outcome must be Won, Lost, Partial, Pending, or Abandoned
Query Examples
Find all precedents for specific payer/LOC/denial_type:
SELECT FROM precedent_objects
WHERE tenant_id = $1 AND payer = $2 AND denial_type = $3 AND loc = $4
ORDER BY created_at DESC
LIMIT 25;
Find all SUD precedents (compliance audit):
SELECT FROM precedent_objects
WHERE tenant_id = $1 AND data_origin_type = 'SUD'
AND sharing_restrictions = 'none' -- This should NEVER match
LIMIT 100;
Find outdated precedents (older than 1 year):
SELECT FROM precedent_objects
WHERE tenant_id = $1 AND last_validated_date < CURRENT_DATE - INTERVAL '1 year'
ORDER BY last_validated_date ASC;
See also
Versioning & Immutability — How updates work
Audit Log — Compliance events
Marketplace Tables — How cluster_id is used
Code reference
src/db/schema.sql — Full table definition
src/types/index.ts — TypeScript PrecedentObject interface
src/models/precedent.ts — Query helpers (select, insert, update, versioning)
src/routes/precedents.ts — API endpoints (CRUD, versioning, export)