Skip to content
Closed
19 changes: 19 additions & 0 deletions prisma/migrations/20260530100000_add_escrow_event/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- Issue #108: EscrowEvent table for append-only escrow state-transition auditing.
-- Supports reconstructing the full escrow lifecycle from persisted from/to states.

-- CreateTable
CREATE TABLE "EscrowEvent" (
"id" TEXT NOT NULL,
"escrowId" TEXT NOT NULL,
"fromState" TEXT,
"toState" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "EscrowEvent_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE INDEX "EscrowEvent_escrowId_idx" ON "EscrowEvent"("escrowId");

-- AddForeignKey
ALTER TABLE "EscrowEvent" ADD CONSTRAINT "EscrowEvent_escrowId_fkey" FOREIGN KEY ("escrowId") REFERENCES "Escrow"("id") ON DELETE CASCADE ON UPDATE CASCADE;
28 changes: 15 additions & 13 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,27 @@ model Escrow {
updatedAt DateTime @updatedAt
disputes Dispute[]
notifications Notification[]
events EscrowEvent[]

@@index([vendorAddress])
@@index([buyerAddress])
@@index([vendorAddress, state])
}

/// Append-only audit log of escrow state transitions (#108).
/// One row per state change captures previous and new state for lifecycle reconstruction.
model EscrowEvent {
id String @id @default(cuid())
escrowId String
fromState String?
toState String
createdAt DateTime @default(now())

escrow Escrow @relation(fields: [escrowId], references: [id], onDelete: Cascade)

@@index([escrowId])
}

model Dispute {
id String @id @default(uuid())
escrowId String
Expand All @@ -66,18 +81,6 @@ model Notification {
escrow Escrow @relation(fields: [escrowId], references: [id], onDelete: Cascade)
}

model Dispute {
id String @id @default(cuid())
escrowId String @unique
reason String
status String @default("OPEN")
resolvedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

escrow Escrow @relation(fields: [escrowId], references: [id], onDelete: Cascade)
}

model VendorProfile {
address String @id
businessName String
Expand All @@ -89,7 +92,6 @@ model VendorProfile {

accountDetails VendorAccountDetails?
trackingSettings VendorTrackingSettings?
escrows Escrow[] @relation("VendorEscrows")
}

model VendorAccountDetails {
Expand Down