feat(payments): add Order & Escrow entities with CQRS commands, Prisma schema
- Add Order entity with lifecycle (pending → paid → completed/cancelled/refunded) - Add Escrow entity with hold/release/dispute flow for secure transactions - Add PlatformFee value object with tiered commission calculation - Implement CQRS: CreateOrder, CancelOrder, HoldEscrow, ReleaseEscrow commands - Add GetOrderStatus query handler - Add OrdersController with REST endpoints and DTOs - Add Prisma models for Order, Escrow, EscrowStatusHistory - Add domain event classes for order and escrow state changes - Add unit tests for Order, Escrow entities and PlatformFee VO - Update PROJECT_TRACKER to Wave 14 status Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,8 @@ model User {
|
||||
refreshTokens RefreshToken[]
|
||||
oauthAccounts OAuthAccount[]
|
||||
buyerTransactions Transaction[] @relation("BuyerTransactions")
|
||||
buyerOrders Order[] @relation("BuyerOrders")
|
||||
sellerOrders Order[] @relation("SellerOrders")
|
||||
mfaChallenges MfaChallenge[]
|
||||
|
||||
@@index([role])
|
||||
@@ -275,6 +277,7 @@ model Listing {
|
||||
|
||||
transactions Transaction[]
|
||||
inquiries Inquiry[]
|
||||
orders Order[]
|
||||
|
||||
// --- Single-column indexes ---
|
||||
@@index([status])
|
||||
@@ -419,6 +422,7 @@ enum PaymentType {
|
||||
LISTING_FEE
|
||||
DEPOSIT
|
||||
FEATURED_LISTING
|
||||
AUCTION_PAYMENT
|
||||
}
|
||||
|
||||
model Payment {
|
||||
@@ -427,6 +431,8 @@ model Payment {
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Restrict)
|
||||
transactionId String?
|
||||
transaction Transaction? @relation(fields: [transactionId], references: [id], onDelete: SetNull)
|
||||
orderId String?
|
||||
order Order? @relation(fields: [orderId], references: [id], onDelete: SetNull)
|
||||
provider PaymentProvider
|
||||
type PaymentType
|
||||
amountVND BigInt
|
||||
@@ -440,6 +446,7 @@ model Payment {
|
||||
@@unique([userId, provider, idempotencyKey], name: "Payment_idempotency_unique")
|
||||
@@index([userId])
|
||||
@@index([transactionId])
|
||||
@@index([orderId])
|
||||
@@index([status])
|
||||
@@index([providerTxId])
|
||||
@@index([createdAt])
|
||||
@@ -448,6 +455,77 @@ model Payment {
|
||||
@@index([userId, type, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ORDERS & ESCROW (Auction Settlement)
|
||||
// =============================================================================
|
||||
|
||||
enum OrderStatus {
|
||||
CREATED
|
||||
PAYMENT_PENDING
|
||||
PAYMENT_CONFIRMED
|
||||
ESCROW_HELD
|
||||
SHIPPED
|
||||
DELIVERED
|
||||
DISPUTE
|
||||
ESCROW_RELEASED
|
||||
COMPLETED
|
||||
CANCELLED
|
||||
REFUNDED
|
||||
}
|
||||
|
||||
enum EscrowStatus {
|
||||
PENDING
|
||||
HELD
|
||||
RELEASED
|
||||
REFUNDED
|
||||
DISPUTED
|
||||
}
|
||||
|
||||
model Order {
|
||||
id String @id @default(cuid())
|
||||
buyerId String
|
||||
buyer User @relation("BuyerOrders", fields: [buyerId], references: [id], onDelete: Restrict)
|
||||
sellerId String
|
||||
seller User @relation("SellerOrders", fields: [sellerId], references: [id], onDelete: Restrict)
|
||||
listingId String
|
||||
listing Listing @relation(fields: [listingId], references: [id], onDelete: Restrict)
|
||||
status OrderStatus @default(CREATED)
|
||||
amountVND BigInt
|
||||
platformFeeVND BigInt
|
||||
sellerPayoutVND BigInt
|
||||
idempotencyKey String? @unique
|
||||
metadata Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
payments Payment[]
|
||||
escrow Escrow?
|
||||
|
||||
@@index([buyerId])
|
||||
@@index([sellerId])
|
||||
@@index([listingId])
|
||||
@@index([status])
|
||||
@@index([createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model Escrow {
|
||||
id String @id @default(cuid())
|
||||
orderId String @unique
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Restrict)
|
||||
amountVND BigInt
|
||||
feeVND BigInt
|
||||
status EscrowStatus @default(PENDING)
|
||||
heldAt DateTime?
|
||||
releasedAt DateTime?
|
||||
disputeReason String? @db.Text
|
||||
disputedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([status])
|
||||
@@index([orderId])
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// SUBSCRIPTIONS
|
||||
// =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user