@valentine-efagene/qshelter-common 2.0.30 → 2.0.32

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.
Files changed (27) hide show
  1. package/dist/generated/client/browser.d.ts +5 -0
  2. package/dist/generated/client/client.d.ts +5 -0
  3. package/dist/generated/client/commonInputTypes.d.ts +152 -10
  4. package/dist/generated/client/enums.d.ts +41 -0
  5. package/dist/generated/client/enums.js +37 -0
  6. package/dist/generated/client/internal/class.d.ts +11 -0
  7. package/dist/generated/client/internal/class.js +2 -2
  8. package/dist/generated/client/internal/prismaNamespace.d.ts +153 -1
  9. package/dist/generated/client/internal/prismaNamespace.js +67 -0
  10. package/dist/generated/client/internal/prismaNamespaceBrowser.d.ts +69 -0
  11. package/dist/generated/client/internal/prismaNamespaceBrowser.js +67 -0
  12. package/dist/generated/client/models/Contract.d.ts +271 -0
  13. package/dist/generated/client/models/ContractPhase.d.ts +52 -1
  14. package/dist/generated/client/models/ContractTermination.d.ts +3449 -0
  15. package/dist/generated/client/models/ContractTermination.js +1 -0
  16. package/dist/generated/client/models/PaymentPlan.d.ts +42 -1
  17. package/dist/generated/client/models/PropertyPaymentMethodPhase.d.ts +51 -1
  18. package/dist/generated/client/models/Tenant.d.ts +163 -0
  19. package/dist/generated/client/models/User.d.ts +586 -0
  20. package/dist/generated/client/models/index.d.ts +1 -0
  21. package/dist/generated/client/models/index.js +1 -0
  22. package/dist/generated/client/models.d.ts +1 -0
  23. package/package.json +1 -1
  24. package/prisma/migrations/20260101081428_normalize_schema/migration.sql +119 -0
  25. package/prisma/migrations/20260101102022_add_contract_termination/migration.sql +69 -0
  26. package/prisma/migrations/20260101110958_add_collect_funds/migration.sql +8 -0
  27. package/prisma/schema.prisma +165 -5
@@ -8,6 +8,7 @@ export * from './ContractPhase';
8
8
  export * from './ContractPhaseStep';
9
9
  export * from './ContractPhaseStepApproval';
10
10
  export * from './ContractPhaseStepDocument';
11
+ export * from './ContractTermination';
11
12
  export * from './ContractTransition';
12
13
  export * from './DeviceEndpoint';
13
14
  export * from './DocumentRequirementRule';
@@ -8,6 +8,7 @@ export * from './ContractPhase';
8
8
  export * from './ContractPhaseStep';
9
9
  export * from './ContractPhaseStepApproval';
10
10
  export * from './ContractPhaseStepDocument';
11
+ export * from './ContractTermination';
11
12
  export * from './ContractTransition';
12
13
  export * from './DeviceEndpoint';
13
14
  export * from './DocumentRequirementRule';
@@ -39,6 +39,7 @@ export type * from './models/ContractPayment.js';
39
39
  export type * from './models/ContractDocument.js';
40
40
  export type * from './models/ContractTransition.js';
41
41
  export type * from './models/ContractEvent.js';
42
+ export type * from './models/ContractTermination.js';
42
43
  export type * from './models/Prequalification.js';
43
44
  export type * from './models/PaymentMethodChangeRequest.js';
44
45
  export type * from './models/DocumentRequirementRule.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valentine-efagene/qshelter-common",
3
- "version": "2.0.30",
3
+ "version": "2.0.32",
4
4
  "description": "Shared database schemas and utilities for QShelter services",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -0,0 +1,119 @@
1
+ /*
2
+ Warnings:
3
+
4
+ - You are about to alter the column `status` on the `contract_documents` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(16))`.
5
+ - You are about to alter the column `status` on the `contract_installments` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(14))`.
6
+ - You are about to alter the column `status` on the `contract_payments` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(15))`.
7
+ - You are about to alter the column `decision` on the `contract_phase_step_approvals` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(13))`.
8
+ - You are about to drop the column `requiredDocumentTypes` on the `contract_phase_steps` table. All the data in the column will be lost.
9
+ - You are about to alter the column `stepType` on the `contract_phase_steps` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(11))`.
10
+ - You are about to alter the column `status` on the `contract_phase_steps` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(12))`.
11
+ - You are about to alter the column `phaseCategory` on the `contract_phases` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(7))`.
12
+ - You are about to alter the column `phaseType` on the `contract_phases` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(8))`.
13
+ - You are about to alter the column `status` on the `contract_phases` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(9))`.
14
+ - You are about to alter the column `status` on the `contracts` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(6))`.
15
+ - You are about to alter the column `state` on the `contracts` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(6))`.
16
+ - You are about to alter the column `paymentFrequency` on the `payment_plans` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(0))`.
17
+ - You are about to drop the column `requiredDocumentTypes` on the `property_payment_method_phases` table. All the data in the column will be lost.
18
+ - You are about to drop the column `stepDefinitions` on the `property_payment_method_phases` table. All the data in the column will be lost.
19
+ - You are about to alter the column `phaseCategory` on the `property_payment_method_phases` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(7))`.
20
+ - You are about to alter the column `phaseType` on the `property_payment_method_phases` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(8))`.
21
+
22
+ */
23
+ -- AlterTable
24
+ ALTER TABLE `contract_documents` MODIFY `status` ENUM('PENDING', 'APPROVED', 'REJECTED') NOT NULL DEFAULT 'PENDING';
25
+
26
+ -- AlterTable
27
+ ALTER TABLE `contract_installments` MODIFY `status` ENUM('PENDING', 'PAID', 'OVERDUE', 'PARTIALLY_PAID', 'WAIVED') NOT NULL DEFAULT 'PENDING';
28
+
29
+ -- AlterTable
30
+ ALTER TABLE `contract_payments` MODIFY `status` ENUM('INITIATED', 'PENDING', 'COMPLETED', 'FAILED', 'REFUNDED') NOT NULL DEFAULT 'INITIATED';
31
+
32
+ -- AlterTable
33
+ ALTER TABLE `contract_phase_step_approvals` MODIFY `decision` ENUM('APPROVED', 'REJECTED', 'REQUEST_CHANGES') NOT NULL;
34
+
35
+ -- AlterTable
36
+ ALTER TABLE `contract_phase_steps` DROP COLUMN `requiredDocumentTypes`,
37
+ MODIFY `stepType` ENUM('UPLOAD', 'REVIEW', 'SIGNATURE', 'APPROVAL', 'EXTERNAL_CHECK', 'WAIT') NOT NULL,
38
+ MODIFY `status` ENUM('PENDING', 'IN_PROGRESS', 'COMPLETED', 'FAILED', 'SKIPPED') NOT NULL DEFAULT 'PENDING';
39
+
40
+ -- AlterTable
41
+ ALTER TABLE `contract_phases` ADD COLUMN `approvedDocumentsCount` INTEGER NOT NULL DEFAULT 0,
42
+ ADD COLUMN `completedStepsCount` INTEGER NOT NULL DEFAULT 0,
43
+ ADD COLUMN `completionCriterion` ENUM('DOCUMENT_APPROVALS', 'PAYMENT_AMOUNT', 'STEPS_COMPLETED') NULL,
44
+ ADD COLUMN `paymentPlanSnapshot` JSON NULL,
45
+ ADD COLUMN `requiredDocumentSnapshot` JSON NULL,
46
+ ADD COLUMN `requiredDocumentsCount` INTEGER NOT NULL DEFAULT 0,
47
+ ADD COLUMN `stepDefinitionsSnapshot` JSON NULL,
48
+ ADD COLUMN `totalStepsCount` INTEGER NOT NULL DEFAULT 0,
49
+ MODIFY `phaseCategory` ENUM('DOCUMENTATION', 'PAYMENT') NOT NULL,
50
+ MODIFY `phaseType` ENUM('KYC', 'VERIFICATION', 'DOWNPAYMENT', 'MORTGAGE', 'BALLOON', 'CUSTOM') NOT NULL,
51
+ MODIFY `status` ENUM('PENDING', 'IN_PROGRESS', 'AWAITING_APPROVAL', 'ACTIVE', 'COMPLETED', 'SKIPPED', 'FAILED') NOT NULL DEFAULT 'PENDING';
52
+
53
+ -- AlterTable
54
+ ALTER TABLE `contracts` MODIFY `status` ENUM('DRAFT', 'PENDING', 'ACTIVE', 'COMPLETED', 'CANCELLED', 'TERMINATED') NOT NULL DEFAULT 'DRAFT',
55
+ MODIFY `state` ENUM('DRAFT', 'PENDING', 'ACTIVE', 'COMPLETED', 'CANCELLED', 'TERMINATED') NOT NULL DEFAULT 'DRAFT';
56
+
57
+ -- AlterTable
58
+ ALTER TABLE `payment_plans` MODIFY `paymentFrequency` ENUM('MONTHLY', 'BIWEEKLY', 'WEEKLY', 'ONE_TIME', 'CUSTOM') NOT NULL;
59
+
60
+ -- AlterTable
61
+ ALTER TABLE `property_payment_method_phases` DROP COLUMN `requiredDocumentTypes`,
62
+ DROP COLUMN `stepDefinitions`,
63
+ ADD COLUMN `completionCriterion` ENUM('DOCUMENT_APPROVALS', 'PAYMENT_AMOUNT', 'STEPS_COMPLETED') NULL,
64
+ ADD COLUMN `requiredDocumentSnapshot` JSON NULL,
65
+ ADD COLUMN `stepDefinitionsSnapshot` JSON NULL,
66
+ MODIFY `phaseCategory` ENUM('DOCUMENTATION', 'PAYMENT') NOT NULL,
67
+ MODIFY `phaseType` ENUM('KYC', 'VERIFICATION', 'DOWNPAYMENT', 'MORTGAGE', 'BALLOON', 'CUSTOM') NOT NULL;
68
+
69
+ -- CreateTable
70
+ CREATE TABLE `payment_method_phase_steps` (
71
+ `id` VARCHAR(191) NOT NULL,
72
+ `phaseId` VARCHAR(191) NOT NULL,
73
+ `name` VARCHAR(191) NOT NULL,
74
+ `stepType` ENUM('UPLOAD', 'REVIEW', 'SIGNATURE', 'APPROVAL', 'EXTERNAL_CHECK', 'WAIT') NOT NULL,
75
+ `order` INTEGER NOT NULL,
76
+ `metadata` JSON NULL,
77
+ `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
78
+ `updatedAt` DATETIME(3) NOT NULL,
79
+
80
+ INDEX `payment_method_phase_steps_phaseId_idx`(`phaseId`),
81
+ PRIMARY KEY (`id`)
82
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
83
+
84
+ -- CreateTable
85
+ CREATE TABLE `payment_method_phase_documents` (
86
+ `id` VARCHAR(191) NOT NULL,
87
+ `phaseId` VARCHAR(191) NOT NULL,
88
+ `documentType` VARCHAR(191) NOT NULL,
89
+ `isRequired` BOOLEAN NOT NULL DEFAULT true,
90
+ `description` TEXT NULL,
91
+ `allowedMimeTypes` VARCHAR(191) NULL,
92
+ `maxSizeBytes` INTEGER NULL,
93
+ `metadata` JSON NULL,
94
+ `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
95
+
96
+ INDEX `payment_method_phase_documents_phaseId_documentType_idx`(`phaseId`, `documentType`),
97
+ PRIMARY KEY (`id`)
98
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
99
+
100
+ -- CreateTable
101
+ CREATE TABLE `contract_phase_step_documents` (
102
+ `id` VARCHAR(191) NOT NULL,
103
+ `stepId` VARCHAR(191) NOT NULL,
104
+ `documentType` VARCHAR(191) NOT NULL,
105
+ `isRequired` BOOLEAN NOT NULL DEFAULT true,
106
+ `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
107
+
108
+ INDEX `contract_phase_step_documents_stepId_documentType_idx`(`stepId`, `documentType`),
109
+ PRIMARY KEY (`id`)
110
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
111
+
112
+ -- AddForeignKey
113
+ ALTER TABLE `payment_method_phase_steps` ADD CONSTRAINT `payment_method_phase_steps_phaseId_fkey` FOREIGN KEY (`phaseId`) REFERENCES `property_payment_method_phases`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
114
+
115
+ -- AddForeignKey
116
+ ALTER TABLE `payment_method_phase_documents` ADD CONSTRAINT `payment_method_phase_documents_phaseId_fkey` FOREIGN KEY (`phaseId`) REFERENCES `property_payment_method_phases`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
117
+
118
+ -- AddForeignKey
119
+ ALTER TABLE `contract_phase_step_documents` ADD CONSTRAINT `contract_phase_step_documents_stepId_fkey` FOREIGN KEY (`stepId`) REFERENCES `contract_phase_steps`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,69 @@
1
+ -- CreateTable
2
+ CREATE TABLE `contract_terminations` (
3
+ `id` VARCHAR(191) NOT NULL,
4
+ `contractId` VARCHAR(191) NOT NULL,
5
+ `tenantId` VARCHAR(191) NOT NULL,
6
+ `requestNumber` VARCHAR(191) NOT NULL,
7
+ `initiatedBy` ENUM('BUYER', 'SELLER', 'ADMIN', 'SYSTEM') NOT NULL,
8
+ `initiatorId` VARCHAR(191) NULL,
9
+ `type` ENUM('BUYER_WITHDRAWAL', 'SELLER_WITHDRAWAL', 'MUTUAL_AGREEMENT', 'PAYMENT_DEFAULT', 'DOCUMENT_FAILURE', 'FRAUD', 'FORCE_MAJEURE', 'PROPERTY_UNAVAILABLE', 'REGULATORY', 'OTHER') NOT NULL,
10
+ `reason` TEXT NULL,
11
+ `supportingDocs` JSON NULL,
12
+ `status` ENUM('REQUESTED', 'PENDING_REVIEW', 'PENDING_REFUND', 'REFUND_IN_PROGRESS', 'REFUND_COMPLETED', 'COMPLETED', 'REJECTED', 'CANCELLED') NOT NULL DEFAULT 'REQUESTED',
13
+ `requiresApproval` BOOLEAN NOT NULL DEFAULT true,
14
+ `autoApproveEligible` BOOLEAN NOT NULL DEFAULT false,
15
+ `reviewedBy` VARCHAR(191) NULL,
16
+ `reviewedAt` DATETIME(3) NULL,
17
+ `reviewNotes` TEXT NULL,
18
+ `rejectionReason` TEXT NULL,
19
+ `contractSnapshot` JSON NOT NULL,
20
+ `totalContractAmount` DOUBLE NOT NULL,
21
+ `totalPaidToDate` DOUBLE NOT NULL,
22
+ `outstandingBalance` DOUBLE NOT NULL,
23
+ `refundableAmount` DOUBLE NOT NULL DEFAULT 0,
24
+ `penaltyAmount` DOUBLE NOT NULL DEFAULT 0,
25
+ `forfeitedAmount` DOUBLE NOT NULL DEFAULT 0,
26
+ `adminFeeAmount` DOUBLE NOT NULL DEFAULT 0,
27
+ `netRefundAmount` DOUBLE NOT NULL DEFAULT 0,
28
+ `settlementNotes` TEXT NULL,
29
+ `refundStatus` ENUM('NOT_APPLICABLE', 'PENDING', 'INITIATED', 'PROCESSING', 'PARTIAL_COMPLETED', 'COMPLETED', 'FAILED') NOT NULL DEFAULT 'NOT_APPLICABLE',
30
+ `refundReference` VARCHAR(191) NULL,
31
+ `refundMethod` VARCHAR(191) NULL,
32
+ `refundAccountDetails` JSON NULL,
33
+ `refundInitiatedAt` DATETIME(3) NULL,
34
+ `refundCompletedAt` DATETIME(3) NULL,
35
+ `refundFailureReason` TEXT NULL,
36
+ `unitReleasedAt` DATETIME(3) NULL,
37
+ `unitReservedForId` VARCHAR(191) NULL,
38
+ `requestedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
39
+ `approvedAt` DATETIME(3) NULL,
40
+ `executedAt` DATETIME(3) NULL,
41
+ `completedAt` DATETIME(3) NULL,
42
+ `cancelledAt` DATETIME(3) NULL,
43
+ `idempotencyKey` VARCHAR(191) NULL,
44
+ `metadata` JSON NULL,
45
+ `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
46
+ `updatedAt` DATETIME(3) NOT NULL,
47
+
48
+ UNIQUE INDEX `contract_terminations_requestNumber_key`(`requestNumber`),
49
+ UNIQUE INDEX `contract_terminations_idempotencyKey_key`(`idempotencyKey`),
50
+ INDEX `contract_terminations_contractId_idx`(`contractId`),
51
+ INDEX `contract_terminations_tenantId_idx`(`tenantId`),
52
+ INDEX `contract_terminations_status_idx`(`status`),
53
+ INDEX `contract_terminations_type_idx`(`type`),
54
+ INDEX `contract_terminations_initiatorId_idx`(`initiatorId`),
55
+ INDEX `contract_terminations_requestedAt_idx`(`requestedAt`),
56
+ PRIMARY KEY (`id`)
57
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
58
+
59
+ -- AddForeignKey
60
+ ALTER TABLE `contract_terminations` ADD CONSTRAINT `contract_terminations_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `contracts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
61
+
62
+ -- AddForeignKey
63
+ ALTER TABLE `contract_terminations` ADD CONSTRAINT `contract_terminations_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
64
+
65
+ -- AddForeignKey
66
+ ALTER TABLE `contract_terminations` ADD CONSTRAINT `contract_terminations_initiatorId_fkey` FOREIGN KEY (`initiatorId`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
67
+
68
+ -- AddForeignKey
69
+ ALTER TABLE `contract_terminations` ADD CONSTRAINT `contract_terminations_reviewedBy_fkey` FOREIGN KEY (`reviewedBy`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,8 @@
1
+ -- AlterTable
2
+ ALTER TABLE `contract_phases` ADD COLUMN `collectFunds` BOOLEAN NOT NULL DEFAULT true;
3
+
4
+ -- AlterTable
5
+ ALTER TABLE `payment_plans` ADD COLUMN `collectFunds` BOOLEAN NOT NULL DEFAULT true;
6
+
7
+ -- AlterTable
8
+ ALTER TABLE `property_payment_method_phases` ADD COLUMN `collectFunds` BOOLEAN NULL;
@@ -99,6 +99,51 @@ enum ApprovalDecision {
99
99
  REQUEST_CHANGES
100
100
  }
101
101
 
102
+ // =============================================================================
103
+ // CONTRACT TERMINATION / CANCELLATION ENUMS
104
+ // =============================================================================
105
+
106
+ enum TerminationType {
107
+ BUYER_WITHDRAWAL // Buyer wants to cancel (voluntary)
108
+ SELLER_WITHDRAWAL // Seller/developer cancels
109
+ MUTUAL_AGREEMENT // Both parties agree to terminate
110
+ PAYMENT_DEFAULT // Buyer failed payment obligations
111
+ DOCUMENT_FAILURE // Buyer failed to provide required documents
112
+ FRAUD // Fraudulent activity detected
113
+ FORCE_MAJEURE // External circumstances (disaster, etc.)
114
+ PROPERTY_UNAVAILABLE // Property no longer available
115
+ REGULATORY // Regulatory/legal requirement
116
+ OTHER // Other reasons (with notes)
117
+ }
118
+
119
+ enum TerminationStatus {
120
+ REQUESTED // Initial request submitted
121
+ PENDING_REVIEW // Awaiting admin review
122
+ PENDING_REFUND // Approved, awaiting refund processing
123
+ REFUND_IN_PROGRESS // Refund being processed
124
+ REFUND_COMPLETED // Refund completed
125
+ COMPLETED // Termination fully executed (no refund or refund done)
126
+ REJECTED // Termination request rejected
127
+ CANCELLED // Termination request was cancelled
128
+ }
129
+
130
+ enum RefundStatus {
131
+ NOT_APPLICABLE // No refund needed (no payments made)
132
+ PENDING // Refund not yet initiated
133
+ INITIATED // Refund request sent to payment gateway
134
+ PROCESSING // Gateway processing refund
135
+ PARTIAL_COMPLETED // Some refund completed (penalties deducted)
136
+ COMPLETED // Full refund completed
137
+ FAILED // Refund failed (needs manual intervention)
138
+ }
139
+
140
+ enum TerminationInitiator {
141
+ BUYER
142
+ SELLER
143
+ ADMIN
144
+ SYSTEM
145
+ }
146
+
102
147
  enum CompletionCriterion {
103
148
  DOCUMENT_APPROVALS
104
149
  PAYMENT_AMOUNT
@@ -160,6 +205,10 @@ model User {
160
205
  paymentMethodChangeRequests PaymentMethodChangeRequest[] @relation("ChangeRequestor")
161
206
  reviewedChangeRequests PaymentMethodChangeRequest[] @relation("ChangeReviewer")
162
207
 
208
+ // Contract terminations
209
+ initiatedTerminations ContractTermination[] @relation("TerminationInitiator")
210
+ reviewedTerminations ContractTermination[] @relation("TerminationReviewer")
211
+
163
212
  @@index([email])
164
213
  @@index([tenantId])
165
214
  @@map("users")
@@ -234,6 +283,9 @@ model Tenant {
234
283
  paymentMethodChangeRequests PaymentMethodChangeRequest[]
235
284
  documentRequirementRules DocumentRequirementRule[]
236
285
 
286
+ // Contract terminations
287
+ contractTerminations ContractTermination[]
288
+
237
289
  @@index([subdomain])
238
290
  @@map("tenants")
239
291
  }
@@ -617,6 +669,11 @@ model PaymentPlan {
617
669
  calculateInterestDaily Boolean @default(false)
618
670
  gracePeriodDays Int @default(0)
619
671
 
672
+ // Fund collection behavior
673
+ // true = we collect funds via wallet/gateway (e.g., downpayment)
674
+ // false = external payment, we only track/reconcile (e.g., bank mortgage)
675
+ collectFunds Boolean @default(true)
676
+
620
677
  createdAt DateTime @default(now())
621
678
  updatedAt DateTime @updatedAt
622
679
 
@@ -713,6 +770,11 @@ model PropertyPaymentMethodPhase {
713
770
  interestRate Float?
714
771
  percentOfPrice Float? // e.g., 10.0 for 10% downpayment
715
772
 
773
+ // Fund collection behavior (inherited from PaymentPlan if not set)
774
+ // true = we collect funds via wallet/gateway (e.g., downpayment)
775
+ // false = external payment, we only track/reconcile (e.g., bank mortgage)
776
+ collectFunds Boolean? // null = inherit from PaymentPlan
777
+
716
778
  // Activation rules
717
779
  requiresPreviousPhaseCompletion Boolean @default(true)
718
780
  minimumCompletionPercentage Float?
@@ -827,11 +889,12 @@ model Contract {
827
889
  updatedAt DateTime @updatedAt
828
890
 
829
891
  // Relations
830
- phases ContractPhase[]
831
- documents ContractDocument[]
832
- payments ContractPayment[]
833
- transitions ContractTransition[]
834
- events ContractEvent[]
892
+ phases ContractPhase[]
893
+ documents ContractDocument[]
894
+ payments ContractPayment[]
895
+ transitions ContractTransition[]
896
+ events ContractEvent[]
897
+ terminations ContractTermination[]
835
898
 
836
899
  // Prequalification that led to this contract (optional)
837
900
  prequalification Prequalification?
@@ -875,6 +938,11 @@ model ContractPhase {
875
938
  remainingAmount Float?
876
939
  interestRate Float?
877
940
 
941
+ // Fund collection behavior (snapshotted from template at contract creation)
942
+ // true = we collect funds via wallet/gateway (e.g., downpayment)
943
+ // false = external payment, we only track/reconcile (e.g., bank mortgage)
944
+ collectFunds Boolean @default(true)
945
+
878
946
  // Progress counters (for efficient activation checks)
879
947
  approvedDocumentsCount Int @default(0)
880
948
  requiredDocumentsCount Int @default(0)
@@ -1107,6 +1175,98 @@ model ContractEvent {
1107
1175
  @@map("contract_events")
1108
1176
  }
1109
1177
 
1178
+ // =============================================================================
1179
+ // CONTRACT TERMINATION - Full lifecycle for cancellation/termination
1180
+ // =============================================================================
1181
+ // Tracks termination requests from initiation through refund completion.
1182
+ // Industry-standard flow:
1183
+ // 1. Request created (by buyer/seller/admin/system)
1184
+ // 2. Admin reviews (if required by policy)
1185
+ // 3. Financial settlement calculated (refunds, penalties, forfeitures)
1186
+ // 4. Refund processed (if applicable)
1187
+ // 5. Contract marked terminated, unit released
1188
+ // =============================================================================
1189
+
1190
+ model ContractTermination {
1191
+ id String @id @default(cuid())
1192
+ contractId String
1193
+ contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
1194
+ tenantId String
1195
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
1196
+
1197
+ // Request identification
1198
+ requestNumber String @unique // TRM-XXXXXX
1199
+
1200
+ // Who initiated and why
1201
+ initiatedBy TerminationInitiator
1202
+ initiatorId String? // userId if BUYER/SELLER/ADMIN
1203
+ initiator User? @relation("TerminationInitiator", fields: [initiatorId], references: [id])
1204
+ type TerminationType
1205
+ reason String? @db.Text
1206
+ supportingDocs Json? // [{type, url, uploadedAt}]
1207
+
1208
+ // Workflow status
1209
+ status TerminationStatus @default(REQUESTED)
1210
+ requiresApproval Boolean @default(true)
1211
+ autoApproveEligible Boolean @default(false) // Pre-signature, no payments
1212
+
1213
+ // Admin review
1214
+ reviewedBy String?
1215
+ reviewer User? @relation("TerminationReviewer", fields: [reviewedBy], references: [id])
1216
+ reviewedAt DateTime?
1217
+ reviewNotes String? @db.Text
1218
+ rejectionReason String? @db.Text
1219
+
1220
+ // Financial snapshot at time of request
1221
+ contractSnapshot Json // Full contract state snapshot
1222
+ totalContractAmount Float
1223
+ totalPaidToDate Float
1224
+ outstandingBalance Float
1225
+
1226
+ // Settlement calculation
1227
+ refundableAmount Float @default(0) // Amount eligible for refund
1228
+ penaltyAmount Float @default(0) // Penalties/fees to deduct
1229
+ forfeitedAmount Float @default(0) // Amount forfeited (non-refundable deposits)
1230
+ adminFeeAmount Float @default(0) // Processing fees
1231
+ netRefundAmount Float @default(0) // refundableAmount - penaltyAmount - adminFeeAmount
1232
+ settlementNotes String? @db.Text
1233
+
1234
+ // Refund processing
1235
+ refundStatus RefundStatus @default(NOT_APPLICABLE)
1236
+ refundReference String? // Payment gateway reference
1237
+ refundMethod String? // ORIGINAL_METHOD, BANK_TRANSFER, CHECK, WALLET
1238
+ refundAccountDetails Json? // Encrypted bank details if needed
1239
+ refundInitiatedAt DateTime?
1240
+ refundCompletedAt DateTime?
1241
+ refundFailureReason String? @db.Text
1242
+
1243
+ // Property unit handling
1244
+ unitReleasedAt DateTime?
1245
+ unitReservedForId String? // If unit being held for another buyer
1246
+
1247
+ // Timing
1248
+ requestedAt DateTime @default(now())
1249
+ approvedAt DateTime?
1250
+ executedAt DateTime?
1251
+ completedAt DateTime?
1252
+ cancelledAt DateTime?
1253
+
1254
+ // Idempotency and audit
1255
+ idempotencyKey String? @unique
1256
+ metadata Json?
1257
+
1258
+ createdAt DateTime @default(now())
1259
+ updatedAt DateTime @updatedAt
1260
+
1261
+ @@index([contractId])
1262
+ @@index([tenantId])
1263
+ @@index([status])
1264
+ @@index([type])
1265
+ @@index([initiatorId])
1266
+ @@index([requestedAt])
1267
+ @@map("contract_terminations")
1268
+ }
1269
+
1110
1270
  // =============================================================================
1111
1271
  // PREQUALIFICATION - Eligibility assessment before contract creation
1112
1272
  // =============================================================================