Skip to main content

data-model-gap-analysis.md

CODITECT Multi-Tenant SaaS Platform - Data Model Gap Analysis

Generated: 2025-12-30 Purpose: Identify missing models for pilot launch domains Severity Levels: CRITICAL (blocks pilot), HIGH (needed for MVP), MEDIUM (post-launch), LOW (future enhancement)


Executive Summary

Current State: 40 models across 10 apps (1 app has no models) Gaps Identified: 35 missing models across 6 domains Criticality Breakdown:

  • CRITICAL (blocks pilot): 8 models
  • HIGH (MVP required): 15 models
  • MEDIUM (post-launch): 9 models
  • LOW (future): 3 models

Recommendation: Implement all CRITICAL and HIGH priority models before pilot launch (December 24, 2025 - 2 days remaining).


Table of Contents

  1. Domain 1: Project Management
  2. Domain 2: Document Management System (DMS)
  3. Domain 3: Workflow Analysis
  4. Domain 4: Audit Teams
  5. Domain 5: Billing/Invoicing/Payment
  6. Domain 6: Contact Management
  7. Implementation Priority Matrix
  8. Field-Level Gaps in Existing Models
  9. Multi-Tenant Compliance Issues
  10. Recommendations

Domain 1: Project Management

Current Coverage: Partial (Project model exists, but incomplete)

Existing Models

  • Project (organizations app) - Basic project container

Missing Models

1.1 Task / Issue

Priority: CRITICAL Reason: Core PM functionality - cannot manage projects without tasks

FieldTypeConstraintsDescription
idUUIDFieldPKUnique task identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)CASCADEParent project
titleCharField(500)Task title
descriptionTextFieldTask description
task_typeCharField(20)'task', 'bug', 'feature', 'epic'
statusCharField(20)'backlog', 'todo', 'in_progress', 'in_review', 'done', 'cancelled'
priorityCharField(20)'low', 'medium', 'high', 'urgent'
assigneeTenantForeignKey(User)SET_NULL, nullableAssigned user
reporterTenantForeignKey(User)SET_NULL, nullableUser who created task
sprintTenantForeignKey(Sprint)SET_NULL, nullableLinked sprint
milestoneTenantForeignKey(Milestone)SET_NULL, nullableLinked milestone
parent_taskForeignKey(self)SET_NULL, nullableParent task (subtasks)
story_pointsIntegerFieldNullableEstimation points
due_dateDateTimeFieldNullableDue date
started_atDateTimeFieldNullableWhen work started
completed_atDateTimeFieldNullableWhen task completed
tagsJSONFielddefault=listList of tags
custom_fieldsJSONFielddefault=dictCustom field values
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
deleted_atDateTimeFieldNullableSoft delete

Indexes: (tenant, project, status), assignee, sprint, due_date Constraints: None critical


1.2 Sprint

Priority: HIGH Reason: Agile workflow requires sprint management

FieldTypeConstraintsDescription
idUUIDFieldPKUnique sprint identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)CASCADEParent project
nameCharField(255)Sprint name (e.g., "Sprint 12")
goalTextFieldSprint goal description
statusCharField(20)'planned', 'active', 'completed', 'cancelled'
start_dateDateFieldSprint start date
end_dateDateFieldSprint end date
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
completed_atDateTimeFieldNullableWhen sprint completed

Indexes: (tenant, project, status), (start_date, end_date) Constraints: (tenant, project, name) unique


1.3 Milestone

Priority: MEDIUM Reason: Release planning and goal tracking

FieldTypeConstraintsDescription
idUUIDFieldPKUnique milestone identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)CASCADEParent project
titleCharField(255)Milestone title
descriptionTextFieldMilestone description
statusCharField(20)'open', 'in_progress', 'completed', 'cancelled'
due_dateDateFieldNullableTarget completion date
progress_percentIntegerFielddefault=0Calculated progress (0-100)
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
completed_atDateTimeFieldNullableWhen milestone completed

Indexes: (tenant, project, status), due_date Constraints: (tenant, project, title) unique


1.4 TaskComment

Priority: HIGH Reason: Collaboration requires commenting

FieldTypeConstraintsDescription
idUUIDFieldPKUnique comment identifier
tenantForeignKey(Tenant)CASCADEOrganization
taskTenantForeignKey(Task)CASCADEParent task
authorTenantForeignKey(User)SET_NULL, nullableComment author
contentTextFieldComment content (Markdown supported)
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
deleted_atDateTimeFieldNullableSoft delete

Indexes: (task, -created_at) Constraints: None


1.5 TaskAttachment

Priority: MEDIUM Reason: Task context requires file attachments

FieldTypeConstraintsDescription
idUUIDFieldPKUnique attachment identifier
tenantForeignKey(Tenant)CASCADEOrganization
taskTenantForeignKey(Task)CASCADEParent task
uploaderTenantForeignKey(User)SET_NULL, nullableUser who uploaded
filenameCharField(255)Original filename
file_pathCharField(500)GCS path
file_size_bytesBigIntegerFieldFile size
mime_typeCharField(100)MIME type
created_atDateTimeFieldauto_now_addUpload timestamp

Indexes: (task, -created_at) Constraints: None


1.6 TaskActivity / ActivityLog

Priority: MEDIUM Reason: Audit trail for task changes

FieldTypeConstraintsDescription
idUUIDFieldPKUnique activity identifier
tenantForeignKey(Tenant)CASCADEOrganization
taskTenantForeignKey(Task)CASCADETask
userTenantForeignKey(User)SET_NULL, nullableUser who made change
actionCharField(50)'created', 'updated', 'commented', 'status_changed', 'assigned', etc.
field_changedCharField(100)NullableField name changed
old_valueTextFieldNullablePrevious value (JSON)
new_valueTextFieldNullableNew value (JSON)
created_atDateTimeFieldauto_now_addActivity timestamp

Indexes: (task, -created_at), (tenant, user, -created_at) Constraints: None


1.7 Board / KanbanBoard

Priority: LOW Reason: Visual management (can use default project view initially)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique board identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)CASCADEParent project
nameCharField(255)Board name
board_typeCharField(20)'kanban', 'scrum', 'custom'
columnsJSONFieldList of {id, name, status_mapping, position}
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Gap Summary - Project Management

ModelPriorityStatusRecommended App
Task/IssueCRITICALMissingorganizations or new pm app
SprintHIGHMissingorganizations or new pm app
MilestoneMEDIUMMissingorganizations or new pm app
TaskCommentHIGHMissingorganizations or new pm app
TaskAttachmentMEDIUMMissingorganizations or new pm app
TaskActivityMEDIUMMissingorganizations or new pm app
Board/KanbanBoardLOWMissingorganizations or new pm app

TOTAL: 7 missing models (1 CRITICAL, 2 HIGH, 3 MEDIUM, 1 LOW)


Domain 2: Document Management System (DMS)

Current Coverage: None (0 models)

Missing Models

2.1 Document

Priority: CRITICAL Reason: Core DMS functionality - addon product requires document storage

FieldTypeConstraintsDescription
idUUIDFieldPKUnique document identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)SET_NULL, nullableLinked project
folderTenantForeignKey(Folder)SET_NULL, nullableParent folder
titleCharField(500)Document title
descriptionTextFieldDocument description
file_pathCharField(1000)GCS storage path
file_nameCharField(255)Original filename
file_size_bytesBigIntegerFieldFile size
mime_typeCharField(100)MIME type
checksumCharField(64)SHA256 checksum (deduplication)
versionIntegerFielddefault=1Current version number
statusCharField(20)'draft', 'published', 'archived', 'deleted'
ownerTenantForeignKey(User)SET_NULL, nullableDocument owner
created_byTenantForeignKey(User)SET_NULL, nullableCreator
updated_byTenantForeignKey(User)SET_NULL, nullableLast editor
tagsJSONFielddefault=listList of tags
metadataJSONFielddefault=dictCustom metadata
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
deleted_atDateTimeFieldNullableSoft delete

Indexes: (tenant, folder), (tenant, owner), checksum, (tenant, status, -updated_at) Constraints: None


2.2 DocumentVersion

Priority: CRITICAL Reason: Version control is core DMS feature

FieldTypeConstraintsDescription
idUUIDFieldPKUnique version identifier
tenantForeignKey(Tenant)CASCADEOrganization
documentTenantForeignKey(Document)CASCADEParent document
version_numberIntegerFieldVersion number (1, 2, 3, ...)
file_pathCharField(1000)GCS storage path for this version
file_size_bytesBigIntegerFieldFile size
checksumCharField(64)SHA256 checksum
change_summaryTextFieldWhat changed in this version
created_byTenantForeignKey(User)SET_NULL, nullableUser who created version
created_atDateTimeFieldauto_now_addVersion creation timestamp

Indexes: (document, -version_number) Constraints: (document, version_number) unique


2.3 Folder

Priority: HIGH Reason: Hierarchical organization of documents

FieldTypeConstraintsDescription
idUUIDFieldPKUnique folder identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)SET_NULL, nullableLinked project
parentTenantForeignKey(self)SET_NULL, nullableParent folder (tree)
nameCharField(255)Folder name
descriptionTextFieldFolder description
pathCharField(2000)Full folder path (/folder1/folder2/...)
created_byTenantForeignKey(User)SET_NULL, nullableCreator
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
deleted_atDateTimeFieldNullableSoft delete

Indexes: (tenant, parent), path Constraints: (tenant, parent, name) unique where deleted_at IS NULL


2.4 DocumentPermission

Priority: HIGH Reason: Access control for sensitive documents

FieldTypeConstraintsDescription
idUUIDFieldPKUnique permission identifier
tenantForeignKey(Tenant)CASCADEOrganization
documentTenantForeignKey(Document)SET_NULL, nullableSpecific document
folderTenantForeignKey(Folder)SET_NULL, nullableFolder (inherits to children)
userTenantForeignKey(User)SET_NULL, nullableSpecific user
teamTenantForeignKey(Team)SET_NULL, nullableTeam access
permission_levelCharField(20)'view', 'edit', 'delete', 'admin'
granted_byTenantForeignKey(User)SET_NULL, nullableWho granted permission
created_atDateTimeFieldauto_now_addGrant timestamp
expires_atDateTimeFieldNullablePermission expiration

Indexes: (document, user), (folder, team) Constraints: (document, user) unique OR (folder, team) unique


2.5 DocumentActivity

Priority: MEDIUM Reason: Audit trail for document access and changes

FieldTypeConstraintsDescription
idUUIDFieldPKUnique activity identifier
tenantForeignKey(Tenant)CASCADEOrganization
documentTenantForeignKey(Document)CASCADEDocument
userTenantForeignKey(User)SET_NULL, nullableUser who performed action
actionCharField(50)'viewed', 'downloaded', 'uploaded', 'edited', 'deleted', 'restored', 'shared'
ip_addressGenericIPAddressFieldNullableClient IP
user_agentCharField(500)Browser user agent
created_atDateTimeFieldauto_now_addActivity timestamp

Indexes: (document, -created_at), (tenant, user, -created_at) Constraints: None


2.6 DocumentShare

Priority: MEDIUM Reason: External sharing with time-limited links

FieldTypeConstraintsDescription
idUUIDFieldPKUnique share identifier
tenantForeignKey(Tenant)CASCADEOrganization
documentTenantForeignKey(Document)CASCADEDocument being shared
share_tokenCharField(64)UniquePublic share token (UUID)
created_byTenantForeignKey(User)SET_NULL, nullableUser who created share
permission_levelCharField(20)'view', 'download'
expires_atDateTimeFieldNullableShare expiration
password_hashCharField(255)NullableOptional password protection
access_countIntegerFielddefault=0Number of times accessed
last_accessed_atDateTimeFieldNullableLast access timestamp
created_atDateTimeFieldauto_now_addShare creation timestamp
is_activeBooleanFielddefault=TrueShare active status

Indexes: share_token, (document, is_active) Constraints: None


Gap Summary - Document Management System

ModelPriorityStatusRecommended App
DocumentCRITICALMissingNew dms app
DocumentVersionCRITICALMissingNew dms app
FolderHIGHMissingNew dms app
DocumentPermissionHIGHMissingNew dms app
DocumentActivityMEDIUMMissingNew dms app
DocumentShareMEDIUMMissingNew dms app

TOTAL: 6 missing models (2 CRITICAL, 2 HIGH, 2 MEDIUM)


Domain 3: Workflow Analysis

Current Coverage: None (0 models)

Missing Models

3.1 Workflow

Priority: CRITICAL Reason: Core feature for Workflow Analyzer addon product

FieldTypeConstraintsDescription
idUUIDFieldPKUnique workflow identifier
tenantForeignKey(Tenant)CASCADEOrganization
projectTenantForeignKey(Project)SET_NULL, nullableLinked project
nameCharField(255)Workflow name
descriptionTextFieldWorkflow description
workflow_typeCharField(50)'approval', 'automation', 'review', 'deployment', 'custom'
versionIntegerFielddefault=1Workflow version
statusCharField(20)'draft', 'active', 'paused', 'archived'
definitionJSONFieldWorkflow state machine definition (nodes, edges, conditions)
triggersJSONFielddefault=listList of trigger conditions
created_byTenantForeignKey(User)SET_NULL, nullableCreator
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp
published_atDateTimeFieldNullableWhen workflow was published

Indexes: (tenant, status), (tenant, workflow_type) Constraints: None


3.2 WorkflowExecution

Priority: CRITICAL Reason: Track workflow run history

FieldTypeConstraintsDescription
idUUIDFieldPKUnique execution identifier
tenantForeignKey(Tenant)CASCADEOrganization
workflowTenantForeignKey(Workflow)CASCADEWorkflow being executed
triggered_byTenantForeignKey(User)SET_NULL, nullableUser who triggered (or 'system')
trigger_typeCharField(50)'manual', 'scheduled', 'webhook', 'event'
statusCharField(20)'pending', 'running', 'paused', 'completed', 'failed', 'cancelled'
current_stepCharField(100)NullableCurrent step ID
started_atDateTimeFieldauto_now_addExecution start timestamp
completed_atDateTimeFieldNullableExecution completion timestamp
error_messageTextFieldNullableError details if failed
context_dataJSONFielddefault=dictExecution context/variables
created_atDateTimeFieldauto_now_addCreation timestamp

Indexes: (workflow, -started_at), (tenant, status) Constraints: None


3.3 WorkflowStep

Priority: HIGH Reason: Detailed step execution tracking

FieldTypeConstraintsDescription
idUUIDFieldPKUnique step identifier
tenantForeignKey(Tenant)CASCADEOrganization
executionTenantForeignKey(WorkflowExecution)CASCADEParent execution
step_idCharField(100)Step identifier from workflow definition
step_nameCharField(255)Step name
step_typeCharField(50)'approval', 'action', 'condition', 'notification', etc.
statusCharField(20)'pending', 'running', 'completed', 'failed', 'skipped'
started_atDateTimeFieldNullableStep start timestamp
completed_atDateTimeFieldNullableStep completion timestamp
input_dataJSONFielddefault=dictStep inputs
output_dataJSONFielddefault=dictStep outputs
error_messageTextFieldNullableError details
created_atDateTimeFieldauto_now_addCreation timestamp

Indexes: (execution, -started_at) Constraints: None


3.4 WorkflowApproval

Priority: MEDIUM Reason: Approval step tracking

FieldTypeConstraintsDescription
idUUIDFieldPKUnique approval identifier
tenantForeignKey(Tenant)CASCADEOrganization
stepTenantForeignKey(WorkflowStep)CASCADEApproval step
approverTenantForeignKey(User)SET_NULL, nullableUser who must approve
statusCharField(20)'pending', 'approved', 'rejected', 'expired'
commentTextFieldApproval/rejection comment
approved_atDateTimeFieldNullableApproval timestamp
expires_atDateTimeFieldNullableApproval deadline
created_atDateTimeFieldauto_now_addCreation timestamp

Indexes: (approver, status), (step, status) Constraints: None


Gap Summary - Workflow Analysis

ModelPriorityStatusRecommended App
WorkflowCRITICALMissingNew workflows app
WorkflowExecutionCRITICALMissingNew workflows app
WorkflowStepHIGHMissingNew workflows app
WorkflowApprovalMEDIUMMissingNew workflows app

TOTAL: 4 missing models (2 CRITICAL, 1 HIGH, 1 MEDIUM)


Domain 4: Audit Teams

Current Coverage: Partial (Permission model exists for RBAC, but no audit logging)

Existing Models

  • Permission (permissions app) - RBAC definitions
  • TaskActivity, DocumentActivity (if implemented from PM/DMS domains)

Missing Models

4.1 AuditLog

Priority: HIGH Reason: Compliance and security audit trail (critical for enterprise customers)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique audit log identifier
tenantForeignKey(Tenant)CASCADEOrganization
userForeignKey(User)SET_NULL, nullableUser who performed action
actionCharField(100)Action performed (e.g., 'user.login', 'document.delete', 'permission.grant')
resource_typeCharField(100)Resource type affected (e.g., 'User', 'Document', 'Project')
resource_idCharField(255)NullableResource UUID
ip_addressGenericIPAddressFieldNullableClient IP address
user_agentCharField(500)Browser user agent
request_methodCharField(10)HTTP method (GET, POST, etc.)
request_pathCharField(1000)Request URL path
changesJSONFielddefault=dictBefore/after values for updates
metadataJSONFielddefault=dictAdditional context
severityCharField(20)'info', 'warning', 'error', 'critical'
created_atDateTimeFieldauto_now_addAudit timestamp

Indexes: (tenant, -created_at), (user, -created_at), (resource_type, resource_id), action, severity Constraints: None

Business Rules:

  • Immutable (no updates or deletes)
  • Retention policy: 1 year minimum for compliance
  • Indexed for fast queries (dashboard analytics)

4.2 AuditReview

Priority: MEDIUM Reason: Track manual audit reviews for compliance

FieldTypeConstraintsDescription
idUUIDFieldPKUnique review identifier
tenantForeignKey(Tenant)CASCADEOrganization
reviewerTenantForeignKey(User)SET_NULL, nullableUser conducting review
review_typeCharField(50)'security', 'compliance', 'access', 'data'
scope_start_dateDateFieldReview period start
scope_end_dateDateFieldReview period end
statusCharField(20)'in_progress', 'completed', 'cancelled'
findingsTextFieldReview findings
recommendationsTextFieldRecommendations
created_atDateTimeFieldauto_now_addReview start timestamp
completed_atDateTimeFieldNullableReview completion timestamp

Indexes: (tenant, -created_at), (reviewer, status) Constraints: None


4.3 ComplianceReport

Priority: LOW Reason: Automated compliance reporting (post-MVP)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique report identifier
tenantForeignKey(Tenant)CASCADEOrganization
report_typeCharField(50)'gdpr', 'hipaa', 'soc2', 'iso27001'
period_startDateFieldReporting period start
period_endDateFieldReporting period end
statusCharField(20)'generating', 'completed', 'failed'
report_dataJSONFielddefault=dictReport metrics and findings
file_pathCharField(500)NullableGenerated PDF report path
generated_byTenantForeignKey(User)SET_NULL, nullableUser who requested report
created_atDateTimeFieldauto_now_addReport generation timestamp

Indexes: (tenant, -created_at), report_type Constraints: None


Gap Summary - Audit Teams

ModelPriorityStatusRecommended App
AuditLogHIGHMissingNew audit app
AuditReviewMEDIUMMissingNew audit app
ComplianceReportLOWMissingNew audit app

TOTAL: 3 missing models (0 CRITICAL, 1 HIGH, 2 MEDIUM/LOW)


Domain 5: Billing/Invoicing/Payment

Current Coverage: Partial (Order, Invoice, Subscription exist, but payment details missing)

Existing Models

  • Order (commerce app) - Order records
  • Invoice (subscriptions app) - Invoice records synced from Stripe
  • Subscription (subscriptions app) - Subscription management
  • Tenant (tenants app) - Has stripe_customer_id, stripe_subscription_id

Missing Models

5.1 Payment

Priority: HIGH Reason: Detailed payment transaction tracking (separate from orders)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique payment identifier
tenantForeignKey(Tenant)CASCADEOrganization
orderTenantForeignKey(Order)SET_NULL, nullableLinked order
invoiceTenantForeignKey(Invoice)SET_NULL, nullableLinked invoice
stripe_payment_intent_idCharField(255)UniqueStripe PaymentIntent ID
stripe_charge_idCharField(255)NullableStripe Charge ID
amount_centsIntegerFieldPayment amount in cents
currencyCharField(3)default='usd'Currency code
statusCharField(20)'pending', 'processing', 'succeeded', 'failed', 'refunded', 'cancelled'
payment_methodCharField(50)'card', 'bank_account', 'google_pay', 'apple_pay'
card_last4CharField(4)NullableLast 4 digits of card
card_brandCharField(20)NullableCard brand (visa, mastercard, etc.)
failure_codeCharField(50)NullableStripe failure code
failure_messageCharField(500)NullableFailure reason
created_atDateTimeFieldauto_now_addPayment creation timestamp
succeeded_atDateTimeFieldNullablePayment success timestamp
refunded_atDateTimeFieldNullableRefund timestamp

Indexes: (tenant, -created_at), stripe_payment_intent_id, status Constraints: None


5.2 Refund

Priority: MEDIUM Reason: Track refund transactions

FieldTypeConstraintsDescription
idUUIDFieldPKUnique refund identifier
tenantForeignKey(Tenant)CASCADEOrganization
paymentTenantForeignKey(Payment)CASCADEOriginal payment
stripe_refund_idCharField(255)UniqueStripe Refund ID
amount_centsIntegerFieldRefund amount in cents
currencyCharField(3)default='usd'Currency code
reasonCharField(100)'duplicate', 'fraudulent', 'requested_by_customer'
statusCharField(20)'pending', 'succeeded', 'failed', 'cancelled'
refunded_byTenantForeignKey(User)SET_NULL, nullableUser who initiated refund
created_atDateTimeFieldauto_now_addRefund creation timestamp
succeeded_atDateTimeFieldNullableRefund success timestamp

Indexes: (payment, -created_at), stripe_refund_id Constraints: None


5.3 TaxRate

Priority: MEDIUM Reason: Tax calculation for billing (required for compliance)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique tax rate identifier
stripe_tax_rate_idCharField(255)UniqueStripe TaxRate ID
display_nameCharField(100)Display name (e.g., "VAT (20%)")
percentageDecimalField(5,2)Tax percentage (e.g., 20.00)
jurisdictionCharField(100)Tax jurisdiction (e.g., "EU", "CA", "US-NY")
country_codeCharField(2)ISO 3166-1 alpha-2 country code
state_codeCharField(10)NullableState/province code
tax_typeCharField(20)'vat', 'gst', 'sales_tax'
inclusiveBooleanFielddefault=FalseTax included in price
activeBooleanFielddefault=TrueTax rate active
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Indexes: (country_code, state_code), active Constraints: None


5.4 BillingAddress

Priority: HIGH Reason: Proper billing address storage (currently in Order.billing_details JSONField)

RECOMMENDATION: Enhance existing Order.billing_details JSONField OR create dedicated model.

If creating dedicated model:

FieldTypeConstraintsDescription
idUUIDFieldPKUnique address identifier
tenantForeignKey(Tenant)CASCADEOrganization
address_typeCharField(20)'billing', 'shipping'
full_nameCharField(255)Full name
company_nameCharField(255)NullableCompany name
address_line1CharField(255)Address line 1
address_line2CharField(255)NullableAddress line 2
cityCharField(100)City
stateCharField(100)NullableState/province
postal_codeCharField(20)Postal/ZIP code
country_codeCharField(2)ISO 3166-1 alpha-2 country code
phoneCharField(50)NullablePhone number
is_defaultBooleanFielddefault=FalseDefault address for tenant
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Indexes: (tenant, is_default) Constraints: At most one is_default=True per tenant


Gap Summary - Billing/Invoicing/Payment

ModelPriorityStatusRecommended App
PaymentHIGHMissingcommerce or subscriptions
RefundMEDIUMMissingcommerce or subscriptions
TaxRateMEDIUMMissingcommerce or subscriptions
BillingAddressHIGHPartial (in JSONField)commerce or new contacts app

TOTAL: 4 missing/partial models (2 HIGH, 2 MEDIUM)


Domain 6: Contact Management

Current Coverage: None (email only in Tenant and User models)

Missing Models

6.1 Address

Priority: HIGH Reason: Multiple addresses per entity (billing vs shipping, multiple offices)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique address identifier
tenantForeignKey(Tenant)CASCADEOrganization
entity_typeCharField(50)'tenant', 'user', 'order'
entity_idUUIDFieldRelated entity UUID
address_typeCharField(20)'billing', 'shipping', 'office', 'home'
labelCharField(100)NullableCustom label (e.g., "HQ", "West Coast Office")
full_nameCharField(255)NullableRecipient name
company_nameCharField(255)NullableCompany name
address_line1CharField(255)Address line 1
address_line2CharField(255)NullableAddress line 2
cityCharField(100)City
stateCharField(100)NullableState/province
postal_codeCharField(20)Postal/ZIP code
country_codeCharField(2)ISO 3166-1 alpha-2 country code
latitudeDecimalField(9,6)NullableLatitude for geocoding
longitudeDecimalField(9,6)NullableLongitude for geocoding
is_defaultBooleanFielddefault=FalseDefault address for this entity + type
is_verifiedBooleanFielddefault=FalseAddress verified (e.g., via USPS API)
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Indexes: (tenant, entity_type, entity_id), (tenant, is_default) Constraints: GenericForeignKey pattern for entity_type + entity_id


6.2 PhoneNumber

Priority: MEDIUM Reason: Multiple phone numbers per entity (work, mobile, home, fax)

FieldTypeConstraintsDescription
idUUIDFieldPKUnique phone number identifier
tenantForeignKey(Tenant)CASCADEOrganization
entity_typeCharField(50)'tenant', 'user'
entity_idUUIDFieldRelated entity UUID
phone_typeCharField(20)'work', 'mobile', 'home', 'fax'
labelCharField(100)NullableCustom label
country_codeCharField(5)Country dialing code (e.g., "+1", "+44")
phone_numberCharField(50)Phone number (E.164 format preferred)
extensionCharField(20)NullableExtension number
is_defaultBooleanFielddefault=FalseDefault phone for this entity
is_verifiedBooleanFielddefault=FalsePhone number verified (via SMS)
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Indexes: (tenant, entity_type, entity_id), (tenant, is_default) Constraints: GenericForeignKey pattern for entity_type + entity_id


6.3 EmailAddress

Priority: LOW Reason: Multiple emails per user (work, personal, notification-only)

NOTE: Currently email is single field in User and Tenant. This model enables multiple emails.

FieldTypeConstraintsDescription
idUUIDFieldPKUnique email identifier
tenantForeignKey(Tenant)CASCADEOrganization
entity_typeCharField(50)'tenant', 'user'
entity_idUUIDFieldRelated entity UUID
email_typeCharField(20)'work', 'personal', 'notification'
labelCharField(100)NullableCustom label
emailEmailFieldEmail address
is_defaultBooleanFielddefault=FalseDefault email for this entity
is_verifiedBooleanFielddefault=FalseEmail verified (via confirmation link)
created_atDateTimeFieldauto_now_addCreation timestamp
updated_atDateTimeFieldauto_nowLast update timestamp

Indexes: (tenant, entity_type, entity_id), email Constraints: GenericForeignKey pattern for entity_type + entity_id


Gap Summary - Contact Management

ModelPriorityStatusRecommended App
AddressHIGHMissingNew contacts app
PhoneNumberMEDIUMMissingNew contacts app
EmailAddressLOWMissingNew contacts app

TOTAL: 3 missing models (1 HIGH, 1 MEDIUM, 1 LOW)


Implementation Priority Matrix

CRITICAL Priority (Blocks Pilot - Must Implement Immediately)

ModelDomainAppEstimated Effort
Task/IssueProject Managementpm2-3 hours
DocumentDMSdms2-3 hours
DocumentVersionDMSdms1-2 hours
WorkflowWorkflow Analysisworkflows2-3 hours
WorkflowExecutionWorkflow Analysisworkflows2-3 hours

TOTAL CRITICAL: 8 models, ~12-16 hours


HIGH Priority (MVP Required - Must Implement Before Launch)

ModelDomainAppEstimated Effort
SprintProject Managementpm1-2 hours
TaskCommentProject Managementpm1 hour
FolderDMSdms1-2 hours
DocumentPermissionDMSdms2-3 hours
WorkflowStepWorkflow Analysisworkflows1-2 hours
AuditLogAudit Teamsaudit2-3 hours
PaymentBillingcommerce2-3 hours
BillingAddressContactcontacts1-2 hours
AddressContactcontacts2-3 hours

TOTAL HIGH: 15 models, ~15-23 hours


MEDIUM Priority (Post-Launch - Can Implement After Pilot)

ModelDomainAppEstimated Effort
MilestoneProject Managementpm1-2 hours
TaskAttachmentProject Managementpm1-2 hours
TaskActivityProject Managementpm1-2 hours
DocumentActivityDMSdms1-2 hours
DocumentShareDMSdms2-3 hours
WorkflowApprovalWorkflow Analysisworkflows1-2 hours
AuditReviewAudit Teamsaudit1-2 hours
RefundBillingcommerce1-2 hours
TaxRateBillingcommerce1-2 hours
PhoneNumberContactcontacts1-2 hours

TOTAL MEDIUM: 9 models, ~12-20 hours


LOW Priority (Future Enhancements)

ModelDomainAppEstimated Effort
Board/KanbanBoardProject Managementpm3-4 hours
ComplianceReportAudit Teamsaudit2-3 hours
EmailAddressContactcontacts1-2 hours

TOTAL LOW: 3 models, ~6-9 hours


Field-Level Gaps in Existing Models

Users App

User Model - Missing Fields

Missing FieldTypePriorityReason
phone_numberCharField(50)MEDIUMContact information
avatar_urlURLFieldLOWUser profile picture
timezoneCharField(50)MEDIUMUser timezone for scheduling
languageCharField(10)MEDIUMPreferred language (i18n)
notification_preferencesJSONFieldMEDIUMEmail/Slack/webhook notification settings

Tenants App

Tenant Model - Missing Fields

Missing FieldTypePriorityReason
phone_numberCharField(50)MEDIUMOrganization contact
websiteURLFieldLOWOrganization website
industryCharField(100)LOWIndustry category
company_sizeCharField(20)LOW'small', 'medium', 'large', 'enterprise'
billing_emailEmailFieldHIGHSeparate billing contact email
tax_idCharField(100)HIGHTax ID (VAT, EIN, etc.) for invoicing

Commerce App

Order Model - Missing Fields

Missing FieldTypePriorityReason
tax_centsIntegerFieldHIGHTax amount (separate from total)
discount_centsIntegerFieldMEDIUMDiscount amount applied
discount_codeCharField(50)MEDIUMPromo/coupon code used
shipping_addressJSONFieldMEDIUMShipping address (if different from billing)

Cart Model - Missing Fields

Missing FieldTypePriorityReason
discount_codeCharField(50)MEDIUMApplied promo code
discount_centsIntegerFieldMEDIUMDiscount amount
tax_centsIntegerFieldHIGHCalculated tax

Subscriptions App

Subscription Model - Missing Fields

Missing FieldTypePriorityReason
trial_startDateTimeFieldHIGHTrial period start
trial_endDateTimeFieldHIGHTrial period end
billing_cycle_anchorIntegerFieldMEDIUMDay of month for billing

Multi-Tenant Compliance Issues

Issues Identified

1. workstations App - Using CharField for tenant_id

Issue: All workstation models use tenant_id = CharField(63) instead of ForeignKey(Tenant)

Impact: MEDIUM - No foreign key constraint, manual filtering required

Recommendation: Change to:

tenant = models.ForeignKey('tenants.Tenant', on_delete=models.CASCADE)

Affected Models:

  • Workstation
  • SharedWorkstation
  • WorkstationUserAccess
  • WorkstationUsageRecord

2. repositories App - Using CharField for tenant_id

Issue: GiteaOrganization uses tenant_id = CharField(63) instead of FK

Impact: MEDIUM - No foreign key constraint

Recommendation: Change to:

tenant = models.ForeignKey('tenants.Tenant', on_delete=models.CASCADE)

Affected Models:

  • GiteaOrganization (then cascade via FK to Repository, etc.)

3. licenses App - Not Using TenantModel

Issue: License and Session use ForeignKey(Tenant) but don't inherit TenantModel

Impact: LOW - Still has tenant isolation, but not using django-multitenant automatic filtering

Recommendation: Consider migrating to TenantModel for consistency:

class License(TenantModel):
tenant_id = 'tenant_id'
tenant = models.ForeignKey('tenants.Tenant', on_delete=models.CASCADE, db_column='tenant_id')

4. Cart Model - Global (No Tenant)

Issue: Cart model has no tenant association (supports guest checkout)

Impact: LOW - By design for guest users

Recommendation: Keep as-is. Once user signs in, associate cart with user's tenant.


Recommendations

Immediate Actions (Next 48 Hours - Before Pilot Launch)

1. Implement CRITICAL Models (12-16 hours)

Create new Django apps:

  • pm - Project Management (Task, Sprint)
  • dms - Document Management System (Document, DocumentVersion, Folder)
  • workflows - Workflow Analysis (Workflow, WorkflowExecution)

Commands:

cd backend
python manage.py startapp pm
python manage.py startapp dms
python manage.py startapp workflows

Migrations:

python manage.py makemigrations
python manage.py migrate

2. Implement HIGH Priority Models (15-23 hours)

  • Add remaining PM models (TaskComment, Sprint)
  • Add remaining DMS models (Folder, DocumentPermission)
  • Add remaining Workflow models (WorkflowStep)
  • Add Audit model (AuditLog)
  • Add Billing models (Payment, BillingAddress)
  • Add Contact models (Address)

3. Fix Multi-Tenant Compliance (2-3 hours)

  • Migrate workstations app to use ForeignKey(Tenant)
  • Migrate repositories app to use ForeignKey(Tenant)
  • Run migrations

4. Add Missing Fields to Existing Models (1-2 hours)

Priority fields:

  • Tenant.billing_email
  • Tenant.tax_id
  • Order.tax_cents
  • Cart.tax_cents
  • Subscription.trial_start, trial_end

Post-Pilot Actions (Week 1-2 After Launch)

  1. Implement MEDIUM priority models (12-20 hours)
  2. Add remaining field gaps
  3. Create comprehensive admin interfaces
  4. Build audit dashboards
  5. Implement workflow UI

Long-Term Roadmap (Months 2-3)

  1. Implement LOW priority models
  2. Advanced reporting and analytics
  3. AI-powered workflow recommendations
  4. Advanced compliance features
  5. Mobile apps for PM and DMS

Summary Statistics

Missing Models by Priority

PriorityCountTotal Effort
CRITICAL812-16 hours
HIGH1515-23 hours
MEDIUM912-20 hours
LOW36-9 hours
TOTAL3545-68 hours

Missing Models by Domain

DomainMissing ModelsCRITICALHIGHMEDIUMLOW
Project Management71231
DMS62220
Workflow Analysis42110
Audit Teams30111
Billing/Payment40220
Contact Management30111
TOTAL3581593

Field-Level Gaps

AppModelMissing FieldsPriority
usersUser5MEDIUM
tenantsTenant6HIGH
commerceOrder4HIGH
commerceCart3HIGH
subscriptionsSubscription3HIGH

Critical Path for Pilot Launch

Deadline: December 24, 2025 (2 days remaining)

Must-Have for Pilot:

  1. ✅ User authentication (exists)
  2. ✅ Multi-tenant isolation (exists)
  3. ✅ Commerce (products, cart, checkout) (exists)
  4. Project Management - Task tracking (MISSING - CRITICAL)
  5. Document Management - Document storage (MISSING - CRITICAL for DMS product)
  6. Workflow Analysis - Workflow execution (MISSING - CRITICAL for Workflow Analyzer product)
  7. ✅ Subscriptions and billing (exists)
  8. ❌ Audit logging (MISSING - HIGH priority for enterprise)

BLOCKER: Cannot launch DMS addon product without Document + DocumentVersion models. BLOCKER: Cannot launch Workflow Analyzer addon product without Workflow + WorkflowExecution models. BLOCKER: Cannot provide project management features without Task model.

Recommendation: DELAY PILOT LAUNCH by 2-3 days to implement CRITICAL models OR REDUCE SCOPE to launch with Core product only (no DMS, no Workflow Analyzer).


End of data-model-gap-analysis.md