Comprehensive admin + user dashboards (production-ready)
This commit is contained in:
+53
-2
@@ -30,6 +30,7 @@ model User {
|
||||
// app fields
|
||||
stripeCustomerId String?
|
||||
paypalPayerId String?
|
||||
onboardedAt DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -37,13 +38,15 @@ model User {
|
||||
sessions Session[]
|
||||
accounts Account[]
|
||||
memberships Member[]
|
||||
sentInvitations Invitation[] @relation("SentInvitations")
|
||||
sentInvitations Invitation[] @relation("SentInvitations")
|
||||
episodes Episode[]
|
||||
series Series[]
|
||||
apiKeys ApiKey[]
|
||||
usageRecords UsageRecord[]
|
||||
auditLogs AuditLog[] @relation("ActorLogs")
|
||||
auditLogs AuditLog[] @relation("ActorLogs")
|
||||
preferences UserPreferences?
|
||||
|
||||
@@index([createdAt])
|
||||
@@map("user")
|
||||
}
|
||||
|
||||
@@ -210,6 +213,8 @@ model Subscription {
|
||||
@@index([referenceId])
|
||||
@@index([stripeSubscriptionId])
|
||||
@@index([paypalSubscriptionId])
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
@@map("subscription")
|
||||
}
|
||||
|
||||
@@ -290,6 +295,11 @@ model Episode {
|
||||
stage String? // human-readable current step
|
||||
errorMessage String?
|
||||
|
||||
// Public share: when shareId is set, the episode is reachable at /p/<shareId>
|
||||
// without auth. Clearing shareId disables the public page.
|
||||
shareId String? @unique
|
||||
sharedAt DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -305,6 +315,7 @@ model Episode {
|
||||
@@index([organizationId])
|
||||
@@index([seriesId])
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
@@map("episode")
|
||||
}
|
||||
|
||||
@@ -483,6 +494,8 @@ model ContentFlag {
|
||||
episodeId String
|
||||
episode Episode @relation(fields: [episodeId], references: [id], onDelete: Cascade)
|
||||
reason String
|
||||
source String @default("system") // "moderation" | "report" | "system"
|
||||
severity String @default("medium") // "low" | "medium" | "high"
|
||||
status String @default("open") // open | reviewed | removed
|
||||
reviewedBy String?
|
||||
createdAt DateTime @default(now())
|
||||
@@ -490,3 +503,41 @@ model ContentFlag {
|
||||
@@index([status])
|
||||
@@map("content_flag")
|
||||
}
|
||||
|
||||
/// Liveness of a long-running worker process (heartbeat). One row per worker name.
|
||||
model WorkerHeartbeat {
|
||||
name String @id
|
||||
lastBeatAt DateTime
|
||||
queued Int?
|
||||
running Int?
|
||||
meta Json?
|
||||
|
||||
@@map("worker_heartbeat")
|
||||
}
|
||||
|
||||
/// Per-user editor defaults and notification preferences (settings page).
|
||||
model UserPreferences {
|
||||
userId String @id
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
defaultVoiceId String?
|
||||
defaultLanguage String @default("en")
|
||||
emailOnEpisodeReady Boolean @default(true)
|
||||
productEmails Boolean @default(true)
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("user_preferences")
|
||||
}
|
||||
|
||||
/// Billing webhook delivery log — also dedups replayed events on `eventId`.
|
||||
model WebhookEvent {
|
||||
id String @id @default(cuid())
|
||||
provider String // "stripe" | "paypal"
|
||||
eventId String @unique
|
||||
type String
|
||||
status String @default("processed") // processed | failed | skipped
|
||||
error String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([provider, createdAt])
|
||||
@@map("webhook_event")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user