Start Here
A reference data model for contract, agreement, obligation, supplier, and spend data — designed for SLA-backed document-AI platforms operating at enterprise scale. The principles, the diagram, and how to use the rest of this guide.
Scope
The model covers:
- Suppliers and supplier hierarchies (parent companies, subsidiaries).
- Documents (physical files: contracts, amendments, invoices, POs).
- Agreements (logical contracts — one agreement = many documents).
- Obligations (extracted commitments per agreement, versioned by extraction).
- Spend (invoice/PO actuals, linked to agreements where possible).
- Extraction provenance and quality artifacts.
It does not cover the CLM workflow layer (approval routing, e-signature, drafting). That's a separate product surface; the model here treats the signed document as the input.
Design principles
1. Separate physical from logical
A document is the file; an agreement is the commitment. A signed MSA, two amendments, and three SOWs are four documents and one agreement. Most analytical queries operate on agreements; most debugging operates on documents. The schema must support both natively.
2. Versioned extractions, never overwrite
When a new model version re-extracts a document, the old extraction stays for audit. Extractions are keyed by (document_id, model_version). Marts present the "current" view via a row-effective-from / row-effective-to pattern.
3. Canonicalize, but preserve the raw
Supplier names get resolved to canonical IDs. Raw extracted names are stored alongside, with the resolution method and confidence. If the resolution turns out to be wrong, you can re-resolve without re-extracting.
4. Stable IDs from content
document_id = hash of file contents + customer_id. Deterministic; re-ingest is idempotent. extraction_id = document_id + model_version. agreement_id is platform-assigned (because agreement-document linkage isn't always derivable from content).
5. Provenance on every extracted value
Every extracted field carries the page and bounding box it came from. Auditability and debugging both depend on this. Without it, the platform can't answer "why does the model say the renewal term is 12 months?"
6. Temporal awareness, not temporal everywhere
Agreement status changes over time; supplier hierarchies change; obligation status changes. The model uses SCD-2-style versioning on agreements and obligations, but not on every entity (that would be operational overhead with no analytical payoff).
The model in one diagram
customers (tenant boundary; all other tables FK to customer_id)
│
├── suppliers ───────┐ supplier_id, canonical_name, parent_supplier_id
│ │
│ ▼
├── agreements ──────┘ agreement_id, supplier_id, parent_agreement_id,
│ │ effective_date, current_term_end, status
│ │
│ ├── document_agreement_links (M:N)
│ │
│ ├── obligations obligation_id, agreement_id, obligation_type,
│ │ value, due_at, status, confidence
│ │
│ └── spend ──┐ spend_id, supplier_id, agreement_id (nullable),
│ │ amount, currency, accrued_at
│ │
├── documents │ document_id, source_uri, file_hash,
│ │ │ doc_class, ingested_at, page_count
│ │
│ └── extractions extraction_id (=document_id+model_version),
│ fields (JSONB), confidence per field,
│ provenance per field
│
└── supplier_name_resolutions raw_name, resolved_supplier_id,
resolution_method, confidence
How to use this reference
- Reading from scratch? 01 → 09 in order. Each chapter builds on the prior. ~2 hours of focused reading.
- Looking up a query? Jump to 07-sql-pattern-library. The patterns are named ("renewals due in 90 days," "off-contract spend with supplier rollup," etc.) and cross-referenced into the modeling chapters where the underlying decisions are explained.
- Adapting to your platform's variant? 01 has the rationale per design decision. Most variants substitute one piece (e.g., a different obligation type taxonomy, customer-specific extension tables); the rest of the model stays.
- Evolving the schema in production? 08-schema-evolution has the backward-compatible migration recipes.
- Adding dbt tests? 09-quality-tests-dbt.