@valentine-efagene/qshelter-common 2.0.150 → 2.0.152
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.
- package/dist/generated/client/browser.d.ts +13 -2
- package/dist/generated/client/client.d.ts +15 -4
- package/dist/generated/client/client.js +2 -2
- package/dist/generated/client/commonInputTypes.d.ts +50 -190
- package/dist/generated/client/enums.d.ts +7 -34
- package/dist/generated/client/enums.js +6 -30
- package/dist/generated/client/internal/class.d.ts +29 -7
- package/dist/generated/client/internal/class.js +2 -2
- package/dist/generated/client/internal/prismaNamespace.d.ts +185 -34
- package/dist/generated/client/internal/prismaNamespace.js +42 -13
- package/dist/generated/client/internal/prismaNamespaceBrowser.d.ts +46 -13
- package/dist/generated/client/internal/prismaNamespaceBrowser.js +42 -13
- package/dist/generated/client/models/ApplicationOrganization.d.ts +308 -67
- package/dist/generated/client/models/ApprovalStage.d.ts +210 -91
- package/dist/generated/client/models/ApprovalStageProgress.d.ts +258 -69
- package/dist/generated/client/models/DocumentApproval.d.ts +196 -65
- package/dist/generated/client/models/DocumentReview.d.ts +475 -86
- package/dist/generated/client/models/Organization.d.ts +424 -52
- package/dist/generated/client/models/OrganizationMember.d.ts +42 -169
- package/dist/generated/client/models/OrganizationType.d.ts +1982 -0
- package/dist/generated/client/models/OrganizationType.js +1 -0
- package/dist/generated/client/models/OrganizationTypeAssignment.d.ts +1159 -0
- package/dist/generated/client/models/OrganizationTypeAssignment.js +1 -0
- package/dist/generated/client/models/Property.d.ts +59 -120
- package/dist/generated/client/models/Tenant.d.ts +575 -4
- package/dist/generated/client/models/User.d.ts +0 -12
- package/dist/generated/client/models/index.d.ts +2 -0
- package/dist/generated/client/models/index.js +2 -0
- package/dist/generated/client/models.d.ts +2 -0
- package/package.json +1 -1
- package/prisma/migrations/20260125090213_remove_is_published_use_status_enum/migration.sql +10 -0
- package/prisma/migrations/20260125102448_org_types_many_to_many/migration.sql +153 -0
- package/prisma/migrations/20260125103700_20260125102448_org_types_many_to_many_fix/migration.sql +5 -0
- package/prisma/schema.prisma +121 -81
|
@@ -760,18 +760,6 @@ export type UserNullableScalarRelationFilter = {
|
|
|
760
760
|
is?: Prisma.UserWhereInput | null;
|
|
761
761
|
isNot?: Prisma.UserWhereInput | null;
|
|
762
762
|
};
|
|
763
|
-
export type StringFieldUpdateOperationsInput = {
|
|
764
|
-
set?: string;
|
|
765
|
-
};
|
|
766
|
-
export type NullableStringFieldUpdateOperationsInput = {
|
|
767
|
-
set?: string | null;
|
|
768
|
-
};
|
|
769
|
-
export type BoolFieldUpdateOperationsInput = {
|
|
770
|
-
set?: boolean;
|
|
771
|
-
};
|
|
772
|
-
export type DateTimeFieldUpdateOperationsInput = {
|
|
773
|
-
set?: Date | string;
|
|
774
|
-
};
|
|
775
763
|
export type NullableDateTimeFieldUpdateOperationsInput = {
|
|
776
764
|
set?: Date | string | null;
|
|
777
765
|
};
|
|
@@ -30,6 +30,8 @@ export * from './OAuthState';
|
|
|
30
30
|
export * from './OfferLetter';
|
|
31
31
|
export * from './Organization';
|
|
32
32
|
export * from './OrganizationMember';
|
|
33
|
+
export * from './OrganizationType';
|
|
34
|
+
export * from './OrganizationTypeAssignment';
|
|
33
35
|
export * from './PasswordReset';
|
|
34
36
|
export * from './PaymentInstallment';
|
|
35
37
|
export * from './PaymentMethodChangeRequest';
|
|
@@ -30,6 +30,8 @@ export * from './OAuthState';
|
|
|
30
30
|
export * from './OfferLetter';
|
|
31
31
|
export * from './Organization';
|
|
32
32
|
export * from './OrganizationMember';
|
|
33
|
+
export * from './OrganizationType';
|
|
34
|
+
export * from './OrganizationTypeAssignment';
|
|
33
35
|
export * from './PasswordReset';
|
|
34
36
|
export * from './PaymentInstallment';
|
|
35
37
|
export * from './PaymentMethodChangeRequest';
|
package/package.json
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the column `isPublished` on the `properties` table. All the data in the column will be lost.
|
|
5
|
+
- You are about to alter the column `status` on the `properties` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Enum(EnumId(5))`.
|
|
6
|
+
|
|
7
|
+
*/
|
|
8
|
+
-- AlterTable
|
|
9
|
+
ALTER TABLE `properties` DROP COLUMN `isPublished`,
|
|
10
|
+
MODIFY `status` ENUM('DRAFT', 'PUBLISHED', 'SOLD_OUT', 'ARCHIVED') NOT NULL DEFAULT 'DRAFT';
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the column `role` on the `application_organizations` table. All the data in the column will be lost.
|
|
5
|
+
- You are about to drop the column `reviewParty` on the `approval_stage_progress` table. All the data in the column will be lost.
|
|
6
|
+
- You are about to drop the column `organizationId` on the `approval_stages` table. All the data in the column will be lost.
|
|
7
|
+
- You are about to drop the column `reviewParty` on the `approval_stages` table. All the data in the column will be lost.
|
|
8
|
+
- You are about to drop the column `reviewParty` on the `document_approvals` table. All the data in the column will be lost.
|
|
9
|
+
- You are about to drop the column `reviewParty` on the `document_reviews` table. All the data in the column will be lost.
|
|
10
|
+
- You are about to drop the column `approvalLimit` on the `organization_members` table. All the data in the column will be lost.
|
|
11
|
+
- You are about to drop the column `canApprove` on the `organization_members` table. All the data in the column will be lost.
|
|
12
|
+
- You are about to drop the column `role` on the `organization_members` table. All the data in the column will be lost.
|
|
13
|
+
- You are about to drop the column `type` on the `organizations` table. All the data in the column will be lost.
|
|
14
|
+
- A unique constraint covering the columns `[applicationId,assignedAsTypeId]` on the table `application_organizations` will be added. If there are existing duplicate values, this will fail.
|
|
15
|
+
- A unique constraint covering the columns `[documentId,organizationId]` on the table `document_reviews` will be added. If there are existing duplicate values, this will fail.
|
|
16
|
+
- Added the required column `assignedAsTypeId` to the `application_organizations` table without a default value. This is not possible if the table is not empty.
|
|
17
|
+
- Added the required column `organizationTypeId` to the `approval_stage_progress` table without a default value. This is not possible if the table is not empty.
|
|
18
|
+
- Added the required column `organizationTypeId` to the `approval_stages` table without a default value. This is not possible if the table is not empty.
|
|
19
|
+
- Added the required column `organizationTypeId` to the `document_approvals` table without a default value. This is not possible if the table is not empty.
|
|
20
|
+
|
|
21
|
+
*/
|
|
22
|
+
-- DropForeignKey
|
|
23
|
+
ALTER TABLE `application_organizations` DROP FOREIGN KEY `application_organizations_applicationId_fkey`;
|
|
24
|
+
|
|
25
|
+
-- DropForeignKey
|
|
26
|
+
ALTER TABLE `document_reviews` DROP FOREIGN KEY `document_reviews_documentId_fkey`;
|
|
27
|
+
|
|
28
|
+
-- DropIndex
|
|
29
|
+
DROP INDEX `application_organizations_applicationId_organizationId_role_key` ON `application_organizations`;
|
|
30
|
+
|
|
31
|
+
-- DropIndex
|
|
32
|
+
DROP INDEX `application_organizations_role_idx` ON `application_organizations`;
|
|
33
|
+
|
|
34
|
+
-- DropIndex
|
|
35
|
+
DROP INDEX `document_reviews_documentId_reviewParty_organizationId_key` ON `document_reviews`;
|
|
36
|
+
|
|
37
|
+
-- DropIndex
|
|
38
|
+
DROP INDEX `document_reviews_reviewParty_idx` ON `document_reviews`;
|
|
39
|
+
|
|
40
|
+
-- DropIndex
|
|
41
|
+
DROP INDEX `organization_members_role_idx` ON `organization_members`;
|
|
42
|
+
|
|
43
|
+
-- DropIndex
|
|
44
|
+
DROP INDEX `organizations_type_idx` ON `organizations`;
|
|
45
|
+
|
|
46
|
+
-- AlterTable
|
|
47
|
+
ALTER TABLE `application_organizations` DROP COLUMN `role`,
|
|
48
|
+
ADD COLUMN `assignedAsTypeId` VARCHAR(191) NOT NULL;
|
|
49
|
+
|
|
50
|
+
-- AlterTable
|
|
51
|
+
ALTER TABLE `approval_stage_progress` DROP COLUMN `reviewParty`,
|
|
52
|
+
ADD COLUMN `organizationTypeId` VARCHAR(191) NOT NULL;
|
|
53
|
+
|
|
54
|
+
-- AlterTable
|
|
55
|
+
ALTER TABLE `approval_stages` DROP COLUMN `organizationId`,
|
|
56
|
+
DROP COLUMN `reviewParty`,
|
|
57
|
+
ADD COLUMN `organizationTypeId` VARCHAR(191) NOT NULL;
|
|
58
|
+
|
|
59
|
+
-- AlterTable
|
|
60
|
+
ALTER TABLE `document_approvals` DROP COLUMN `reviewParty`,
|
|
61
|
+
ADD COLUMN `organizationTypeId` VARCHAR(191) NOT NULL;
|
|
62
|
+
|
|
63
|
+
-- AlterTable
|
|
64
|
+
ALTER TABLE `document_reviews` DROP COLUMN `reviewParty`,
|
|
65
|
+
ADD COLUMN `organizationTypeId` VARCHAR(191) NULL;
|
|
66
|
+
|
|
67
|
+
-- AlterTable
|
|
68
|
+
ALTER TABLE `organization_members` DROP COLUMN `approvalLimit`,
|
|
69
|
+
DROP COLUMN `canApprove`,
|
|
70
|
+
DROP COLUMN `role`,
|
|
71
|
+
ADD COLUMN `joinedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3);
|
|
72
|
+
|
|
73
|
+
-- AlterTable
|
|
74
|
+
ALTER TABLE `organizations` DROP COLUMN `type`;
|
|
75
|
+
|
|
76
|
+
-- CreateTable
|
|
77
|
+
CREATE TABLE `organization_types` (
|
|
78
|
+
`id` VARCHAR(191) NOT NULL,
|
|
79
|
+
`tenantId` VARCHAR(191) NOT NULL,
|
|
80
|
+
`code` VARCHAR(191) NOT NULL,
|
|
81
|
+
`name` VARCHAR(191) NOT NULL,
|
|
82
|
+
`description` TEXT NULL,
|
|
83
|
+
`isSystemType` BOOLEAN NOT NULL DEFAULT false,
|
|
84
|
+
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
85
|
+
`updatedAt` DATETIME(3) NOT NULL,
|
|
86
|
+
|
|
87
|
+
INDEX `organization_types_tenantId_idx`(`tenantId`),
|
|
88
|
+
INDEX `organization_types_code_idx`(`code`),
|
|
89
|
+
UNIQUE INDEX `organization_types_tenantId_code_key`(`tenantId`, `code`),
|
|
90
|
+
PRIMARY KEY (`id`)
|
|
91
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
92
|
+
|
|
93
|
+
-- CreateTable
|
|
94
|
+
CREATE TABLE `organization_type_assignments` (
|
|
95
|
+
`id` VARCHAR(191) NOT NULL,
|
|
96
|
+
`organizationId` VARCHAR(191) NOT NULL,
|
|
97
|
+
`typeId` VARCHAR(191) NOT NULL,
|
|
98
|
+
`isPrimary` BOOLEAN NOT NULL DEFAULT false,
|
|
99
|
+
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
100
|
+
|
|
101
|
+
INDEX `organization_type_assignments_organizationId_idx`(`organizationId`),
|
|
102
|
+
INDEX `organization_type_assignments_typeId_idx`(`typeId`),
|
|
103
|
+
UNIQUE INDEX `organization_type_assignments_organizationId_typeId_key`(`organizationId`, `typeId`),
|
|
104
|
+
PRIMARY KEY (`id`)
|
|
105
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
106
|
+
|
|
107
|
+
-- CreateIndex
|
|
108
|
+
CREATE INDEX `application_organizations_assignedAsTypeId_idx` ON `application_organizations`(`assignedAsTypeId`);
|
|
109
|
+
|
|
110
|
+
-- CreateIndex
|
|
111
|
+
CREATE UNIQUE INDEX `application_organizations_applicationId_assignedAsTypeId_key` ON `application_organizations`(`applicationId`, `assignedAsTypeId`);
|
|
112
|
+
|
|
113
|
+
-- CreateIndex
|
|
114
|
+
CREATE INDEX `approval_stages_organizationTypeId_idx` ON `approval_stages`(`organizationTypeId`);
|
|
115
|
+
|
|
116
|
+
-- CreateIndex
|
|
117
|
+
CREATE INDEX `document_approvals_organizationTypeId_idx` ON `document_approvals`(`organizationTypeId`);
|
|
118
|
+
|
|
119
|
+
-- CreateIndex
|
|
120
|
+
CREATE INDEX `document_reviews_organizationId_idx` ON `document_reviews`(`organizationId`);
|
|
121
|
+
|
|
122
|
+
-- CreateIndex
|
|
123
|
+
CREATE INDEX `document_reviews_organizationTypeId_idx` ON `document_reviews`(`organizationTypeId`);
|
|
124
|
+
|
|
125
|
+
-- CreateIndex
|
|
126
|
+
CREATE UNIQUE INDEX `document_reviews_documentId_organizationId_key` ON `document_reviews`(`documentId`, `organizationId`);
|
|
127
|
+
|
|
128
|
+
-- AddForeignKey
|
|
129
|
+
ALTER TABLE `organization_types` ADD CONSTRAINT `organization_types_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
130
|
+
|
|
131
|
+
-- AddForeignKey
|
|
132
|
+
ALTER TABLE `organization_type_assignments` ADD CONSTRAINT `organization_type_assignments_organizationId_fkey` FOREIGN KEY (`organizationId`) REFERENCES `organizations`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
133
|
+
|
|
134
|
+
-- AddForeignKey
|
|
135
|
+
ALTER TABLE `organization_type_assignments` ADD CONSTRAINT `organization_type_assignments_typeId_fkey` FOREIGN KEY (`typeId`) REFERENCES `organization_types`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
136
|
+
|
|
137
|
+
-- AddForeignKey
|
|
138
|
+
ALTER TABLE `approval_stages` ADD CONSTRAINT `approval_stages_organizationTypeId_fkey` FOREIGN KEY (`organizationTypeId`) REFERENCES `organization_types`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
139
|
+
|
|
140
|
+
-- AddForeignKey
|
|
141
|
+
ALTER TABLE `application_organizations` ADD CONSTRAINT `application_organizations_assignedAsTypeId_fkey` FOREIGN KEY (`assignedAsTypeId`) REFERENCES `organization_types`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
142
|
+
|
|
143
|
+
-- AddForeignKey
|
|
144
|
+
ALTER TABLE `document_reviews` ADD CONSTRAINT `document_reviews_organizationId_fkey` FOREIGN KEY (`organizationId`) REFERENCES `organizations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
|
145
|
+
|
|
146
|
+
-- AddForeignKey
|
|
147
|
+
ALTER TABLE `document_reviews` ADD CONSTRAINT `document_reviews_organizationTypeId_fkey` FOREIGN KEY (`organizationTypeId`) REFERENCES `organization_types`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
|
148
|
+
|
|
149
|
+
-- AddForeignKey
|
|
150
|
+
ALTER TABLE `approval_stage_progress` ADD CONSTRAINT `approval_stage_progress_organizationTypeId_fkey` FOREIGN KEY (`organizationTypeId`) REFERENCES `organization_types`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
151
|
+
|
|
152
|
+
-- AddForeignKey
|
|
153
|
+
ALTER TABLE `document_approvals` ADD CONSTRAINT `document_approvals_organizationTypeId_fkey` FOREIGN KEY (`organizationTypeId`) REFERENCES `organization_types`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
package/prisma/migrations/20260125103700_20260125102448_org_types_many_to_many_fix/migration.sql
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- AddForeignKey
|
|
2
|
+
ALTER TABLE `application_organizations` ADD CONSTRAINT `application_organizations_applicationId_fkey` FOREIGN KEY (`applicationId`) REFERENCES `applications`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
3
|
+
|
|
4
|
+
-- AddForeignKey
|
|
5
|
+
ALTER TABLE `document_reviews` ADD CONSTRAINT `document_reviews_documentId_fkey` FOREIGN KEY (`documentId`) REFERENCES `application_documents`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
package/prisma/schema.prisma
CHANGED
|
@@ -51,6 +51,13 @@ enum PaymentFrequency {
|
|
|
51
51
|
CUSTOM
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
enum PropertyStatus {
|
|
55
|
+
DRAFT
|
|
56
|
+
PUBLISHED
|
|
57
|
+
SOLD_OUT
|
|
58
|
+
ARCHIVED
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
enum ApplicationStatus {
|
|
55
62
|
DRAFT
|
|
56
63
|
PENDING
|
|
@@ -196,17 +203,69 @@ enum ApprovalDecision {
|
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
// =============================================================================
|
|
199
|
-
// ORGANIZATION
|
|
206
|
+
// ORGANIZATION TYPE - Lookup table for organization types (replaces enum)
|
|
207
|
+
// =============================================================================
|
|
208
|
+
// Organizations can have multiple types via OrganizationTypeAssignment.
|
|
209
|
+
// Example: QShelter can be both PLATFORM and DEVELOPER.
|
|
210
|
+
// System types are seeded during tenant bootstrap and cannot be deleted.
|
|
200
211
|
// =============================================================================
|
|
201
212
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
213
|
+
model OrganizationType {
|
|
214
|
+
id String @id @default(cuid())
|
|
215
|
+
tenantId String
|
|
216
|
+
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
217
|
+
code String // "PLATFORM", "BANK", "DEVELOPER", "LEGAL", "INSURER", "GOVERNMENT"
|
|
218
|
+
name String // Human-readable: "Platform Operator", "Bank/Lender", etc.
|
|
219
|
+
description String? @db.Text
|
|
220
|
+
|
|
221
|
+
// System types are seeded during bootstrap and cannot be deleted
|
|
222
|
+
isSystemType Boolean @default(false)
|
|
223
|
+
|
|
224
|
+
createdAt DateTime @default(now())
|
|
225
|
+
updatedAt DateTime @updatedAt
|
|
226
|
+
|
|
227
|
+
// Organizations with this type
|
|
228
|
+
organizations OrganizationTypeAssignment[]
|
|
229
|
+
|
|
230
|
+
// Applications assigned to orgs acting as this type
|
|
231
|
+
applicationOrganizations ApplicationOrganization[]
|
|
232
|
+
|
|
233
|
+
// Approval stages that require this type of organization
|
|
234
|
+
approvalStages ApprovalStage[]
|
|
235
|
+
|
|
236
|
+
// Document reviews performed by orgs acting as this type (audit snapshot)
|
|
237
|
+
documentReviews DocumentReview[]
|
|
238
|
+
|
|
239
|
+
// Approval stage progress instances
|
|
240
|
+
approvalStageProgress ApprovalStageProgress[]
|
|
241
|
+
|
|
242
|
+
// Document approvals
|
|
243
|
+
documentApprovals DocumentApproval[]
|
|
244
|
+
|
|
245
|
+
@@unique([tenantId, code])
|
|
246
|
+
@@index([tenantId])
|
|
247
|
+
@@index([code])
|
|
248
|
+
@@map("organization_types")
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/// Links organizations to their types (many-to-many)
|
|
252
|
+
/// An organization can have multiple types (e.g., QShelter is PLATFORM + DEVELOPER)
|
|
253
|
+
model OrganizationTypeAssignment {
|
|
254
|
+
id String @id @default(cuid())
|
|
255
|
+
organizationId String
|
|
256
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
257
|
+
typeId String
|
|
258
|
+
orgType OrganizationType @relation(fields: [typeId], references: [id], onDelete: Cascade)
|
|
259
|
+
|
|
260
|
+
// Which type is the primary one for display purposes
|
|
261
|
+
isPrimary Boolean @default(false)
|
|
262
|
+
|
|
263
|
+
createdAt DateTime @default(now())
|
|
264
|
+
|
|
265
|
+
@@unique([organizationId, typeId])
|
|
266
|
+
@@index([organizationId])
|
|
267
|
+
@@index([typeId])
|
|
268
|
+
@@map("organization_type_assignments")
|
|
210
269
|
}
|
|
211
270
|
|
|
212
271
|
/// Status of an organization
|
|
@@ -217,14 +276,6 @@ enum OrganizationStatus {
|
|
|
217
276
|
INACTIVE // No longer active
|
|
218
277
|
}
|
|
219
278
|
|
|
220
|
-
/// Role of a member within an organization
|
|
221
|
-
enum OrganizationRole {
|
|
222
|
-
ADMIN // Can manage org settings, members, and full operations
|
|
223
|
-
MANAGER // Can approve transactions within limits (checker)
|
|
224
|
-
OFFICER // Regular employee, can initiate actions (maker)
|
|
225
|
-
VIEWER // Read-only access to organization data
|
|
226
|
-
}
|
|
227
|
-
|
|
228
279
|
// =============================================================================
|
|
229
280
|
// CONTRACT TERMINATION / CANCELLATION ENUMS
|
|
230
281
|
// =============================================================================
|
|
@@ -267,21 +318,9 @@ enum CompletionCriterion {
|
|
|
267
318
|
}
|
|
268
319
|
|
|
269
320
|
// =============================================================================
|
|
270
|
-
//
|
|
271
|
-
// =============================================================================
|
|
272
|
-
// Enables different organizations to review the same document independently
|
|
321
|
+
// DOCUMENT REVIEW ENUMS
|
|
273
322
|
// =============================================================================
|
|
274
323
|
|
|
275
|
-
enum ReviewParty {
|
|
276
|
-
INTERNAL // Your internal team (compliance, underwriting, etc.)
|
|
277
|
-
BANK // Partner bank/lender
|
|
278
|
-
DEVELOPER // Property developer
|
|
279
|
-
LEGAL // Legal team
|
|
280
|
-
GOVERNMENT // Government agencies (e.g., land registry)
|
|
281
|
-
INSURER // Insurance company
|
|
282
|
-
CUSTOMER // Customer acknowledgment/signature
|
|
283
|
-
}
|
|
284
|
-
|
|
285
324
|
enum ReviewDecision {
|
|
286
325
|
PENDING // Review not yet performed
|
|
287
326
|
APPROVED // Document approved by this party
|
|
@@ -616,9 +655,12 @@ model Organization {
|
|
|
616
655
|
id String @id @default(cuid())
|
|
617
656
|
tenantId String
|
|
618
657
|
name String // e.g., "Access Bank PLC", "Lekki Gardens Ltd"
|
|
619
|
-
type OrganizationType // PLATFORM, BANK, DEVELOPER, LEGAL, INSURER, GOVERNMENT
|
|
620
658
|
status OrganizationStatus @default(PENDING)
|
|
621
659
|
|
|
660
|
+
// Organization types (many-to-many via OrganizationTypeAssignment)
|
|
661
|
+
// An org can have multiple types (e.g., QShelter is PLATFORM + DEVELOPER)
|
|
662
|
+
types OrganizationTypeAssignment[]
|
|
663
|
+
|
|
622
664
|
// Platform organization flag - marks the tenant's own organization
|
|
623
665
|
isPlatformOrg Boolean @default(false)
|
|
624
666
|
|
|
@@ -660,41 +702,39 @@ model Organization {
|
|
|
660
702
|
// Bank-specific document requirements (for BANK type organizations)
|
|
661
703
|
documentRequirements BankDocumentRequirement[]
|
|
662
704
|
|
|
705
|
+
// Document reviews performed by this organization
|
|
706
|
+
documentReviews DocumentReview[]
|
|
707
|
+
|
|
663
708
|
// Properties developed by this organization (for DEVELOPERs)
|
|
664
709
|
// developedProperties Property[] @relation("PropertyDeveloper")
|
|
665
710
|
|
|
666
711
|
@@unique([tenantId, bankCode]) // Bank codes unique within tenant
|
|
667
712
|
@@unique([tenantId, cacNumber]) // CAC numbers unique within tenant
|
|
668
713
|
@@index([tenantId])
|
|
669
|
-
@@index([type])
|
|
670
714
|
@@index([status])
|
|
671
715
|
@@map("organizations")
|
|
672
716
|
}
|
|
673
717
|
|
|
674
|
-
/// OrganizationMember: Links users to organizations
|
|
675
|
-
///
|
|
718
|
+
/// OrganizationMember: Links users to organizations
|
|
719
|
+
/// User's own roles (via UserRole) determine their abilities within the org
|
|
676
720
|
model OrganizationMember {
|
|
677
|
-
id String
|
|
721
|
+
id String @id @default(cuid())
|
|
678
722
|
organizationId String
|
|
679
723
|
userId String
|
|
680
|
-
role OrganizationRole @default(OFFICER)
|
|
681
724
|
|
|
682
725
|
// Employee details
|
|
683
|
-
title String? // Job title (e.g., "Loan Officer", "
|
|
726
|
+
title String? // Job title (e.g., "Loan Officer", "Mortgage Operations Officer")
|
|
684
727
|
department String? // Department within organization
|
|
685
728
|
employeeId String? // Internal employee ID
|
|
686
729
|
|
|
687
730
|
// Status
|
|
688
731
|
isActive Boolean @default(true)
|
|
689
732
|
|
|
690
|
-
// Maker-Checker workflow permissions
|
|
691
|
-
canApprove Boolean @default(false) // Can this member approve transactions?
|
|
692
|
-
approvalLimit Decimal? // Maximum amount this member can approve (null = unlimited)
|
|
693
|
-
|
|
694
733
|
// Invitation/onboarding tracking
|
|
695
734
|
invitedAt DateTime?
|
|
696
735
|
acceptedAt DateTime?
|
|
697
736
|
invitedBy String? // User ID who invited this member
|
|
737
|
+
joinedAt DateTime @default(now())
|
|
698
738
|
|
|
699
739
|
createdAt DateTime @default(now())
|
|
700
740
|
updatedAt DateTime @updatedAt
|
|
@@ -705,7 +745,6 @@ model OrganizationMember {
|
|
|
705
745
|
@@unique([organizationId, userId]) // User can only be member once per org
|
|
706
746
|
@@index([userId])
|
|
707
747
|
@@index([organizationId])
|
|
708
|
-
@@index([role])
|
|
709
748
|
@@map("organization_members")
|
|
710
749
|
}
|
|
711
750
|
|
|
@@ -879,6 +918,7 @@ model Tenant {
|
|
|
879
918
|
|
|
880
919
|
// Application organization assignments
|
|
881
920
|
applicationOrganizations ApplicationOrganization[]
|
|
921
|
+
organizationTypes OrganizationType[]
|
|
882
922
|
|
|
883
923
|
@@index([subdomain])
|
|
884
924
|
@@map("tenants")
|
|
@@ -1112,11 +1152,10 @@ model Property {
|
|
|
1112
1152
|
streetAddress String?
|
|
1113
1153
|
longitude Float?
|
|
1114
1154
|
latitude Float?
|
|
1115
|
-
status
|
|
1155
|
+
status PropertyStatus @default(DRAFT)
|
|
1116
1156
|
description String? @db.Text
|
|
1117
1157
|
displayImageId String?
|
|
1118
1158
|
displayImage PropertyMedia? @relation("DisplayImage", fields: [displayImageId], references: [id], onDelete: SetNull)
|
|
1119
|
-
isPublished Boolean @default(false)
|
|
1120
1159
|
publishedAt DateTime?
|
|
1121
1160
|
createdAt DateTime @default(now())
|
|
1122
1161
|
updatedAt DateTime @updatedAt
|
|
@@ -1419,7 +1458,7 @@ model DocumentDefinition {
|
|
|
1419
1458
|
// APPROVAL STAGE - Sequential workflow stages for document review (template)
|
|
1420
1459
|
// =============================================================================
|
|
1421
1460
|
// Defines a stage in the approval workflow. Documents flow through stages
|
|
1422
|
-
// sequentially. Each stage
|
|
1461
|
+
// sequentially. Each stage requires a specific organization type to review.
|
|
1423
1462
|
// =============================================================================
|
|
1424
1463
|
|
|
1425
1464
|
model ApprovalStage {
|
|
@@ -1427,9 +1466,10 @@ model ApprovalStage {
|
|
|
1427
1466
|
planId String
|
|
1428
1467
|
plan DocumentationPlan @relation(fields: [planId], references: [id], onDelete: Cascade)
|
|
1429
1468
|
|
|
1430
|
-
name
|
|
1431
|
-
order
|
|
1432
|
-
|
|
1469
|
+
name String // "QShelter Review", "Bank Review"
|
|
1470
|
+
order Int // 1, 2, 3 - sequential order
|
|
1471
|
+
organizationTypeId String // Which type of org should review at this stage
|
|
1472
|
+
organizationType OrganizationType @relation(fields: [organizationTypeId], references: [id])
|
|
1433
1473
|
|
|
1434
1474
|
// Stage behavior flags
|
|
1435
1475
|
autoTransition Boolean @default(false) // Auto-complete when all docs approved? Default: require explicit approval
|
|
@@ -1440,9 +1480,6 @@ model ApprovalStage {
|
|
|
1440
1480
|
onRejection RejectionBehavior @default(CASCADE_BACK)
|
|
1441
1481
|
restartFromStageOrder Int? // If onRejection = RESTART_FROM_STAGE, which stage order to restart from
|
|
1442
1482
|
|
|
1443
|
-
// Optional: specific organization (e.g., which bank)
|
|
1444
|
-
organizationId String?
|
|
1445
|
-
|
|
1446
1483
|
// SLA (optional)
|
|
1447
1484
|
slaHours Int? // Escalate if not completed within X hours
|
|
1448
1485
|
|
|
@@ -1456,6 +1493,7 @@ model ApprovalStage {
|
|
|
1456
1493
|
|
|
1457
1494
|
@@unique([planId, order])
|
|
1458
1495
|
@@index([planId])
|
|
1496
|
+
@@index([organizationTypeId])
|
|
1459
1497
|
@@map("approval_stages")
|
|
1460
1498
|
}
|
|
1461
1499
|
|
|
@@ -2073,18 +2111,9 @@ model Application {
|
|
|
2073
2111
|
// in a specific application. This enables:
|
|
2074
2112
|
// 1. Validation that only assigned developers can upload sales offers
|
|
2075
2113
|
// 2. Only assigned banks can upload preapproval/mortgage offer letters
|
|
2076
|
-
// 3.
|
|
2114
|
+
// 3. Flexible type-based assignment (org assigned acting as specific type)
|
|
2077
2115
|
// =============================================================================
|
|
2078
2116
|
|
|
2079
|
-
/// Role that an organization plays in an application
|
|
2080
|
-
enum ApplicationOrganizationRole {
|
|
2081
|
-
DEVELOPER // Property developer - uploads sales offer letters
|
|
2082
|
-
LENDER // Bank/financial institution - provides mortgage
|
|
2083
|
-
LEGAL // Legal firm - handles conveyancing
|
|
2084
|
-
INSURER // Insurance company
|
|
2085
|
-
GOVERNMENT // Government agency (land registry, etc.)
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
2117
|
/// Status of organization's involvement in the application
|
|
2089
2118
|
enum ApplicationOrganizationStatus {
|
|
2090
2119
|
PENDING // Awaiting organization's response/engagement
|
|
@@ -2105,8 +2134,11 @@ model ApplicationOrganization {
|
|
|
2105
2134
|
organizationId String
|
|
2106
2135
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2107
2136
|
|
|
2108
|
-
//
|
|
2109
|
-
|
|
2137
|
+
// Which type the org is acting as on this application
|
|
2138
|
+
// (org must have this type in their OrganizationTypeAssignment)
|
|
2139
|
+
assignedAsTypeId String
|
|
2140
|
+
assignedAsType OrganizationType @relation(fields: [assignedAsTypeId], references: [id])
|
|
2141
|
+
|
|
2110
2142
|
status ApplicationOrganizationStatus @default(PENDING)
|
|
2111
2143
|
|
|
2112
2144
|
// Who assigned this organization (admin or system)
|
|
@@ -2153,11 +2185,11 @@ model ApplicationOrganization {
|
|
|
2153
2185
|
createdAt DateTime @default(now())
|
|
2154
2186
|
updatedAt DateTime @updatedAt
|
|
2155
2187
|
|
|
2156
|
-
@@unique([applicationId,
|
|
2188
|
+
@@unique([applicationId, assignedAsTypeId]) // One org per type per application
|
|
2157
2189
|
@@index([tenantId])
|
|
2158
2190
|
@@index([applicationId])
|
|
2159
2191
|
@@index([organizationId])
|
|
2160
|
-
@@index([
|
|
2192
|
+
@@index([assignedAsTypeId])
|
|
2161
2193
|
@@index([status])
|
|
2162
2194
|
@@index([isPrimary])
|
|
2163
2195
|
@@index([slaBreachedAt])
|
|
@@ -2723,8 +2755,9 @@ model ApplicationDocument {
|
|
|
2723
2755
|
// =============================================================================
|
|
2724
2756
|
// DOCUMENT REVIEW - Multi-party review tracking
|
|
2725
2757
|
// =============================================================================
|
|
2726
|
-
// Tracks reviews by different organizations for the same document
|
|
2727
|
-
//
|
|
2758
|
+
// Tracks reviews by different organizations for the same document.
|
|
2759
|
+
// organizationId is NULL for customer self-attestations/signatures.
|
|
2760
|
+
// For org reviews, organizationTypeId captures which type the org was acting as.
|
|
2728
2761
|
// =============================================================================
|
|
2729
2762
|
|
|
2730
2763
|
model DocumentReview {
|
|
@@ -2734,12 +2767,14 @@ model DocumentReview {
|
|
|
2734
2767
|
documentId String
|
|
2735
2768
|
document ApplicationDocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
2736
2769
|
|
|
2737
|
-
// Who is reviewing
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2770
|
+
// Who is reviewing - NULL organizationId means customer self-review
|
|
2771
|
+
organizationId String? // Organization performing the review (null = customer)
|
|
2772
|
+
organization Organization? @relation(fields: [organizationId], references: [id])
|
|
2773
|
+
organizationTypeId String? // Which type the org was acting as (audit snapshot)
|
|
2774
|
+
organizationType OrganizationType? @relation(fields: [organizationTypeId], references: [id])
|
|
2775
|
+
reviewerId String? // User who performed the review
|
|
2776
|
+
reviewer User? @relation("DocumentReviewer", fields: [reviewerId], references: [id])
|
|
2777
|
+
reviewerName String? // Denormalized for audit trail
|
|
2743
2778
|
|
|
2744
2779
|
// Review state
|
|
2745
2780
|
decision ReviewDecision @default(PENDING)
|
|
@@ -2765,10 +2800,12 @@ model DocumentReview {
|
|
|
2765
2800
|
createdAt DateTime @default(now())
|
|
2766
2801
|
updatedAt DateTime @updatedAt
|
|
2767
2802
|
|
|
2768
|
-
|
|
2803
|
+
// Unique: one review per org per doc (null org = customer review)
|
|
2804
|
+
@@unique([documentId, organizationId])
|
|
2769
2805
|
@@index([tenantId])
|
|
2770
2806
|
@@index([documentId])
|
|
2771
|
-
@@index([
|
|
2807
|
+
@@index([organizationId])
|
|
2808
|
+
@@index([organizationTypeId])
|
|
2772
2809
|
@@index([decision])
|
|
2773
2810
|
@@index([reviewerId])
|
|
2774
2811
|
@@index([parentReviewId])
|
|
@@ -2794,9 +2831,10 @@ model ApprovalStageProgress {
|
|
|
2794
2831
|
approvalStage ApprovalStage @relation(fields: [approvalStageId], references: [id])
|
|
2795
2832
|
|
|
2796
2833
|
// Stage info (denormalized for convenience)
|
|
2797
|
-
name
|
|
2798
|
-
order
|
|
2799
|
-
|
|
2834
|
+
name String
|
|
2835
|
+
order Int
|
|
2836
|
+
organizationTypeId String // Which type of org should review at this stage
|
|
2837
|
+
organizationType OrganizationType @relation(fields: [organizationTypeId], references: [id])
|
|
2800
2838
|
|
|
2801
2839
|
// Behavior flags (copied from template)
|
|
2802
2840
|
autoTransition Boolean @default(false)
|
|
@@ -2850,9 +2888,10 @@ model DocumentApproval {
|
|
|
2850
2888
|
stageProgress ApprovalStageProgress @relation(fields: [stageProgressId], references: [id], onDelete: Cascade)
|
|
2851
2889
|
|
|
2852
2890
|
// Reviewer info
|
|
2853
|
-
reviewerId
|
|
2854
|
-
reviewer
|
|
2855
|
-
|
|
2891
|
+
reviewerId String
|
|
2892
|
+
reviewer User @relation("DocumentApprovalReviewer", fields: [reviewerId], references: [id])
|
|
2893
|
+
organizationTypeId String // Which type the reviewer's org was acting as
|
|
2894
|
+
organizationType OrganizationType @relation(fields: [organizationTypeId], references: [id])
|
|
2856
2895
|
|
|
2857
2896
|
// Decision
|
|
2858
2897
|
decision ReviewDecision // APPROVED, REJECTED, CHANGES_REQUESTED
|
|
@@ -2865,6 +2904,7 @@ model DocumentApproval {
|
|
|
2865
2904
|
@@index([documentId])
|
|
2866
2905
|
@@index([stageProgressId])
|
|
2867
2906
|
@@index([reviewerId])
|
|
2907
|
+
@@index([organizationTypeId])
|
|
2868
2908
|
@@index([decision])
|
|
2869
2909
|
@@map("document_approvals")
|
|
2870
2910
|
}
|