03 · Persistence
Data Model
Stack-agnostic. Types are indicative — use the equivalent in the chosen stack/DB.
Tracking fields on every entity
| Field | Type | Notes |
|---|---|---|
| id | uuid | primary key |
| deal_id | uuid | shared Deal Thread id |
| status | enum | validated by the state machine |
| current_owner_id | uuid → User | who is responsible right now |
| owner_team | enum(Team) | Sales / Purchase / Production / QA / Logistics |
| created_at / updated_at | timestamp |
Primary thread entities
All share one deal_id so the thread is queryable end-to-end.
Deal (thread root)
company · primary_contact · stage · status · current_owner · owner_team · value · source
Lead
company · source · phone · email · enrichment_data (enrichment worker — deferred) · manager_approved_by · assigned_at
Opportunity
requirements · product_spec · attachments[]
Quotation → QuoteLine
quote_no · priced_by (Purchase) · sent_at · tat_due_at · lines[product, qty, unit_price, currency]
Sample
sample_no · prepared_by · qa_inspected_by · dispatched_at · feedback · outcome
Contract
template_id · document_id · status · confirmed_at · final_document_id
Order (post-sales)
order_no · production_plan · packaging_status · shipment_id · payment_status · sap_ref
Supporting entities
| Entity | Key fields |
|---|---|
| User | name · email · role (SalesRep / Manager / TopMgmt / TeamMember / Client) · team · active |
| Task | entity_ref · title · assignee · stage · due_at · sla_minutes · status · escalation_level |
| StatusHistory | from_status · to_status · changed_by · changed_at (append-only) |
| ActivityLog | action · actor · from_owner · to_owner · meta · created_at (immutable) |
| Document | type (Invoice / Certificate / BL / Contract) · file_ref · visible_in_portal · uploaded_by |
| Notification | user · channel · subject · body · related_entity · read |
| Product / Service | name · type (Product/Service) · category · raw_materials (BOM) · active |
| ProductTeamMap | product_id · owner_team — responsible team(s) per product |
| DealProduct | deal_id · product_id — products selected on the lead; routes team access (RBAC §5) |
Status enums by stage
Lead NEW_LEAD → ENRICHED → MANAGER_APPROVAL → ASSIGNED → CONNECTED
Opportunity OPPORTUNITY
Quotation QUOTE_REQUESTED → QUOTE_SHELL → PRICING_ADDED → QUOTE_SENT
Sample SAMPLE_REQUESTED → IN_PRODUCTION → IN_QA → DISPATCHED → FEEDBACK_AWAITED → APPROVED | REJECTED
Contract DOCS_REQUESTED → DOCS_PROVIDED → CLIENT_APPROVED → CONTRACT_DRAFT → CONTRACT_CONFIRMED
Order IN_PRODUCTION → PACKAGED → SHIPPED → PAYMENT → COMPLETED
Opportunity OPPORTUNITY
Quotation QUOTE_REQUESTED → QUOTE_SHELL → PRICING_ADDED → QUOTE_SENT
Sample SAMPLE_REQUESTED → IN_PRODUCTION → IN_QA → DISPATCHED → FEEDBACK_AWAITED → APPROVED | REJECTED
Contract DOCS_REQUESTED → DOCS_PROVIDED → CLIENT_APPROVED → CONTRACT_DRAFT → CONTRACT_CONFIRMED
Order IN_PRODUCTION → PACKAGED → SHIPPED → PAYMENT → COMPLETED
Key relationships
- One Deal (thread) ⟶ zero/one of each stage record, all sharing
deal_id. - One entity ⟶ many
StatusHistory,ActivityLog,Task,Documentrows. - One User belongs to one Team; can be
current_ownerof many entities.