Files
hqland-app/prisma.md
2026-04-18 04:46:01 +00:00

8.6 KiB

Dành cho AI Agent & Lập trình

Dưới đây là file Prisma Schema đầy đủ, thống nhất và chi tiết nhất dựa trên tất cả các yêu cầu bạn đã nêu từ đầu đến giờ (bao gồm file Excel, logic chuyển nhượng, tình trạng hạ tầng nested, PaymentSchedule với template, dư/thiếu tiền, v.v.).

prisma

// =============================================
// PRISMA SCHEMA - HỆ THỐNG QUẢN LÝ BẤT ĐỘNG SẢN
// Phiên bản: 2.3
// Ngày: 18/04/2026
// Mục đích: Hoàn chỉnh, self-host, hỗ trợ nhiều loại sản phẩm, 
//           lịch sử chuyển nhượng, phụ lục kế thừa, 
//           tình trạng hạ tầng nested, và dòng tiền chi tiết.
// =============================================

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

// =============================================
// 1. PROJECT (Khu / Dự án)
// =============================================
model Project {
  id          String   @id @default(uuid())
  code        String   @unique   // ví dụ: STH03
  name        String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  products    Product[]
  templates   PaymentTemplate[]
}

// =============================================
// 2. PRODUCT (Sản phẩm - Đất nền, Căn hộ...)
// =============================================
model Product {
  id                        String       @id @default(uuid())
  projectId                 String

  productType               ProductType

  // === TRƯỜNG CHUNG TỪ FILE sanpham.xlsx ===
  code                      String       @unique   // Khu + Lô (STH03.01)
  area                      Decimal
  pricePerUnit              Decimal
  totalPrice                Decimal
  qsddValue                 Decimal
  foundationTempValue       Decimal
  contractTempValue         Decimal
  adjacentRoad              String?
  frontageCount             Int?
  maxFloors                 Int?
  buildingDensity           Decimal?
  constructionStatus        String?

  // === TÌNH TRẠNG HẠ TẦNG (NESTED JSONB) ===
  infrastructureRawText     String?      // Giữ nguyên text gốc để backup
  infrastructureStatus      Json         // Cấu trúc nested (hỗ trợ child-of-child)

  // === TRẠNG THÁI SỔ ĐỎ ===
  redBookStatus             String       @default("Chưa có dữ liệu")

  // === TRƯỜNG LINH HOẠT CHO SẢN PHẨM MỚI ===
  customData                Json         // Block, tầng, hướng, sổ hồng riêng, giấy phép XD...

  createdAt                 DateTime     @default(now())
  updatedAt                 DateTime     @updatedAt

  project                   Project      @relation(fields: [projectId], references: [id])
  contracts                 Contract[]
  settlements               Settlement[]
}

// =============================================
// ENUM LOẠI SẢN PHẨM
// =============================================
enum ProductType {
  LAND
  APARTMENT
  SHOPHOUSE
  OFFICE
  CONDOTEL
  VILLA
  // Thêm loại mới ở đây
}

// =============================================
// 3. CONTRACT & CHUYỂN NHƯỢNG (Giữ nguyên logic Excel)
// =============================================
model Contract {
  id                String   @id @default(uuid())
  productId         String
  transferOrder     Int      // 0 = KH HIỆN TẠI, 1 = HĐ GỐC, 2+ = VBCN
  contractType      String   // HĐGV, HĐMB, VBCN
  contractNumber    String
  signingDate       DateTime
  totalValue        Decimal
  paidAmount        Decimal
  remainingAmount   Decimal
  metadata          Json?

  product           Product  @relation(fields: [productId], references: [id])
  customers         ContractCustomer[]
  appendices        Appendix[]
  payments          Payment[]
  schedule          PaymentSchedule?
  fines             PaymentFine[]

  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt
}

model Customer {
  id          String   @id @default(uuid())
  cmndCccd    String   @unique
  fullName    String
  phone       String
  email       String?
  address     Json?
  dob         DateTime?

  contracts   ContractCustomer[]
}

model ContractCustomer {
  id            String   @id @default(uuid())
  contractId    String
  customerId    String
  role          String   // "CHỦ SH 1", "CHỦ SH 2", "CHỦ SH 3"
  transferOrder Int

  contract      Contract @relation(fields: [contractId], references: [id])
  customer      Customer @relation(fields: [customerId], references: [id])
}

// =============================================
// 4. APPENDIX (Phụ lục)
// =============================================
model Appendix {
  id               String   @id @default(uuid())
  contractId       String
  productId        String
  type             String
  applyFromOrder   Int      // Kế thừa từ CN #
  signingDate      DateTime
  customData       Json?

  contract         Contract @relation(fields: [contractId], references: [id])
}

// =============================================
// 5. SETTLEMENT (Quyết toán & Sổ đỏ)
// =============================================
model Settlement {
  id            String   @id @default(uuid())
  productId     String
  type          String   // MÓNG, THÂN, CP THI CÔNG
  tempValue     Decimal
  finalValue    Decimal
  difference    Decimal
  redBookStatus String
  issueDate     DateTime?

  product       Product  @relation(fields: [productId], references: [id])
}

// =============================================
// 6. PAYMENT MODULE - DÒNG TIỀN (THEO YÊU CẦU)
// =============================================
model PaymentTemplate {
  id          String   @id @default(uuid())
  projectId   String
  name        String   // "Thanh toán chuẩn 30-30-40", "Trả một lần"
  isDefault   Boolean  @default(false)

  project     Project  @relation(fields: [projectId], references: [id])
  items       PaymentScheduleItem[]
  schedules   PaymentSchedule[]

  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

model PaymentScheduleItem {
  id                String      @id @default(uuid())
  templateId        String?
  scheduleId        String?

  installmentNo     Int
  amount            Decimal?
  percentage        Decimal?     // Ưu tiên % nếu có

  // Hai cách tính ngày đến hạn
  daysAfterSigning  Int?         // Số ngày sau ngày ký hợp đồng
  dueDate           DateTime?    // Ngày chính xác

  type              PaymentType

  template          PaymentTemplate? @relation(fields: [templateId], references: [id])
  schedule          PaymentSchedule? @relation(fields: [scheduleId], references: [id])
  payments          Payment[]

  createdAt         DateTime @default(now())
}

model PaymentSchedule {
  id          String   @id @default(uuid())
  contractId  String
  templateId  String   // Template đã chọn khi tạo hợp đồng

  contract    Contract @relation(fields: [contractId], references: [id])
  template    PaymentTemplate @relation(fields: [templateId], references: [id])
  items       PaymentScheduleItem[]

  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

model Payment {
  id              String   @id @default(uuid())
  contractId      String
  scheduleItemId  String?

  amount          Decimal
  paidDate        DateTime
  receiptNumber   String?
  method          String
  metadata        Json?

  contract        Contract @relation(fields: [contractId], references: [id])
  scheduleItem    PaymentScheduleItem? @relation(fields: [scheduleItemId], references: [id])

  createdAt       DateTime @default(now())
}

model PaymentFine {
  id          String   @id @default(uuid())
  contractId  String
  amount      Decimal
  reason      String
  dueDate     DateTime
  paidDate    DateTime?

  contract    Contract @relation(fields: [contractId], references: [id])
}

// =============================================
// ENUMS
// =============================================
enum PaymentType {
  QSDD
  MONG
  THAN
  CHI_PHI_TC
  CK
  PHAT
  OTHER
}

Hướng dẫn sử dụng cho AI Agent / Lập trình:

  • Model chính: Product, Contract, PaymentTemplate, PaymentScheduleItem, PaymentSchedule, Payment.
  • Logic tạo hợp đồng: Khi tạo Contract → clone PaymentTemplate (mặc định hoặc do nhân viên chọn) thành PaymentSchedule + các PaymentScheduleItem.
  • Dư/thiếu tiền: Xử lý ở tầng application logic (khi tạo Payment).
  • Tình trạng hạ tầng: Sử dụng infrastructureStatus JSONB (nested).
  • Dynamic fields: Sử dụng customData JSONB.