fix: 完善权威数据约束与测试隔离
This commit is contained in:
+79
-37
@@ -19,12 +19,27 @@ enum AuthProvider {
|
||||
WECHAT
|
||||
}
|
||||
|
||||
enum BottleStatus {
|
||||
enum ReviewStatus {
|
||||
DRAFT
|
||||
REVIEWING
|
||||
REJECTED
|
||||
MANUAL_REVIEW
|
||||
APPROVED
|
||||
}
|
||||
|
||||
enum BottlePoolStatus {
|
||||
IN_POOL
|
||||
PICKED
|
||||
EXPIRED
|
||||
LEASED
|
||||
CONSUMED
|
||||
REMOVED
|
||||
CLOSED
|
||||
}
|
||||
|
||||
enum BottlePickLeaseStatus {
|
||||
ACTIVE
|
||||
RETURNED
|
||||
EXPIRED
|
||||
CONSUMED
|
||||
}
|
||||
|
||||
enum ConversationStatus {
|
||||
@@ -103,14 +118,17 @@ model Account {
|
||||
}
|
||||
|
||||
model AnonymousProfile {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
accountId String @unique @map("account_id") @db.Uuid
|
||||
nickname String @db.VarChar(64)
|
||||
avatarKey String? @map("avatar_key") @db.VarChar(255)
|
||||
bio String? @db.VarChar(500)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
accountId String @unique @map("account_id") @db.Uuid
|
||||
publicId String @unique @default(uuid()) @map("public_id") @db.Uuid
|
||||
nickname String @db.VarChar(64)
|
||||
avatarKey String? @map("avatar_key") @db.VarChar(255)
|
||||
avatarColor String @map("avatar_color") @db.VarChar(16)
|
||||
bio String? @db.VarChar(500)
|
||||
reviewStatus ReviewStatus @default(REVIEWING) @map("review_status")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("anonymous_profiles")
|
||||
}
|
||||
@@ -148,8 +166,11 @@ model Bottle {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
authorId String @map("author_id") @db.Uuid
|
||||
contentText String @map("content_text") @db.Text
|
||||
status BottleStatus @default(DRAFT)
|
||||
pickedAt DateTime? @map("picked_at") @db.Timestamptz(3)
|
||||
reviewStatus ReviewStatus @default(DRAFT) @map("review_status")
|
||||
poolStatus BottlePoolStatus @default(CLOSED) @map("pool_status")
|
||||
version Int @default(1)
|
||||
approvedAt DateTime? @map("approved_at") @db.Timestamptz(3)
|
||||
consumedAt DateTime? @map("consumed_at") @db.Timestamptz(3)
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamptz(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
@@ -159,21 +180,24 @@ model Bottle {
|
||||
conversation Conversation?
|
||||
reports Report[]
|
||||
|
||||
@@index([status, createdAt])
|
||||
@@index([poolStatus, createdAt])
|
||||
@@index([reviewStatus, createdAt])
|
||||
@@index([authorId, createdAt])
|
||||
@@map("bottles")
|
||||
}
|
||||
|
||||
model BottlePickLease {
|
||||
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)
|
||||
consumedAt DateTime? @map("consumed_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)
|
||||
/// 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)
|
||||
|
||||
@@index([pickerId, expiresAt])
|
||||
@@index([bottleId, expiresAt])
|
||||
@@ -194,6 +218,7 @@ model BottlePickHistory {
|
||||
}
|
||||
|
||||
model DailyUsage {
|
||||
/// Nonnegative counters are enforced by CHECK constraints in 0001_init SQL.
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
accountId String @map("account_id") @db.Uuid
|
||||
usageDate DateTime @map("usage_date") @db.Date
|
||||
@@ -213,7 +238,8 @@ model Conversation {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
sourceBottleId String @unique @map("source_bottle_id") @db.Uuid
|
||||
status ConversationStatus @default(ACTIVE)
|
||||
nextSeq Int @default(1) @map("next_seq")
|
||||
nextSeq BigInt @default(1) @map("next_seq")
|
||||
lastMessageAt DateTime @default(now()) @map("last_message_at") @db.Timestamptz(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
sourceBottle Bottle @relation(fields: [sourceBottleId], references: [id], onDelete: Restrict)
|
||||
@@ -226,14 +252,16 @@ model Conversation {
|
||||
}
|
||||
|
||||
model ConversationMember {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
conversationId String @map("conversation_id") @db.Uuid
|
||||
accountId String @map("account_id") @db.Uuid
|
||||
joinedAt DateTime @default(now()) @map("joined_at") @db.Timestamptz(3)
|
||||
leftAt DateTime? @map("left_at") @db.Timestamptz(3)
|
||||
lastReadSeq Int @default(0) @map("last_read_seq")
|
||||
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
||||
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
conversationId String @map("conversation_id") @db.Uuid
|
||||
accountId String @map("account_id") @db.Uuid
|
||||
joinedAt DateTime @default(now()) @map("joined_at") @db.Timestamptz(3)
|
||||
leftAt DateTime? @map("left_at") @db.Timestamptz(3)
|
||||
lastReadSeq BigInt @default(0) @map("last_read_seq")
|
||||
peerAliasSnapshot String @map("peer_alias_snapshot") @db.VarChar(64)
|
||||
blockedAt DateTime? @map("blocked_at") @db.Timestamptz(3)
|
||||
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
||||
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([conversationId, accountId])
|
||||
@@index([accountId, joinedAt])
|
||||
@@ -245,9 +273,12 @@ model Message {
|
||||
conversationId String @map("conversation_id") @db.Uuid
|
||||
senderId String @map("sender_id") @db.Uuid
|
||||
clientMsgId String @map("client_msg_id") @db.VarChar(128)
|
||||
seq Int
|
||||
seq BigInt
|
||||
contentText String @map("content_text") @db.Text
|
||||
status MessageStatus @default(SENT)
|
||||
reviewStatus ReviewStatus @default(REVIEWING) @map("review_status")
|
||||
sentAt DateTime @default(now()) @map("sent_at") @db.Timestamptz(3)
|
||||
recalledAt DateTime? @map("recalled_at") @db.Timestamptz(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
||||
@@ -274,6 +305,7 @@ model Block {
|
||||
}
|
||||
|
||||
model Report {
|
||||
/// Exactly one nullable target foreign key must be set; enforced in 0001_init SQL.
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
reporterId String @map("reporter_id") @db.Uuid
|
||||
reportedAccountId String? @map("reported_account_id") @db.Uuid
|
||||
@@ -282,6 +314,8 @@ model Report {
|
||||
messageId String? @map("message_id") @db.Uuid
|
||||
reason String @db.VarChar(100)
|
||||
details String? @db.Text
|
||||
targetSnapshot Json @map("target_snapshot")
|
||||
resolution String? @db.Text
|
||||
status ReportStatus @default(PENDING)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
@@ -299,17 +333,25 @@ model Report {
|
||||
|
||||
model ModerationTask {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
reportId String @map("report_id") @db.Uuid
|
||||
targetType String @map("target_type") @db.VarChar(50)
|
||||
targetId String @map("target_id") @db.Uuid
|
||||
provider String @db.VarChar(100)
|
||||
result Json?
|
||||
riskLabels String[] @map("risk_labels")
|
||||
payloadHash String @map("payload_hash") @db.VarChar(128)
|
||||
reportId String? @map("report_id") @db.Uuid
|
||||
assignedToId String? @map("assigned_to_id") @db.Uuid
|
||||
status ModerationTaskStatus @default(PENDING)
|
||||
decision String? @db.Text
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
reviewedAt DateTime? @map("reviewed_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
report Report @relation(fields: [reportId], references: [id], onDelete: Cascade)
|
||||
report Report? @relation(fields: [reportId], references: [id], onDelete: SetNull)
|
||||
assignedTo Account? @relation("Moderator", fields: [assignedToId], references: [id], onDelete: SetNull)
|
||||
sanctions Sanction[]
|
||||
|
||||
@@index([status, createdAt])
|
||||
@@index([targetType, targetId])
|
||||
@@index([assignedToId, status])
|
||||
@@map("moderation_tasks")
|
||||
}
|
||||
@@ -357,12 +399,12 @@ model OutboxEvent {
|
||||
payload Json
|
||||
status OutboxStatus @default(PENDING)
|
||||
attempts Int @default(0)
|
||||
availableAt DateTime @default(now()) @map("available_at") @db.Timestamptz(3)
|
||||
nextRetryAt DateTime @default(now()) @map("next_retry_at") @db.Timestamptz(3)
|
||||
publishedAt DateTime? @map("published_at") @db.Timestamptz(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
|
||||
@@index([status, availableAt])
|
||||
@@index([status, nextRetryAt])
|
||||
@@index([aggregateType, aggregateId])
|
||||
@@map("outbox_events")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user