Skip to content

Data Models — dot-cOS

All data lives in Supabase PostgreSQL, managed via Prisma ORM.

Entity Relationship Overview

erDiagram
    TENANT ||--o{ ENTITY : "has many"
    TENANT ||--o{ USER : "has many"
    TENANT ||--o{ ROLE : "has many"
    TENANT ||--o{ WORKFLOW_INSTANCE : "has many"
    TENANT ||--o{ AUDIT_LOG : "has many"
    TENANT ||--o{ FORM_MAPPING : "has many (tenant-specific)"

    ENTITY ||--o{ WORKFLOW_INSTANCE : "has many"
    ENTITY ||--o{ FINANCIAL_METRIC : "has many"
    ENTITY ||--o{ AUDIT_LOG : "has many"
    ENTITY ||--o{ DOCUMENT : "has many"

    WORKFLOW_TEMPLATE ||--o{ WORKFLOW_INSTANCE : "instantiated as"
    WORKFLOW_INSTANCE ||--o{ AUDIT_LOG : "logged in"
    WORKFLOW_INSTANCE ||--o{ WORKFLOW_CONTEXT : "has context"

    USER }o--|| ROLE : "has role"
    USER }o--|| ENTITY : "belongs to"

Tenant

Lightweight reference — status and plan are authoritative in the Central Registry.

model Tenant {
  id            String   @id @default(uuid())
  name          String
  entityType    String   @default("PRIVATE_LIMITED")
  country       String   @default("IN")
  contactEmail  String?
  contactPhone  String?
  gstin         String?
  pan           String?
  signupSource  String   @default("ADMIN")
  createdAt     DateTime @default(now())
  // subscriptionPlan removed — read from Central Registry
}

User

model User {
  id         String  @id @default(uuid())
  tenantId   String
  supabaseId String? @unique   // links to auth.users.id
  email      String  @unique
  name       String
  // password removed — managed by Supabase Auth
  roleId     String
  entityId   String
}

Entity

model Entity {
  id                 String  @id @default(uuid())
  tenantId           String
  name               String
  registrationNumber String?
  industry           String?
  profileData        Json?   // Address, Directors, Capital, etc.
  version            Int     @default(1)
}

WorkflowTemplate

model WorkflowTemplate {
  id                 String  @id @default(uuid())
  tenantId           String? // null = global system template
  workflowName       String
  legalReference     String?
  applicabilityRules Json    // { entityTypes: ["PRIVATE_LIMITED", ...] }
  timelineLogic      Json
  phases             Json    // Sequential workflow stages
  validationRules    Json
  advisoryPrompts    Json
  completionCriteria Json
  isAdhoc            Boolean @default(false)
  isActive           Boolean @default(true)
}

WorkflowInstance

model WorkflowInstance {
  id             String  @id @default(uuid())
  tenantId       String
  templateId     String
  entityId       String
  status         String  @default("DRAFT") // DRAFT | IN_PROGRESS | COMPLETED
  financialYear  String?
  currentData    Json    // Real-time workflow state
  certificateUrl String?
}

DocumentTemplate

model DocumentTemplate {
  id             String  @id @default(uuid())
  tenantId       String? // null = global
  name           String
  category       String  // BOARD_RESOLUTION | NOTICE | LETTER | MCA_FORM | ...
  body           String  // HTML with {{variable}} placeholders
  variables      Json    // [{name, label, type, required, defaultValue}]
  isActive       Boolean @default(true)
}