@valentine-efagene/qshelter-common 2.0.98 → 2.0.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -345,7 +345,7 @@ model User {
345
345
  socials Social[]
346
346
 
347
347
  // Relations to other domains
348
- properties Property[]
348
+ properties Property[]
349
349
  applications Application[] @relation("ApplicationBuyer")
350
350
  soldApplications Application[] @relation("ApplicationSeller")
351
351
  applicationPayments ApplicationPayment[] @relation("ApplicationPayer")
@@ -353,7 +353,7 @@ model User {
353
353
  // Documentation step assignments and approvals
354
354
  assignedSteps DocumentationStep[] @relation("DocumentationStepAssignee")
355
355
  stepApprovals DocumentationStepApproval[] @relation("DocumentationStepApprover")
356
- uploadedDocs ApplicationDocument[] @relation("DocumentUploader")
356
+ uploadedDocs ApplicationDocument[] @relation("DocumentUploader")
357
357
 
358
358
  // Payment method changes
359
359
  paymentMethodChangeRequests PaymentMethodChangeRequest[] @relation("ChangeRequestor")
@@ -496,7 +496,7 @@ model Tenant {
496
496
  properties Property[]
497
497
  paymentPlans PaymentPlan[]
498
498
  paymentMethods PropertyPaymentMethod[]
499
- applications Application[]
499
+ applications Application[]
500
500
 
501
501
  // RBAC: Tenant-scoped roles and permissions
502
502
  roles Role[]
@@ -1023,11 +1023,11 @@ model PropertyPaymentMethod {
1023
1023
  updatedAt DateTime @updatedAt
1024
1024
 
1025
1025
  // Many-to-many with properties
1026
- properties PropertyPaymentMethodLink[]
1026
+ properties PropertyPaymentMethodLink[]
1027
1027
  // Phases that make up this method (templates)
1028
- phases PropertyPaymentMethodPhase[]
1028
+ phases PropertyPaymentMethodPhase[]
1029
1029
  // Contracts using this method
1030
- applications Application[]
1030
+ applications Application[]
1031
1031
 
1032
1032
  // Payment method change tracking
1033
1033
  changeRequestsFrom PaymentMethodChangeRequest[] @relation("ChangeFromMethod")
@@ -1292,8 +1292,8 @@ model Application {
1292
1292
 
1293
1293
  // Contract identification
1294
1294
  applicationNumber String @unique
1295
- title String
1296
- description String? @db.Text
1295
+ title String
1296
+ description String? @db.Text
1297
1297
  applicationType String // Admin-defined: MORTGAGE, INSTALLMENT, RENT_TO_OWN, CASH, LEASE, etc.
1298
1298
 
1299
1299
  // Contract value (negotiated from unit price)
@@ -1325,7 +1325,7 @@ model Application {
1325
1325
  paymentMethodChangeRequests PaymentMethodChangeRequest[]
1326
1326
 
1327
1327
  // Transfer tracking - when a contract is transferred to a different property
1328
- transferredFromId String? @unique // Source contract if this was created via transfer
1328
+ transferredFromId String? @unique // Source contract if this was created via transfer
1329
1329
  transferredFrom Application? @relation("ApplicationTransfer", fields: [transferredFromId], references: [id])
1330
1330
  transferredTo Application? @relation("ApplicationTransfer")
1331
1331
 
@@ -1419,7 +1419,7 @@ model ApplicationRefund {
1419
1419
  // =============================================================================
1420
1420
 
1421
1421
  model ApplicationPhase {
1422
- id String @id @default(cuid())
1422
+ id String @id @default(cuid())
1423
1423
  applicationId String
1424
1424
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1425
1425
 
@@ -1473,8 +1473,8 @@ model ApplicationPhase {
1473
1473
  // =============================================================================
1474
1474
 
1475
1475
  model QuestionnairePhase {
1476
- id String @id @default(cuid())
1477
- phaseId String @unique
1476
+ id String @id @default(cuid())
1477
+ phaseId String @unique
1478
1478
  phase ApplicationPhase @relation(fields: [phaseId], references: [id], onDelete: Cascade)
1479
1479
 
1480
1480
  // Progress tracking
@@ -1507,8 +1507,8 @@ model QuestionnairePhase {
1507
1507
  // =============================================================================
1508
1508
 
1509
1509
  model DocumentationPhase {
1510
- id String @id @default(cuid())
1511
- phaseId String @unique
1510
+ id String @id @default(cuid())
1511
+ phaseId String @unique
1512
1512
  phase ApplicationPhase @relation(fields: [phaseId], references: [id], onDelete: Cascade)
1513
1513
 
1514
1514
  // Current step pointer for UX and orchestration
@@ -1547,8 +1547,8 @@ model DocumentationPhase {
1547
1547
  // =============================================================================
1548
1548
 
1549
1549
  model PaymentPhase {
1550
- id String @id @default(cuid())
1551
- phaseId String @unique
1550
+ id String @id @default(cuid())
1551
+ phaseId String @unique
1552
1552
  phase ApplicationPhase @relation(fields: [phaseId], references: [id], onDelete: Cascade)
1553
1553
 
1554
1554
  // Payment plan reference
@@ -1646,7 +1646,7 @@ model QuestionnaireField {
1646
1646
  // ApplicationEvent is purely for historical tracking and state machine transitions.
1647
1647
  // =============================================================================
1648
1648
  model ApplicationEvent {
1649
- id String @id @default(cuid())
1649
+ id String @id @default(cuid())
1650
1650
  applicationId String
1651
1651
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1652
1652
 
@@ -1797,15 +1797,15 @@ model PaymentInstallment {
1797
1797
 
1798
1798
  // Unified payment record for contracts
1799
1799
  model ApplicationPayment {
1800
- id String @id @default(cuid())
1801
- applicationId String
1802
- application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1800
+ id String @id @default(cuid())
1801
+ applicationId String
1802
+ application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1803
1803
  phaseId String?
1804
- phase ApplicationPhase? @relation(fields: [phaseId], references: [id])
1804
+ phase ApplicationPhase? @relation(fields: [phaseId], references: [id])
1805
1805
  installmentId String?
1806
1806
  installment PaymentInstallment? @relation(fields: [installmentId], references: [id])
1807
1807
  payerId String?
1808
- payer User? @relation("ApplicationPayer", fields: [payerId], references: [id])
1808
+ payer User? @relation("ApplicationPayer", fields: [payerId], references: [id])
1809
1809
 
1810
1810
  amount Float
1811
1811
  principalAmount Float @default(0)
@@ -1833,11 +1833,11 @@ model ApplicationPayment {
1833
1833
 
1834
1834
  // Contract documents (owned by contract, linked to phases/steps as needed)
1835
1835
  model ApplicationDocument {
1836
- id String @id @default(cuid())
1836
+ id String @id @default(cuid())
1837
1837
  applicationId String
1838
1838
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1839
- phaseId String? // Optional link to specific phase
1840
- stepId String? // Optional link to specific step
1839
+ phaseId String? // Optional link to specific phase
1840
+ stepId String? // Optional link to specific step
1841
1841
 
1842
1842
  name String
1843
1843
  url String
@@ -1894,9 +1894,9 @@ model DocumentTemplate {
1894
1894
  }
1895
1895
 
1896
1896
  model OfferLetter {
1897
- id String @id @default(cuid())
1898
- tenantId String
1899
- tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
1897
+ id String @id @default(cuid())
1898
+ tenantId String
1899
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
1900
1900
  applicationId String
1901
1901
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1902
1902
 
@@ -1959,11 +1959,11 @@ model OfferLetter {
1959
1959
  // =============================================================================
1960
1960
 
1961
1961
  model ApplicationTermination {
1962
- id String @id @default(cuid())
1962
+ id String @id @default(cuid())
1963
1963
  applicationId String
1964
1964
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
1965
- tenantId String
1966
- tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
1965
+ tenantId String
1966
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
1967
1967
 
1968
1968
  // Request identification
1969
1969
  requestNumber String @unique // TRM-XXXXXX
@@ -1991,8 +1991,8 @@ model ApplicationTermination {
1991
1991
  // Financial snapshot at time of request
1992
1992
  applicationSnapshot Json // Full contract state snapshot
1993
1993
  totalApplicationAmount Float
1994
- totalPaidToDate Float
1995
- outstandingBalance Float
1994
+ totalPaidToDate Float
1995
+ outstandingBalance Float
1996
1996
 
1997
1997
  // Settlement calculation
1998
1998
  refundableAmount Float @default(0) // Amount eligible for refund
@@ -2057,9 +2057,9 @@ enum PaymentMethodChangeStatus {
2057
2057
  }
2058
2058
 
2059
2059
  model PaymentMethodChangeRequest {
2060
- id String @id @default(cuid())
2061
- tenantId String
2062
- tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
2060
+ id String @id @default(cuid())
2061
+ tenantId String
2062
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
2063
2063
  applicationId String
2064
2064
  application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
2065
2065
 
@@ -2599,3 +2599,103 @@ model ApprovalRequest {
2599
2599
  @@index([type, status]) // Efficient queries for approval dashboard
2600
2600
  @@map("approval_requests")
2601
2601
  }
2602
+
2603
+ // =============================================================================
2604
+ // WORKFLOW BLOCKER TRACKING - Analytics for workflow delays
2605
+ // =============================================================================
2606
+ // Tracks who is blocking the workflow at any point, enabling analytics like:
2607
+ // - Average time customers take to upload documents
2608
+ // - Average time admins take to review/approve
2609
+ // - Most common bottleneck steps
2610
+ // - SLA compliance tracking
2611
+ // - Customer service intervention triggers
2612
+ // =============================================================================
2613
+
2614
+ /// Who is responsible for the current workflow block
2615
+ enum BlockerActor {
2616
+ CUSTOMER // Customer action required (upload, sign, pay)
2617
+ ADMIN // Admin action required (review, approve, reject)
2618
+ SYSTEM // System processing (auto-generation, external checks)
2619
+ EXTERNAL // External party (bank, government, third-party verification)
2620
+ }
2621
+
2622
+ /// Category of action that is blocking workflow
2623
+ enum BlockerCategory {
2624
+ UPLOAD // Document upload needed
2625
+ RESUBMISSION // Document resubmission after rejection
2626
+ SIGNATURE // Signature required
2627
+ REVIEW // Admin review needed
2628
+ APPROVAL // Admin approval needed
2629
+ PAYMENT // Payment required
2630
+ PROCESSING // System processing
2631
+ EXTERNAL_CHECK // External verification
2632
+ QUESTIONNAIRE // Form/questionnaire completion
2633
+ }
2634
+
2635
+ /// Urgency level for prioritization and SLA tracking
2636
+ enum BlockerUrgency {
2637
+ LOW // No immediate deadline
2638
+ NORMAL // Standard processing
2639
+ HIGH // Approaching deadline or overdue
2640
+ CRITICAL // Significantly overdue or business-critical
2641
+ }
2642
+
2643
+ /// Workflow Blocker - Records who is blocking workflow and for how long
2644
+ model WorkflowBlocker {
2645
+ id String @id @default(cuid())
2646
+ tenantId String
2647
+
2648
+ // Reference to the blocked entity
2649
+ applicationId String
2650
+ phaseId String?
2651
+ stepId String?
2652
+
2653
+ // Actor and action details
2654
+ blockerActor BlockerActor
2655
+ blockerCategory BlockerCategory
2656
+ urgency BlockerUrgency @default(NORMAL)
2657
+
2658
+ // Human-readable descriptions
2659
+ actionRequired String @db.VarChar(500) // What action is needed
2660
+ context String? @db.Text // Additional context
2661
+
2662
+ // SLA tracking
2663
+ expectedByDate DateTime? // When this action should be completed
2664
+ isOverdue Boolean @default(false)
2665
+ overdueAt DateTime? // When it became overdue
2666
+
2667
+ // Duration tracking
2668
+ startedAt DateTime @default(now()) // When this block started
2669
+ resolvedAt DateTime? // When it was resolved
2670
+ durationMs Int? // Calculated duration on resolution
2671
+
2672
+ // Resolution details
2673
+ resolvedByActor String? // Who resolved it (userId or "SYSTEM")
2674
+ resolutionTrigger String? // What action resolved it (e.g., "DOCUMENT_UPLOADED", "STEP_COMPLETED")
2675
+
2676
+ // Reminder tracking (for customer service)
2677
+ reminderCount Int @default(0) // Number of reminders sent
2678
+ lastReminderAt DateTime? // Last reminder timestamp
2679
+ nextReminderAt DateTime? // Scheduled next reminder
2680
+
2681
+ // Metadata for additional analytics
2682
+ metadata Json? // Flexible data: { documentType, stepType, phaseType, etc. }
2683
+
2684
+ createdAt DateTime @default(now())
2685
+ updatedAt DateTime @updatedAt
2686
+
2687
+ @@index([tenantId])
2688
+ @@index([applicationId])
2689
+ @@index([phaseId])
2690
+ @@index([stepId])
2691
+ @@index([blockerActor])
2692
+ @@index([blockerCategory])
2693
+ @@index([urgency])
2694
+ @@index([isOverdue])
2695
+ @@index([startedAt])
2696
+ @@index([resolvedAt])
2697
+ @@index([tenantId, blockerActor, resolvedAt]) // For "open blockers by actor" queries
2698
+ @@index([tenantId, blockerCategory, resolvedAt]) // For "open blockers by category" queries
2699
+ @@index([tenantId, isOverdue, blockerActor]) // For SLA violation queries
2700
+ @@map("workflow_blockers")
2701
+ }