@valentine-efagene/qshelter-common 2.0.19 → 2.0.22
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 +45 -30
- package/dist/generated/client/client.d.ts +45 -30
- package/dist/generated/client/commonInputTypes.d.ts +40 -0
- package/dist/generated/client/internal/class.d.ts +93 -60
- package/dist/generated/client/internal/class.js +2 -2
- package/dist/generated/client/internal/prismaNamespace.d.ts +1050 -720
- package/dist/generated/client/internal/prismaNamespace.js +313 -190
- package/dist/generated/client/internal/prismaNamespaceBrowser.d.ts +344 -215
- package/dist/generated/client/internal/prismaNamespaceBrowser.js +313 -190
- package/dist/generated/client/models/Amenity.d.ts +168 -1
- package/dist/generated/client/models/Contract.d.ts +2037 -298
- package/dist/generated/client/models/ContractDocument.d.ts +299 -12
- package/dist/generated/client/models/ContractEvent.d.ts +1052 -0
- package/dist/generated/client/models/ContractEvent.js +1 -0
- package/dist/generated/client/models/ContractInstallment.d.ts +1656 -0
- package/dist/generated/client/models/ContractInstallment.js +1 -0
- package/dist/generated/client/models/ContractPayment.d.ts +2026 -0
- package/dist/generated/client/models/ContractPayment.js +1 -0
- package/dist/generated/client/models/ContractPhase.d.ts +2467 -0
- package/dist/generated/client/models/ContractPhase.js +1 -0
- package/dist/generated/client/models/ContractPhaseStep.d.ts +1678 -0
- package/dist/generated/client/models/ContractPhaseStep.js +1 -0
- package/dist/generated/client/models/ContractPhaseStepApproval.d.ts +1249 -0
- package/dist/generated/client/models/ContractPhaseStepApproval.js +1 -0
- package/dist/generated/client/models/ContractTransition.d.ts +1118 -0
- package/dist/generated/client/models/ContractTransition.js +1 -0
- package/dist/generated/client/models/DomainEvent.d.ts +1240 -0
- package/dist/generated/client/models/DomainEvent.js +1 -0
- package/dist/generated/client/models/PaymentPlan.d.ts +325 -1062
- package/dist/generated/client/models/Property.d.ts +154 -684
- package/dist/generated/client/models/PropertyPaymentMethod.d.ts +1498 -0
- package/dist/generated/client/models/PropertyPaymentMethod.js +1 -0
- package/dist/generated/client/models/PropertyPaymentMethodLink.d.ts +1158 -0
- package/dist/generated/client/models/PropertyPaymentMethodLink.js +1 -0
- package/dist/generated/client/models/PropertyPaymentMethodPhase.d.ts +1656 -0
- package/dist/generated/client/models/PropertyPaymentMethodPhase.js +1 -0
- package/dist/generated/client/models/PropertyUnit.d.ts +1598 -0
- package/dist/generated/client/models/PropertyUnit.js +1 -0
- package/dist/generated/client/models/PropertyVariant.d.ts +2079 -0
- package/dist/generated/client/models/PropertyVariant.js +1 -0
- package/dist/generated/client/models/PropertyVariantAmenity.d.ts +1080 -0
- package/dist/generated/client/models/PropertyVariantAmenity.js +1 -0
- package/dist/generated/client/models/PropertyVariantMedia.d.ts +1189 -0
- package/dist/generated/client/models/PropertyVariantMedia.js +1 -0
- package/dist/generated/client/models/User.d.ts +684 -427
- package/dist/generated/client/models/index.d.ts +15 -12
- package/dist/generated/client/models/index.js +15 -12
- package/dist/generated/client/models.d.ts +15 -12
- package/dist/src/config/config.service.d.ts +0 -1
- package/dist/src/config/config.service.js +0 -1
- package/package.json +2 -1
- package/prisma/schema.prisma +544 -269
package/prisma/schema.prisma
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
// =============================================================================
|
|
7
7
|
|
|
8
8
|
generator client {
|
|
9
|
-
provider
|
|
10
|
-
output
|
|
9
|
+
provider = "prisma-client"
|
|
10
|
+
output = "../generated/client"
|
|
11
|
+
engineType = "client"
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
datasource db {
|
|
@@ -48,12 +49,15 @@ model User {
|
|
|
48
49
|
socials Social[]
|
|
49
50
|
|
|
50
51
|
// Relations to other domains
|
|
51
|
-
properties
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
properties Property[]
|
|
53
|
+
contracts Contract[] @relation("ContractBuyer")
|
|
54
|
+
soldContracts Contract[] @relation("ContractSeller")
|
|
55
|
+
contractPayments ContractPayment[] @relation("ContractPayer")
|
|
56
|
+
|
|
57
|
+
// Phase step assignments and approvals
|
|
58
|
+
assignedSteps ContractPhaseStep[] @relation("PhaseStepAssignee")
|
|
59
|
+
stepApprovals ContractPhaseStepApproval[] @relation("PhaseStepApprover")
|
|
60
|
+
uploadedDocs ContractDocument[] @relation("DocumentUploader")
|
|
57
61
|
|
|
58
62
|
@@index([email])
|
|
59
63
|
@@index([tenantId])
|
|
@@ -261,6 +265,10 @@ model Settings {
|
|
|
261
265
|
// =============================================================================
|
|
262
266
|
// PROPERTY DOMAIN
|
|
263
267
|
// =============================================================================
|
|
268
|
+
// Property = listing/project (e.g., "Sunrise Estate")
|
|
269
|
+
// PropertyVariant = configuration with specs & price (e.g., "3-Bed Corner - Finished")
|
|
270
|
+
// PropertyUnit = individual sellable unit (e.g., "Unit A1")
|
|
271
|
+
// =============================================================================
|
|
264
272
|
|
|
265
273
|
model Property {
|
|
266
274
|
id String @id @default(cuid())
|
|
@@ -268,21 +276,16 @@ model Property {
|
|
|
268
276
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
269
277
|
title String
|
|
270
278
|
category String // SALE, RENT, LEASE
|
|
271
|
-
propertyType String // APARTMENT, HOUSE, LAND, COMMERCIAL
|
|
279
|
+
propertyType String // APARTMENT, HOUSE, LAND, COMMERCIAL, ESTATE, TOWNHOUSE
|
|
272
280
|
country String
|
|
273
281
|
currency String // USD, NGN, etc
|
|
274
282
|
city String
|
|
275
283
|
district String?
|
|
276
284
|
zipCode String?
|
|
277
285
|
streetAddress String?
|
|
278
|
-
nBedrooms String
|
|
279
|
-
nBathrooms String
|
|
280
|
-
nParkingSpots String
|
|
281
|
-
price Float
|
|
282
286
|
longitude Float?
|
|
283
287
|
latitude Float?
|
|
284
|
-
|
|
285
|
-
status String @default("DRAFT") // DRAFT, PUBLISHED, SOLD, RENTED
|
|
288
|
+
status String @default("DRAFT") // DRAFT, PUBLISHED, SOLD_OUT, ARCHIVED
|
|
286
289
|
description String? @db.Text
|
|
287
290
|
displayImageId String?
|
|
288
291
|
displayImage PropertyMedia? @relation("DisplayImage", fields: [displayImageId], references: [id], onDelete: SetNull)
|
|
@@ -291,17 +294,18 @@ model Property {
|
|
|
291
294
|
createdAt DateTime @default(now())
|
|
292
295
|
updatedAt DateTime @updatedAt
|
|
293
296
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
// Relations
|
|
298
|
+
documents PropertyDocument[]
|
|
299
|
+
media PropertyMedia[] @relation("PropertyMedia")
|
|
300
|
+
amenities PropertyAmenity[] // Shared amenities (gym, pool, security)
|
|
301
|
+
paymentMethods PropertyPaymentMethodLink[]
|
|
302
|
+
variants PropertyVariant[]
|
|
300
303
|
|
|
301
304
|
@@index([userId])
|
|
302
305
|
@@index([category])
|
|
303
306
|
@@index([propertyType])
|
|
304
307
|
@@index([city])
|
|
308
|
+
@@index([status])
|
|
305
309
|
@@map("properties")
|
|
306
310
|
}
|
|
307
311
|
|
|
@@ -337,15 +341,134 @@ model PropertyDocument {
|
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
model Amenity {
|
|
340
|
-
id String
|
|
341
|
-
name String
|
|
342
|
-
|
|
343
|
-
|
|
344
|
+
id String @id @default(cuid())
|
|
345
|
+
name String @unique
|
|
346
|
+
category String? // PROPERTY, VARIANT, BOTH - helps filter which amenities to show
|
|
347
|
+
icon String? // Icon name/URL for UI
|
|
348
|
+
createdAt DateTime @default(now())
|
|
349
|
+
updatedAt DateTime @updatedAt
|
|
344
350
|
properties PropertyAmenity[]
|
|
351
|
+
variants PropertyVariantAmenity[]
|
|
345
352
|
|
|
353
|
+
@@index([category])
|
|
346
354
|
@@map("amenities")
|
|
347
355
|
}
|
|
348
356
|
|
|
357
|
+
// =============================================================================
|
|
358
|
+
// PROPERTY VARIANT & UNIT MODELS
|
|
359
|
+
// =============================================================================
|
|
360
|
+
|
|
361
|
+
// PropertyVariant = specific configuration with its own price and amenities
|
|
362
|
+
// e.g., "3-Bedroom Corner Piece - Fully Finished", "2-Bedroom Standard - Carcass"
|
|
363
|
+
model PropertyVariant {
|
|
364
|
+
id String @id @default(cuid())
|
|
365
|
+
propertyId String
|
|
366
|
+
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
|
|
367
|
+
|
|
368
|
+
name String // "Corner Piece - Finished", "Standard - Carcass"
|
|
369
|
+
description String? @db.Text
|
|
370
|
+
|
|
371
|
+
// Specifications
|
|
372
|
+
nBedrooms Int?
|
|
373
|
+
nBathrooms Int?
|
|
374
|
+
nParkingSpots Int?
|
|
375
|
+
area Float? // Square meters/feet
|
|
376
|
+
|
|
377
|
+
// Pricing
|
|
378
|
+
price Float
|
|
379
|
+
pricePerSqm Float? // Computed or set manually
|
|
380
|
+
|
|
381
|
+
// Inventory counters (denormalized for performance, updated via triggers/service)
|
|
382
|
+
totalUnits Int @default(1)
|
|
383
|
+
availableUnits Int @default(1)
|
|
384
|
+
reservedUnits Int @default(0)
|
|
385
|
+
soldUnits Int @default(0)
|
|
386
|
+
|
|
387
|
+
// Status
|
|
388
|
+
status String @default("AVAILABLE") // AVAILABLE, LOW_STOCK, SOLD_OUT, ARCHIVED
|
|
389
|
+
isActive Boolean @default(true)
|
|
390
|
+
createdAt DateTime @default(now())
|
|
391
|
+
updatedAt DateTime @updatedAt
|
|
392
|
+
|
|
393
|
+
// Relations
|
|
394
|
+
amenities PropertyVariantAmenity[]
|
|
395
|
+
units PropertyUnit[]
|
|
396
|
+
media PropertyVariantMedia[]
|
|
397
|
+
|
|
398
|
+
@@index([propertyId])
|
|
399
|
+
@@index([status])
|
|
400
|
+
@@index([price])
|
|
401
|
+
@@map("property_variants")
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// PropertyVariantAmenity = amenities specific to a variant
|
|
405
|
+
// e.g., "Finished Kitchen", "Smart Home System", "Private Garden"
|
|
406
|
+
model PropertyVariantAmenity {
|
|
407
|
+
variantId String
|
|
408
|
+
amenityId String
|
|
409
|
+
variant PropertyVariant @relation(fields: [variantId], references: [id], onDelete: Cascade)
|
|
410
|
+
amenity Amenity @relation(fields: [amenityId], references: [id], onDelete: Cascade)
|
|
411
|
+
createdAt DateTime @default(now())
|
|
412
|
+
|
|
413
|
+
@@id([variantId, amenityId])
|
|
414
|
+
@@map("property_variant_amenities")
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// PropertyVariantMedia = images/videos specific to a variant
|
|
418
|
+
model PropertyVariantMedia {
|
|
419
|
+
id String @id @default(cuid())
|
|
420
|
+
variantId String
|
|
421
|
+
variant PropertyVariant @relation(fields: [variantId], references: [id], onDelete: Cascade)
|
|
422
|
+
url String
|
|
423
|
+
type String // IMAGE, VIDEO, FLOOR_PLAN, 3D_TOUR
|
|
424
|
+
caption String?
|
|
425
|
+
order Int @default(0)
|
|
426
|
+
createdAt DateTime @default(now())
|
|
427
|
+
updatedAt DateTime @updatedAt
|
|
428
|
+
|
|
429
|
+
@@index([variantId])
|
|
430
|
+
@@map("property_variant_media")
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// PropertyUnit = individual sellable/rentable unit within a variant
|
|
434
|
+
// e.g., "Unit A1", "Block B - Flat 3", "Plot 15"
|
|
435
|
+
model PropertyUnit {
|
|
436
|
+
id String @id @default(cuid())
|
|
437
|
+
variantId String
|
|
438
|
+
variant PropertyVariant @relation(fields: [variantId], references: [id], onDelete: Cascade)
|
|
439
|
+
|
|
440
|
+
unitNumber String // "A1", "B-3", "Plot 15"
|
|
441
|
+
floorNumber Int? // For apartments
|
|
442
|
+
blockName String? // "Block A", "Tower 1"
|
|
443
|
+
|
|
444
|
+
// Unit-specific overrides (if different from variant)
|
|
445
|
+
priceOverride Float? // If this specific unit has a different price
|
|
446
|
+
areaOverride Float? // If this specific unit has a different area
|
|
447
|
+
notes String? @db.Text // Internal notes about this unit
|
|
448
|
+
|
|
449
|
+
// Status tracking
|
|
450
|
+
status String @default("AVAILABLE") // AVAILABLE, RESERVED, SOLD, RENTED, UNAVAILABLE
|
|
451
|
+
|
|
452
|
+
// Reservation/hold
|
|
453
|
+
reservedAt DateTime?
|
|
454
|
+
reservedUntil DateTime?
|
|
455
|
+
reservedById String?
|
|
456
|
+
|
|
457
|
+
// Ownership tracking (once sold)
|
|
458
|
+
ownerId String?
|
|
459
|
+
|
|
460
|
+
createdAt DateTime @default(now())
|
|
461
|
+
updatedAt DateTime @updatedAt
|
|
462
|
+
|
|
463
|
+
// Relations
|
|
464
|
+
contracts Contract[]
|
|
465
|
+
|
|
466
|
+
@@unique([variantId, unitNumber])
|
|
467
|
+
@@index([variantId])
|
|
468
|
+
@@index([status])
|
|
469
|
+
@@map("property_units")
|
|
470
|
+
}
|
|
471
|
+
|
|
349
472
|
model PropertyAmenity {
|
|
350
473
|
propertyId String
|
|
351
474
|
amenityId String
|
|
@@ -358,305 +481,457 @@ model PropertyAmenity {
|
|
|
358
481
|
}
|
|
359
482
|
|
|
360
483
|
// =============================================================================
|
|
361
|
-
//
|
|
484
|
+
// PAYMENT PLAN DOMAIN - Reusable installment structure templates
|
|
362
485
|
// =============================================================================
|
|
363
486
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
interestRate Float
|
|
379
|
-
monthlyPayment Float
|
|
380
|
-
status String @default("DRAFT") // DRAFT, PENDING, ACTIVE, COMPLETED, CANCELLED
|
|
381
|
-
state String @default("DRAFT") // FSM state
|
|
382
|
-
stateMetadata String? @db.Text // JSON metadata
|
|
383
|
-
lastReminderSentAt DateTime?
|
|
384
|
-
createdAt DateTime @default(now())
|
|
385
|
-
updatedAt DateTime @updatedAt
|
|
487
|
+
// PaymentPlan = reusable structure for how payments are scheduled
|
|
488
|
+
// Examples: "Monthly360" (360 monthly payments), "Weekly52", "OneTime"
|
|
489
|
+
model PaymentPlan {
|
|
490
|
+
id String @id @default(cuid())
|
|
491
|
+
name String @unique
|
|
492
|
+
description String? @db.Text
|
|
493
|
+
isActive Boolean @default(true)
|
|
494
|
+
|
|
495
|
+
// Structure configuration
|
|
496
|
+
paymentFrequency String // MONTHLY, BIWEEKLY, WEEKLY, ONE_TIME, CUSTOM
|
|
497
|
+
customFrequencyDays Int?
|
|
498
|
+
numberOfInstallments Int // 1 for one-time, 360 for 30yr monthly, etc
|
|
499
|
+
calculateInterestDaily Boolean @default(false)
|
|
500
|
+
gracePeriodDays Int @default(0)
|
|
386
501
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
transitions MortgageTransition[]
|
|
390
|
-
transitionEvents MortgageTransitionEvent[]
|
|
502
|
+
createdAt DateTime @default(now())
|
|
503
|
+
updatedAt DateTime @updatedAt
|
|
391
504
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
505
|
+
// Used by property payment method phases (templates)
|
|
506
|
+
methodPhases PropertyPaymentMethodPhase[]
|
|
507
|
+
// Used by instantiated contract phases
|
|
508
|
+
contractPhases ContractPhase[]
|
|
509
|
+
|
|
510
|
+
@@map("payment_plans")
|
|
397
511
|
}
|
|
398
512
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
description String? @db.Text
|
|
403
|
-
createdAt DateTime @default(now())
|
|
404
|
-
updatedAt DateTime @updatedAt
|
|
405
|
-
mortgages Mortgage[]
|
|
513
|
+
// =============================================================================
|
|
514
|
+
// PROPERTY PAYMENT METHOD DOMAIN - Product offerings per property
|
|
515
|
+
// =============================================================================
|
|
406
516
|
|
|
407
|
-
|
|
408
|
-
|
|
517
|
+
// PropertyPaymentMethod = how a property can be purchased (e.g., "Standard Mortgage", "Cash", "Rent-to-Own")
|
|
518
|
+
model PropertyPaymentMethod {
|
|
519
|
+
id String @id @default(cuid())
|
|
520
|
+
name String // "Standard Mortgage", "Flexible Payment", "Cash Purchase"
|
|
521
|
+
description String? @db.Text
|
|
522
|
+
isActive Boolean @default(true)
|
|
409
523
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
url String
|
|
416
|
-
type String // INCOME_PROOF, ID, etc
|
|
417
|
-
createdAt DateTime @default(now())
|
|
418
|
-
updatedAt DateTime @updatedAt
|
|
524
|
+
// Global method configuration
|
|
525
|
+
allowEarlyPayoff Boolean @default(true)
|
|
526
|
+
earlyPayoffPenaltyRate Float?
|
|
527
|
+
autoActivatePhases Boolean @default(true)
|
|
528
|
+
requiresManualApproval Boolean @default(false)
|
|
419
529
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
530
|
+
createdAt DateTime @default(now())
|
|
531
|
+
updatedAt DateTime @updatedAt
|
|
423
532
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
order Int
|
|
431
|
-
isCompleted Boolean @default(false)
|
|
432
|
-
completedAt DateTime?
|
|
433
|
-
createdAt DateTime @default(now())
|
|
434
|
-
updatedAt DateTime @updatedAt
|
|
533
|
+
// Many-to-many with properties
|
|
534
|
+
properties PropertyPaymentMethodLink[]
|
|
535
|
+
// Phases that make up this method (templates)
|
|
536
|
+
phases PropertyPaymentMethodPhase[]
|
|
537
|
+
// Contracts using this method
|
|
538
|
+
contracts Contract[]
|
|
435
539
|
|
|
436
|
-
@@
|
|
437
|
-
@@map("mortgage_steps")
|
|
540
|
+
@@map("property_payment_methods")
|
|
438
541
|
}
|
|
439
542
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
endDate DateTime
|
|
447
|
-
createdAt DateTime @default(now())
|
|
448
|
-
updatedAt DateTime @updatedAt
|
|
543
|
+
// Many-to-many link between Property and PaymentMethod
|
|
544
|
+
model PropertyPaymentMethodLink {
|
|
545
|
+
propertyId String
|
|
546
|
+
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
|
|
547
|
+
paymentMethodId String
|
|
548
|
+
paymentMethod PropertyPaymentMethod @relation(fields: [paymentMethodId], references: [id], onDelete: Cascade)
|
|
449
549
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
550
|
+
// Method-specific overrides for this property
|
|
551
|
+
isDefault Boolean @default(false)
|
|
552
|
+
isActive Boolean @default(true)
|
|
553
|
+
createdAt DateTime @default(now())
|
|
453
554
|
|
|
454
|
-
@@
|
|
555
|
+
@@id([propertyId, paymentMethodId])
|
|
556
|
+
@@map("property_payment_method_links")
|
|
455
557
|
}
|
|
456
558
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
createdAt DateTime @default(now())
|
|
466
|
-
updatedAt DateTime @updatedAt
|
|
559
|
+
// Phase template within a PropertyPaymentMethod (e.g., documentation, downpayment, mortgage)
|
|
560
|
+
// phaseCategory determines the FSM type: DOCUMENTATION or PAYMENT
|
|
561
|
+
model PropertyPaymentMethodPhase {
|
|
562
|
+
id String @id @default(cuid())
|
|
563
|
+
paymentMethodId String
|
|
564
|
+
paymentMethod PropertyPaymentMethod @relation(fields: [paymentMethodId], references: [id], onDelete: Cascade)
|
|
565
|
+
paymentPlanId String? // Only for PAYMENT phases
|
|
566
|
+
paymentPlan PaymentPlan? @relation(fields: [paymentPlanId], references: [id])
|
|
467
567
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
}
|
|
568
|
+
name String
|
|
569
|
+
description String? @db.Text
|
|
471
570
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
amount Float
|
|
477
|
-
paymentMethod String
|
|
478
|
-
reference String?
|
|
479
|
-
status String @default("PENDING")
|
|
480
|
-
createdAt DateTime @default(now())
|
|
481
|
-
updatedAt DateTime @updatedAt
|
|
571
|
+
// Phase classification
|
|
572
|
+
phaseCategory String // DOCUMENTATION, PAYMENT
|
|
573
|
+
phaseType String // Admin-defined: KYC, VERIFICATION, DOWNPAYMENT, MORTGAGE, BALLOON, CUSTOM, etc.
|
|
574
|
+
order Int
|
|
482
575
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
576
|
+
// Financial configuration (for PAYMENT phases)
|
|
577
|
+
interestRate Float?
|
|
578
|
+
percentOfPrice Float? // e.g., 10.0 for 10% downpayment
|
|
486
579
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
mortgage Mortgage @relation(fields: [mortgageId], references: [id], onDelete: Cascade)
|
|
491
|
-
fromState String
|
|
492
|
-
toState String
|
|
493
|
-
trigger String
|
|
494
|
-
metadata String? @db.Text // JSON
|
|
495
|
-
transitionedAt DateTime @default(now())
|
|
580
|
+
// Activation rules
|
|
581
|
+
requiresPreviousPhaseCompletion Boolean @default(true)
|
|
582
|
+
minimumCompletionPercentage Float?
|
|
496
583
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}
|
|
584
|
+
// For DOCUMENTATION phases: define required steps
|
|
585
|
+
requiredDocumentTypes String? // CSV: ID,BANK_STATEMENT,INCOME_PROOF
|
|
586
|
+
stepDefinitions String? @db.Text // JSON: [{name, stepType, order}]
|
|
500
587
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
mortgageId String
|
|
504
|
-
mortgage Mortgage @relation(fields: [mortgageId], references: [id], onDelete: Cascade)
|
|
505
|
-
event String
|
|
506
|
-
data String? @db.Text // JSON
|
|
507
|
-
createdAt DateTime @default(now())
|
|
588
|
+
createdAt DateTime @default(now())
|
|
589
|
+
updatedAt DateTime @updatedAt
|
|
508
590
|
|
|
509
|
-
@@index([
|
|
510
|
-
@@
|
|
591
|
+
@@index([paymentMethodId])
|
|
592
|
+
@@index([paymentPlanId])
|
|
593
|
+
@@index([phaseCategory])
|
|
594
|
+
@@map("property_payment_method_phases")
|
|
511
595
|
}
|
|
512
596
|
|
|
513
597
|
// =============================================================================
|
|
514
|
-
//
|
|
598
|
+
// CONTRACT DOMAIN - Unified agreement model (replaces Mortgage, PurchasePlan, etc.)
|
|
599
|
+
// =============================================================================
|
|
600
|
+
// Contract is the canonical agreement. "Mortgage" is just a product configuration
|
|
601
|
+
// that creates a Contract with specific phases (documentation, downpayment, long-term payment).
|
|
602
|
+
// Phases can be DOCUMENTATION (FSM for approvals) or PAYMENT (PaymentPlan-driven installments).
|
|
515
603
|
// =============================================================================
|
|
516
604
|
|
|
517
|
-
model
|
|
518
|
-
id
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
605
|
+
model Contract {
|
|
606
|
+
id String @id @default(cuid())
|
|
607
|
+
// Link to specific unit being purchased/rented
|
|
608
|
+
propertyUnitId String
|
|
609
|
+
propertyUnit PropertyUnit @relation(fields: [propertyUnitId], references: [id], onDelete: Cascade)
|
|
610
|
+
buyerId String
|
|
611
|
+
buyer User @relation("ContractBuyer", fields: [buyerId], references: [id], onDelete: Cascade)
|
|
612
|
+
sellerId String?
|
|
613
|
+
seller User? @relation("ContractSeller", fields: [sellerId], references: [id])
|
|
614
|
+
paymentMethodId String? // PropertyPaymentMethod used to create this contract
|
|
615
|
+
paymentMethod PropertyPaymentMethod? @relation(fields: [paymentMethodId], references: [id])
|
|
616
|
+
|
|
617
|
+
// Contract identification
|
|
618
|
+
contractNumber String @unique
|
|
619
|
+
title String
|
|
620
|
+
description String? @db.Text
|
|
621
|
+
contractType String // Admin-defined: MORTGAGE, INSTALLMENT, RENT_TO_OWN, CASH, LEASE, etc.
|
|
622
|
+
|
|
623
|
+
// Financial summary (computed from phases)
|
|
624
|
+
totalAmount Float // Total contract value (from unit price or negotiated)
|
|
625
|
+
downPayment Float @default(0)
|
|
626
|
+
downPaymentPaid Float @default(0)
|
|
627
|
+
principal Float? // Financed amount (if applicable)
|
|
628
|
+
interestRate Float? // Overall interest rate (if applicable)
|
|
629
|
+
termMonths Int? // Total term (if applicable)
|
|
630
|
+
periodicPayment Float? // Computed periodic payment (if applicable)
|
|
631
|
+
totalPaidToDate Float @default(0)
|
|
632
|
+
totalInterestPaid Float @default(0)
|
|
633
|
+
|
|
634
|
+
// FSM state
|
|
635
|
+
status String @default("DRAFT") // DRAFT, PENDING, ACTIVE, COMPLETED, CANCELLED, TERMINATED
|
|
636
|
+
state String @default("DRAFT") // FSM state for workflow
|
|
637
|
+
currentPhaseId String?
|
|
638
|
+
|
|
639
|
+
// Timing
|
|
640
|
+
nextPaymentDueDate DateTime?
|
|
641
|
+
lastReminderSentAt DateTime?
|
|
642
|
+
startDate DateTime?
|
|
643
|
+
endDate DateTime?
|
|
644
|
+
signedAt DateTime?
|
|
645
|
+
terminatedAt DateTime?
|
|
646
|
+
createdAt DateTime @default(now())
|
|
647
|
+
updatedAt DateTime @updatedAt
|
|
648
|
+
|
|
649
|
+
// Relations
|
|
650
|
+
phases ContractPhase[]
|
|
651
|
+
documents ContractDocument[]
|
|
652
|
+
payments ContractPayment[]
|
|
653
|
+
transitions ContractTransition[]
|
|
654
|
+
events ContractEvent[]
|
|
655
|
+
|
|
656
|
+
@@index([propertyUnitId])
|
|
542
657
|
@@index([buyerId])
|
|
658
|
+
@@index([sellerId])
|
|
659
|
+
@@index([paymentMethodId])
|
|
660
|
+
@@index([status])
|
|
543
661
|
@@index([state])
|
|
544
|
-
@@map("
|
|
662
|
+
@@map("contracts")
|
|
545
663
|
}
|
|
546
664
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
665
|
+
// Phase within a contract - can be DOCUMENTATION or PAYMENT type
|
|
666
|
+
// Admin names phases freely (e.g., "KYC Documents", "Downpayment", "Monthly Mortgage")
|
|
667
|
+
model ContractPhase {
|
|
668
|
+
id String @id @default(cuid())
|
|
669
|
+
contractId String
|
|
670
|
+
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
|
671
|
+
paymentPlanId String? // Only for PAYMENT phases
|
|
672
|
+
paymentPlan PaymentPlan? @relation(fields: [paymentPlanId], references: [id])
|
|
673
|
+
|
|
674
|
+
// Admin-defined naming
|
|
675
|
+
name String
|
|
676
|
+
description String? @db.Text
|
|
677
|
+
|
|
678
|
+
// Phase classification
|
|
679
|
+
phaseCategory String // DOCUMENTATION, PAYMENT
|
|
680
|
+
phaseType String // Admin-defined: DOWNPAYMENT, MORTGAGE, KYC, VERIFICATION, BALLOON, CUSTOM, etc.
|
|
681
|
+
order Int
|
|
682
|
+
|
|
683
|
+
// FSM state for this phase
|
|
684
|
+
status String @default("PENDING") // PENDING, IN_PROGRESS, AWAITING_APPROVAL, ACTIVE, COMPLETED, SKIPPED, FAILED
|
|
685
|
+
|
|
686
|
+
// Financial details (for PAYMENT phases)
|
|
687
|
+
totalAmount Float?
|
|
688
|
+
paidAmount Float @default(0)
|
|
689
|
+
remainingAmount Float?
|
|
690
|
+
interestRate Float?
|
|
691
|
+
|
|
692
|
+
// Timing
|
|
693
|
+
dueDate DateTime?
|
|
694
|
+
startDate DateTime?
|
|
695
|
+
endDate DateTime?
|
|
696
|
+
activatedAt DateTime?
|
|
697
|
+
completedAt DateTime?
|
|
698
|
+
|
|
699
|
+
// Activation rules
|
|
700
|
+
requiresPreviousPhaseCompletion Boolean @default(true)
|
|
701
|
+
minimumCompletionPercentage Float?
|
|
702
|
+
|
|
703
|
+
createdAt DateTime @default(now())
|
|
704
|
+
updatedAt DateTime @updatedAt
|
|
705
|
+
|
|
706
|
+
// Relations
|
|
707
|
+
installments ContractInstallment[]
|
|
708
|
+
payments ContractPayment[]
|
|
709
|
+
steps ContractPhaseStep[] // For DOCUMENTATION phases (FSM steps)
|
|
710
|
+
|
|
711
|
+
@@index([contractId])
|
|
712
|
+
@@index([paymentPlanId])
|
|
713
|
+
@@index([phaseCategory])
|
|
714
|
+
@@index([status])
|
|
715
|
+
@@index([order])
|
|
716
|
+
@@map("contract_phases")
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// Steps within a DOCUMENTATION phase (FSM for document collection/approval)
|
|
720
|
+
model ContractPhaseStep {
|
|
721
|
+
id String @id @default(cuid())
|
|
722
|
+
phaseId String
|
|
723
|
+
phase ContractPhase @relation(fields: [phaseId], references: [id], onDelete: Cascade)
|
|
724
|
+
|
|
725
|
+
name String
|
|
726
|
+
description String? @db.Text
|
|
727
|
+
stepType String // UPLOAD, REVIEW, SIGNATURE, APPROVAL, EXTERNAL_CHECK, WAIT
|
|
728
|
+
order Int
|
|
729
|
+
|
|
730
|
+
status String @default("PENDING") // PENDING, IN_PROGRESS, COMPLETED, FAILED, SKIPPED
|
|
731
|
+
|
|
732
|
+
// Assignment
|
|
733
|
+
assigneeId String?
|
|
734
|
+
assignee User? @relation("PhaseStepAssignee", fields: [assigneeId], references: [id])
|
|
735
|
+
|
|
736
|
+
// Required document types for UPLOAD steps
|
|
737
|
+
requiredDocumentTypes String? // CSV: ID,BANK_STATEMENT,INCOME_PROOF
|
|
738
|
+
|
|
739
|
+
// Timing
|
|
740
|
+
dueDate DateTime?
|
|
741
|
+
completedAt DateTime?
|
|
742
|
+
|
|
743
|
+
createdAt DateTime @default(now())
|
|
744
|
+
updatedAt DateTime @updatedAt
|
|
745
|
+
|
|
746
|
+
approvals ContractPhaseStepApproval[]
|
|
747
|
+
|
|
748
|
+
@@index([phaseId])
|
|
749
|
+
@@index([status])
|
|
750
|
+
@@index([order])
|
|
751
|
+
@@map("contract_phase_steps")
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Approvals for documentation steps
|
|
755
|
+
model ContractPhaseStepApproval {
|
|
756
|
+
id String @id @default(cuid())
|
|
757
|
+
stepId String
|
|
758
|
+
step ContractPhaseStep @relation(fields: [stepId], references: [id], onDelete: Cascade)
|
|
759
|
+
approverId String?
|
|
760
|
+
approver User? @relation("PhaseStepApprover", fields: [approverId], references: [id])
|
|
761
|
+
|
|
762
|
+
decision String // APPROVED, REJECTED, REQUEST_CHANGES
|
|
763
|
+
comment String? @db.Text
|
|
764
|
+
decidedAt DateTime @default(now())
|
|
558
765
|
|
|
559
|
-
|
|
560
|
-
payments Payment[]
|
|
766
|
+
createdAt DateTime @default(now())
|
|
561
767
|
|
|
562
|
-
@@index([
|
|
563
|
-
@@map("
|
|
768
|
+
@@index([stepId])
|
|
769
|
+
@@map("contract_phase_step_approvals")
|
|
564
770
|
}
|
|
565
771
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
772
|
+
// Installments within a PAYMENT phase
|
|
773
|
+
model ContractInstallment {
|
|
774
|
+
id String @id @default(cuid())
|
|
775
|
+
phaseId String
|
|
776
|
+
phase ContractPhase @relation(fields: [phaseId], references: [id], onDelete: Cascade)
|
|
777
|
+
|
|
570
778
|
installmentNumber Int
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
779
|
+
|
|
780
|
+
amount Float
|
|
781
|
+
principalAmount Float @default(0)
|
|
782
|
+
interestAmount Float @default(0)
|
|
783
|
+
|
|
784
|
+
dueDate DateTime
|
|
785
|
+
status String @default("PENDING") // PENDING, PAID, OVERDUE, PARTIALLY_PAID, WAIVED
|
|
786
|
+
|
|
787
|
+
paidAmount Float @default(0)
|
|
788
|
+
paidDate DateTime?
|
|
789
|
+
|
|
790
|
+
lateFee Float @default(0)
|
|
791
|
+
lateFeeWaived Boolean @default(false)
|
|
792
|
+
gracePeriodDays Int @default(0)
|
|
793
|
+
gracePeriodEndDate DateTime?
|
|
794
|
+
|
|
795
|
+
createdAt DateTime @default(now())
|
|
796
|
+
updatedAt DateTime @updatedAt
|
|
797
|
+
|
|
798
|
+
payments ContractPayment[]
|
|
799
|
+
|
|
800
|
+
@@index([phaseId])
|
|
585
801
|
@@index([dueDate])
|
|
586
802
|
@@index([status])
|
|
587
|
-
@@map("
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
803
|
+
@@map("contract_installments")
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Unified payment record for contracts
|
|
807
|
+
model ContractPayment {
|
|
808
|
+
id String @id @default(cuid())
|
|
809
|
+
contractId String
|
|
810
|
+
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
|
811
|
+
phaseId String?
|
|
812
|
+
phase ContractPhase? @relation(fields: [phaseId], references: [id])
|
|
813
|
+
installmentId String?
|
|
814
|
+
installment ContractInstallment? @relation(fields: [installmentId], references: [id])
|
|
815
|
+
payerId String?
|
|
816
|
+
payer User? @relation("ContractPayer", fields: [payerId], references: [id])
|
|
817
|
+
|
|
600
818
|
amount Float
|
|
601
|
-
principalAmount Float
|
|
602
|
-
interestAmount Float
|
|
603
|
-
lateFeeAmount Float
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
819
|
+
principalAmount Float @default(0)
|
|
820
|
+
interestAmount Float @default(0)
|
|
821
|
+
lateFeeAmount Float @default(0)
|
|
822
|
+
|
|
823
|
+
paymentMethod String // BANK_TRANSFER, CREDIT_CARD, WALLET, CASH, CHECK
|
|
824
|
+
status String @default("INITIATED") // INITIATED, PENDING, COMPLETED, FAILED, REFUNDED
|
|
825
|
+
|
|
826
|
+
reference String? @unique
|
|
827
|
+
gatewayResponse String? @db.Text // JSON
|
|
828
|
+
|
|
829
|
+
processedAt DateTime?
|
|
830
|
+
createdAt DateTime @default(now())
|
|
831
|
+
updatedAt DateTime @updatedAt
|
|
832
|
+
|
|
833
|
+
@@index([contractId])
|
|
834
|
+
@@index([phaseId])
|
|
835
|
+
@@index([installmentId])
|
|
613
836
|
@@index([payerId])
|
|
614
837
|
@@index([status])
|
|
615
838
|
@@index([reference])
|
|
616
|
-
@@map("
|
|
839
|
+
@@map("contract_payments")
|
|
617
840
|
}
|
|
618
841
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
buyer User? @relation("ContractBuyer", fields: [buyerId], references: [id])
|
|
627
|
-
sellerId String?
|
|
628
|
-
seller User? @relation("ContractSeller", fields: [sellerId], references: [id])
|
|
629
|
-
contractType String // MORTGAGE, SALE_AGREEMENT, LEASE_AGREEMENT, etc
|
|
630
|
-
contractNumber String @unique
|
|
631
|
-
title String
|
|
632
|
-
description String? @db.Text
|
|
633
|
-
status String @default("DRAFT") // DRAFT, PENDING_SIGNATURE, ACTIVE, COMPLETED, TERMINATED
|
|
634
|
-
startDate DateTime?
|
|
635
|
-
endDate DateTime?
|
|
636
|
-
signedAt DateTime?
|
|
637
|
-
terminatedAt DateTime?
|
|
638
|
-
createdAt DateTime @default(now())
|
|
639
|
-
updatedAt DateTime @updatedAt
|
|
842
|
+
// Contract documents (owned by contract, linked to phases/steps as needed)
|
|
843
|
+
model ContractDocument {
|
|
844
|
+
id String @id @default(cuid())
|
|
845
|
+
contractId String
|
|
846
|
+
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
|
847
|
+
phaseId String? // Optional link to specific phase
|
|
848
|
+
stepId String? // Optional link to specific step
|
|
640
849
|
|
|
641
|
-
|
|
850
|
+
name String
|
|
851
|
+
url String
|
|
852
|
+
type String // ID, BANK_STATEMENT, INCOME_PROOF, TITLE_DEED, SIGNATURE, etc.
|
|
853
|
+
uploadedById String?
|
|
854
|
+
uploadedBy User? @relation("DocumentUploader", fields: [uploadedById], references: [id])
|
|
642
855
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
856
|
+
status String @default("PENDING") // PENDING, APPROVED, REJECTED
|
|
857
|
+
|
|
858
|
+
createdAt DateTime @default(now())
|
|
859
|
+
updatedAt DateTime @updatedAt
|
|
860
|
+
|
|
861
|
+
@@index([contractId])
|
|
862
|
+
@@index([phaseId])
|
|
863
|
+
@@index([stepId])
|
|
864
|
+
@@index([type])
|
|
646
865
|
@@index([status])
|
|
647
|
-
@@map("
|
|
866
|
+
@@map("contract_documents")
|
|
648
867
|
}
|
|
649
868
|
|
|
650
|
-
|
|
869
|
+
// FSM transitions for audit
|
|
870
|
+
model ContractTransition {
|
|
871
|
+
id String @id @default(cuid())
|
|
872
|
+
contractId String
|
|
873
|
+
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
|
874
|
+
fromState String
|
|
875
|
+
toState String
|
|
876
|
+
trigger String
|
|
877
|
+
metadata String? @db.Text // JSON
|
|
878
|
+
transitionedAt DateTime @default(now())
|
|
879
|
+
|
|
880
|
+
@@index([contractId])
|
|
881
|
+
@@map("contract_transitions")
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Domain events for audit and integration
|
|
885
|
+
model ContractEvent {
|
|
651
886
|
id String @id @default(cuid())
|
|
652
887
|
contractId String
|
|
653
888
|
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
type String
|
|
889
|
+
event String
|
|
890
|
+
data String? @db.Text // JSON
|
|
657
891
|
createdAt DateTime @default(now())
|
|
658
|
-
updatedAt DateTime @updatedAt
|
|
659
892
|
|
|
660
893
|
@@index([contractId])
|
|
661
|
-
@@map("
|
|
894
|
+
@@map("contract_events")
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// =============================================================================
|
|
898
|
+
// EVENT OUTBOX - For guaranteed event delivery to SQS queues
|
|
899
|
+
// =============================================================================
|
|
900
|
+
|
|
901
|
+
model DomainEvent {
|
|
902
|
+
id String @id @default(cuid())
|
|
903
|
+
|
|
904
|
+
// Event identification
|
|
905
|
+
eventType String // MORTGAGE.CREATED, PHASE.ACTIVATED, PAYMENT.COMPLETED, etc
|
|
906
|
+
aggregateType String // Mortgage, MortgagePhase, MortgagePayment, Property, etc
|
|
907
|
+
aggregateId String
|
|
908
|
+
|
|
909
|
+
// Routing - which queue(s) should receive this
|
|
910
|
+
queueName String // notifications, payments, mortgage-steps, accounting, etc
|
|
911
|
+
|
|
912
|
+
// Event payload (all data needed by consumers)
|
|
913
|
+
payload String @db.Text // JSON
|
|
914
|
+
|
|
915
|
+
// Metadata
|
|
916
|
+
occurredAt DateTime @default(now())
|
|
917
|
+
actorId String? // User who triggered the event
|
|
918
|
+
actorRole String? // Role of the actor
|
|
919
|
+
|
|
920
|
+
// Processing status
|
|
921
|
+
status String @default("PENDING") // PENDING, PROCESSING, SENT, FAILED
|
|
922
|
+
processedAt DateTime?
|
|
923
|
+
sentAt DateTime?
|
|
924
|
+
failureCount Int @default(0)
|
|
925
|
+
lastError String? @db.Text
|
|
926
|
+
nextRetryAt DateTime?
|
|
927
|
+
|
|
928
|
+
createdAt DateTime @default(now())
|
|
929
|
+
updatedAt DateTime @updatedAt
|
|
930
|
+
|
|
931
|
+
@@index([status, nextRetryAt])
|
|
932
|
+
@@index([eventType])
|
|
933
|
+
@@index([aggregateType, aggregateId])
|
|
934
|
+
@@index([queueName])
|
|
935
|
+
@@index([occurredAt])
|
|
936
|
+
@@map("domain_events")
|
|
662
937
|
}
|