/* ============================================================ Contracts hub — the customer-contract domain model (registry). Reuses the SAME CX_DASH framework as Finance: the Artifacts page is a grid of data-product cards; clicking a card opens the full artifact in the drawer (Artifact / Data / Control / Context). Content pack: window.CON_DASH (tabs/contracts_dashboard_content.js). ============================================================ */ function ContractsDashboard() { const hostRef = React.useRef(null); React.useEffect(() => { const con = window.CON_DASH; const host = hostRef.current; if (!window.ensureFinCxGlobal || !window.ensureFinCxGlobal() || !con || !host) return; if (window.registerCxPack) window.registerCxPack(con); host.innerHTML = '
' + '
' + con.cardsHtml + '
' + '
'; return () => { try { if (window.closeFull) window.closeFull(); } catch (e) {} try { if (window.closeDrawer) window.closeDrawer(); } catch (e) {} document.body.style.overflow = ''; host.innerHTML = ''; }; }, []); return
; } window.ContractsDashboard = ContractsDashboard; /* ============================================================ Contracts — Model page. A registry domain's "model" is the ENCODING: what we extracted from the documents, where each field came from, and who consumes it. Not a Finance-style statement stack — its own shape. ============================================================ */ function ContractsModel() { const C = { ink: 'var(--fg-dark)', base: 'var(--fg-base)', muted: 'var(--fg-muted)', line: 'var(--border-subtle, rgba(38,24,17,0.10))', panel: 'var(--bg-panel)', green: 'var(--accent-green)', blue: 'var(--accent-blue)', purple: 'var(--accent-purple-ai)', grey: '#8A8580', red: 'var(--accent-red)', }; const s = (window.CONTRACTS_REVIEW || { stats: {} }).stats || {}; // Lineage: source → extraction → ODP → ADP → consumer const LINEAGE = [ { label: 'Legal corpus', sub: s.total ? s.total + ' signed PDFs' : 'signed PDFs', color: C.blue }, { label: 'AI extraction', sub: 'read each document', color: C.purple, proc: true }, { label: 'Tabular Review', sub: 'ODP · structured', color: C.grey }, { label: 'Expiration Schedule', sub: 'ADP · computed', color: C.purple }, { label: 'Finance', sub: 'consumes terms', color: C.green }, ]; // The encoding schema — what we've pulled out of each contract. const FIELDS = [ ['Party', 'entity ref', 'MSA cover / signature block', 'link → Customers', 'Commercial', false], ['Contract type', 'enum · MSA / SOW', 'Document header', 'attribute', '—', false], ['Model', 'enum · Turnkey / Tolling', 'Pricing clause', 'attribute', 'Finance · COGS', false], ['Committed value', 'money', 'Volume-commitment clause', 'attribute', 'Finance · revenue backlog', false], ['Term start / end', 'date', 'Term clause', 'attribute', 'Expiration schedule · Finance', false], ['Renewal type', 'enum', 'Renewal clause', 'attribute', 'Expiration schedule', false], ['Pricing basis', 'text', 'Pricing clause', 'attribute', 'Finance · margin', false], ['Status', 'enum', 'Register + events', 'attribute', 'Finance · AR', false], ['Quality certs · indemnity · insurance · LoL', 'flags / text', 'Obligations clause', 'not yet extracted', 'future', true], ]; const HEAD = ['Field', 'Type', 'Extracted from', 'Encoded as', 'Feeds']; const CHECKS = [ ['Coverage', (s.total || 0) + ' of ' + (s.total || 0) + ' contracts have a source PDF (100%)'], ['Reconciliation', 'Extracted committed value reconciles to the CLM register'], ['Cross-domain tie', 'Committed ' + (s.committed || '') + ' ties to Finance’s revenue backlog'], ['Scope', '8 fields extracted per contract · clause-level fields (obligations) not yet extracted'], ]; const Chip = (n, i) => ( {i > 0 && }
{n.label}
{n.sub}
); return (
{/* topbar */}
Contracts Model
A registry — {s.total} contracts encoded from their signed documents
{/* lineage */}
Lineage
{LINEAGE.map(Chip)}
{/* encoding schema */}
What we’ve encoded
the fields extracted from every contract, with provenance and consumer
{HEAD.map((h) => ( ))} {FIELDS.map((f, ri) => ( ))}
{h}
{f[0]} {f[1]} {f[2]} {f[3]} {f[4]}
{/* coverage & checks */}
Coverage & checks
{CHECKS.map(([k, v]) => (
{k}
{v}
))}
); } window.ContractsModel = ContractsModel;