Hugo Fund Formation Platform16 Apr, 05:10 CET

Data Model

Core entities, MFN tables, signal tables, and append-only invariants.

Core entities

TablePurposeKey relationships
funds Fund with name, GP, vintage, target size, lifecycle status Parent of commitments, clauses, documents
investors Beneficial investor entity (e.g. "Temasek") Parent of LPs
lps Legal signer vehicle beneath an investor FK → investors; parent of commitments
commitments LP's participation in one fund — amount, status, SL status, KYC, dates FK → lps, funds, fund_closings
clauses Side letter clause text with version history FK → funds, clause_names; self-ref parent_id for genealogy
clause_assignments Links a clause to a commitment (this LP has this clause) FK → clauses, commitments
documents Uploaded .docx files with parse state, review state, gap-tracking and paragraph counts FK → funds, lps; R2 key for blob

Upload + review tables

Table / columnPurpose
documents.review_state Inbox lifecycle: pendingreviewed | flagged | complete. Drives the upload Inbox tabs.
documents.total_paragraphs + uncovered_paragraph_count Written by parse.ts at finish; surfaced in the review pane as the gap-summary banner ("3 unmapped paragraphs — review?").
documents.gap_reviewed_at Set when reviewer acknowledges the gap banner. Non-destructive — the original uncovered count is preserved for reporting.
documents.last_reviewed_at Stamp of the most recent draft confirmation/rejection. Drives "Continue review" sort order.
clauses.initial_clause_name_id Captures the AI's first classification at parse time. Preserved across reclassification so per-type accuracy stats compare against the original guess.
clause_corrections Append-only log of every reviewer-driven rename/reject/text-edit. Powers the per-type accuracy chips ("MFN: 94% accuracy in this fund").

Investor import tables

TablePurpose
import_jobs One row per investor spreadsheet import — filename, row count, status (completed | undone | running | cancelled | failed), completed_at, undo_expires_at. Powers the 15-minute undo window and SSE progress stream.
import_job_records Join table mapping job → (entity_type, entity_id) for every investor / LP / commitment / category created. Enables FK-ordered undo without polluting hot tables.
mapping_profiles Saved column mappings keyed by header tokens (not raw indices) so reordered files still resolve correctly. Auto-applied via Jaccard ≥ 0.8 header overlap.

MFN tables

TablePurpose
mfn_basic_rulesFund-wide comparator gates (amount, date, closing)
mfn_general_rulesCategory-level include/exclude rules
mfn_individual_rulesPer-LP include/exclude overrides
mfn_electionsLP's election decision per clause (elected / excluded / pending)
mfn_clause_exclusionsCarve-outs at clause level

Signal tables

TablePurpose
fund_eventsAppend-only SITREP signal stream — root events + derived cascades with provenance
activity_logHuman-readable audit trail of every mutation
lp_tasksPer-commitment follow-up tasks with priority + due date

Append-only invariants

Two tables are never updated or deleted. This is a compliance requirement.

All deletes in these tables are logical: rows are never removed from the database or R2. "Restore" and "Checkpoint" operations create new versions.

Ctrl+K to open · ↑↓ navigate · Enter go · Esc close
Copied