Phase 6.1 — Enterprise CRM Core Business Entities
| Field |
Value |
| Status |
Complete |
| Module |
crm |
| Version |
0.6.1.0 |
| Database |
crm_db |
| Migration |
0002_phase_61_entities |
| Depends On |
Phase 6.0 |
Goal
Implement the Sales CRM core business entities only: leads, contacts, organizations, lookups, tags, addresses, custom fields, notes, attachments (file references), and audit.
Out of scope: Workflow, Automation, Customer360, Marketing, Communication, Helpdesk, Analytics, AI, Accounting / Restaurant / Marketplace integrations.
Created Models
Core aggregates (expanded)
| Model |
Table |
Notes |
| Lead |
leads |
lead_number, names, company, phones, source/status refs, owner, priority, soft delete, actors |
| Contact |
contacts |
personal/business, multi phone/email JSON, social links, birthday, soft delete |
| Organization |
organizations |
company/branch/department, legal/trade names, tax IDs, parent org, soft delete |
Lookups
| Model |
Table |
| LeadSource |
lead_sources |
| LeadStatusDefinition |
lead_statuses |
| ContactType |
contact_types |
| OrganizationType |
organization_types |
| OrganizationIndustry |
organization_industries |
Supporting
| Model |
Table |
| LeadAssignment |
lead_assignments |
| CrmTag |
crm_tags |
| LeadTag / ContactTag / OrganizationTag |
lead_tags, contact_tags, organization_tags |
| CrmCustomField / CrmCustomFieldValue |
crm_custom_fields, crm_custom_field_values |
| CrmAddress |
crm_addresses |
| CrmNote / CrmNoteVersion |
crm_notes, crm_note_versions |
| CrmAttachment |
crm_attachments (file_storage_id only) |
| CrmAuditLog |
crm_audit |
Phase 6.0 aggregates retained: Pipeline, PipelineStage, Opportunity, SalesActivity, Quote.
Relationships
UUID references within crm_db only (no SQLAlchemy relationship graphs between aggregates):
- Lead →
lead_source_id, lead_status_id, contact_id, organization_id
- Contact →
contact_type_id, organization_id
- Organization →
organization_type_id, organization_industry_id, parent_organization_id
- Addresses / Notes / Attachments / CustomFieldValues →
(entity_type, entity_id)
- Tag join tables → entity id +
tag_id
- Attachment →
file_storage_id (File Storage service contract)
ER Diagram
erDiagram
LEAD ||--o{ LEAD_ASSIGNMENT : assigns
LEAD ||--o{ LEAD_TAG : tagged
CONTACT ||--o{ CONTACT_TAG : tagged
ORGANIZATION ||--o{ ORGANIZATION_TAG : tagged
CRM_TAG ||--o{ LEAD_TAG : used
CRM_TAG ||--o{ CONTACT_TAG : used
CRM_TAG ||--o{ ORGANIZATION_TAG : used
LEAD_SOURCE ||--o{ LEAD : sources
LEAD_STATUS ||--o{ LEAD : statuses
CONTACT_TYPE ||--o{ CONTACT : types
ORGANIZATION_TYPE ||--o{ ORGANIZATION : types
ORGANIZATION_INDUSTRY ||--o{ ORGANIZATION : industries
ORGANIZATION ||--o{ ORGANIZATION : parent
CRM_CUSTOM_FIELD ||--o{ CRM_CUSTOM_FIELD_VALUE : values
LEAD ||--o{ CRM_ADDRESS : addresses
LEAD ||--o{ CRM_NOTE : notes
CRM_NOTE ||--o{ CRM_NOTE_VERSION : versions
LEAD ||--o{ CRM_ATTACHMENT : attachments
LEAD ||--o{ CRM_AUDIT : audited
Business Rules
- Lead number unique per tenant; auto-generated when omitted (
LEAD-XXXXXXXXXX)
- Lead owner required
- Soft delete + restore for Lead / Contact / Organization / Address / Note / Attachment
- Organization name unique per tenant; parent cannot be self
- Attachment stores reference only (no binary in CRM)
- Notes are versioned on body update
- Custom fields are per-tenant and per-entity with typed validation
Validation Rules
| Area |
Rules |
| Email |
RFC-ish format, lowercased |
| Phone / Mobile |
5–30 chars of digits/spaces/+()- |
| Owner |
non-empty |
| Lead status |
known enum / status definition |
| Amount |
non-negative |
| Custom fields |
type match; required; select option membership |
| Attachment |
file_storage_id + file_name required |
| Address |
line1 required |
Events
| Event |
When |
crm.lead.created / crm.lead.updated |
Lead create/update |
crm.contact.created |
Contact create |
crm.organization.created |
Organization create |
crm.note.created |
Note create |
crm.attachment.added |
Attachment reference create |
Permissions
crm.leads.*, crm.contacts.*, crm.organizations.*, crm.notes.*, crm.attachments.*, crm.customfields.* (+ existing 6.0 trees).
API Endpoints
| Area |
Paths |
| Leads |
POST/GET/PATCH /api/v1/leads, /assign, /delete, /restore |
| Contacts |
POST/GET/PATCH /api/v1/contacts, /delete |
| Organizations |
POST/GET/PATCH /api/v1/organizations, /delete |
| Lookups |
/api/v1/lookups/lead-sources|lead-statuses|contact-types|organization-types|organization-industries |
| Tags |
/api/v1/tags, /tags/leads|contacts|organizations/{id} |
| Addresses |
/api/v1/addresses |
| Notes |
/api/v1/notes |
| Attachments |
/api/v1/attachments |
| Custom fields |
/api/v1/custom-fields, /custom-fields/values |
| Audit |
/api/v1/audit |
Migration Summary
- Alembic revision
0002_phase_61_entities (down_revision 0001_initial)
- Expands metadata via
create_all for additive tables/columns on fresh installs
- Indexes on tenant + status/email/owner/entity polymorphic keys
- Unique constraints: lead_number, org name, lookup codes, tag names, custom field keys
Services / Repositories / Validators
| Service |
Repository |
| LeadService |
LeadRepository (+ LeadAssignmentRepository) |
| ContactService |
ContactRepository |
| OrganizationService |
OrganizationRepository |
| AddressService |
CrmAddressRepository |
| TagService |
CrmTagRepository + join repos |
| CustomFieldService |
CrmCustomField* repositories |
| AttachmentService |
CrmAttachmentRepository |
| NoteService |
CrmNote* repositories |
| AuditService |
CrmAuditLogRepository |
| LookupService |
lookup repositories |
Validators live in app/validators/ (lead/contact/org/address/tag/custom field/attachment rules).
Tests Executed
- Model / architecture / dependency
- Repository / service / validation / audit
- API / permission / migration / tenant isolation
- Documentation validation
Known Limitations
- File Storage resolve is contract-only (
FileStorageProvider); no live S3/upload in CRM
- Multi phone/email stored as JSON arrays (not separate child tables)
- Schema evolution on already-applied 6.0 Postgres may need operational
ALTER if 0001 ran with old columns only
- No Automation / Customer360 consumption yet
Next Phase
Phase 6.2 completed — see crm-phase-6-2.md. CRM Core Platform complete through crm-phase-6-3.md.
Related Documents