feat: 实现公平捞瓶和领取租约

This commit is contained in:
root
2026-09-15 13:56:56 +08:00
parent 969a10d664
commit 69fc8d51ce
23 changed files with 1221 additions and 20 deletions
+30 -10
View File
@@ -118,6 +118,7 @@ model Account {
notifications Notification[]
auditLogs AuditLog[] @relation("AuditActor")
dailyUsage DailyUsage[]
pickRequests BottlePickRequest[]
@@map("accounts")
}
@@ -213,6 +214,8 @@ model Bottle {
pickHistory BottlePickHistory[]
conversation Conversation?
reports Report[]
activeLeaseId String? @unique @map("active_lease_id") @db.Uuid
activeLease BottlePickLease? @relation("ActiveBottleLease", fields: [activeLeaseId], references: [id], onDelete: SetNull)
@@unique([authorId, clientRequestId])
@@index([poolStatus, createdAt])
@@ -223,22 +226,39 @@ model Bottle {
model BottlePickLease {
/// Partial unique index bottle_pick_leases_one_active_per_bottle is managed in 0001_init SQL.
id String @id @default(uuid()) @db.Uuid
bottleId String @map("bottle_id") @db.Uuid
pickerId String @map("picker_id") @db.Uuid
leaseTokenHash String @unique @map("lease_token_hash") @db.VarChar(255)
expiresAt DateTime @map("expires_at") @db.Timestamptz(3)
status BottlePickLeaseStatus @default(ACTIVE)
endedAt DateTime? @map("ended_at") @db.Timestamptz(3)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
bottle Bottle @relation(fields: [bottleId], references: [id], onDelete: Cascade)
picker Account @relation("PickerLeases", fields: [pickerId], references: [id], onDelete: Cascade)
id String @id @default(uuid()) @db.Uuid
bottleId String @map("bottle_id") @db.Uuid
pickerId String @map("picker_id") @db.Uuid
leaseTokenHash String @unique @map("lease_token_hash") @db.VarChar(255)
leaseTokenCiphertext Bytes @map("lease_token_ciphertext")
expiresAt DateTime @map("expires_at") @db.Timestamptz(3)
status BottlePickLeaseStatus @default(ACTIVE)
endedAt DateTime? @map("ended_at") @db.Timestamptz(3)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
bottle Bottle @relation(fields: [bottleId], references: [id], onDelete: Cascade)
activeForBottle Bottle? @relation("ActiveBottleLease")
picker Account @relation("PickerLeases", fields: [pickerId], references: [id], onDelete: Cascade)
pickRequest BottlePickRequest?
@@index([pickerId, expiresAt])
@@index([bottleId, expiresAt])
@@map("bottle_pick_leases")
}
model BottlePickRequest {
id String @id @default(uuid()) @db.Uuid
pickerId String @map("picker_id") @db.Uuid
requestId String @map("request_id") @db.VarChar(128)
leaseId String? @unique @map("lease_id") @db.Uuid
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
picker Account @relation(fields: [pickerId], references: [id], onDelete: Cascade)
lease BottlePickLease? @relation(fields: [leaseId], references: [id], onDelete: SetNull)
@@unique([pickerId, requestId])
@@index([createdAt])
@@map("bottle_pick_requests")
}
model BottlePickHistory {
id String @id @default(uuid()) @db.Uuid
bottleId String @map("bottle_id") @db.Uuid