diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6cd47e5..60cd217 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -392,9 +392,37 @@ model Story { reactions StoryReaction[] comments StoryComment[] + // Story music overlay — optional, admin-curated catalog only (no user + // uploads, licensing liability). onDelete: SetNull so retiring/deleting a + // MusicTrack never orphans historical stories that already used it. + musicTrack MusicTrack? @relation(fields: [musicTrackId], references: [id], onDelete: SetNull) + musicTrackId String? + musicOffsetSecs Float? @default(0) // start point within the track, since story display duration is fixed + musicMuteOriginal Boolean @default(false) // VIDEO stories only — mute the baked-in Mux audio in favor of the track + @@index([petId, expiresAt]) // supports lazy-delete filter query @@index([muxUploadId]) @@index([muxAssetId]) + @@index([musicTrackId]) +} + +// Admin-curated royalty-free music catalog for the Story music overlay. +// Deliberately no user-upload path — copyright liability stays with the +// admin who uploads and records `licenseNote` for each track. +model MusicTrack { + id String @id @default(cuid()) + title String @db.VarChar(100) + artist String @db.VarChar(100) + licenseNote String @db.VarChar(500) // license/source reference, required for compliance + storageKey String // Supabase Storage object key, MUSIC_STORAGE_BUCKET + durationSecs Float + active Boolean @default(true) // soft-disable instead of deleting so past stories keep working + createdBy String // ownerId of the admin who uploaded it + createdAt DateTime @default(now()) + + stories Story[] + + @@index([active]) } enum StoryMediaType { @@ -855,8 +883,8 @@ model AdRepost { model ModerationLog { id String @id @default(cuid()) - action String @db.VarChar(50) // DELETE_POST | DELETE_COMMENT | BAN_USER | UNBAN_USER | DELETE_IMAGE | DISMISS_REPORT | CREATE_AD | UPDATE_AD | DELETE_AD | GRANT_ROLE | REVOKE_ROLE | WARN_USER | VERIFY_PET | UNVERIFY_PET | DELETE_ACCOUNT | APPROVE_VERIFICATION_REQUEST | REJECT_VERIFICATION_REQUEST | HIDE_POST | UNHIDE_POST | SHADOWBAN_USER | UNSHADOWBAN_USER | SET_AI_DISCLOSURE | ENABLE_MAINTENANCE_MODE | DISABLE_MAINTENANCE_MODE | PIN_POST | UNPIN_POST | SEND_BROADCAST | DELETE_BROADCAST - targetType String @db.VarChar(20) // POST | COMMENT | USER | IMAGE | AD | REPORT | PET | SYSTEM + action String @db.VarChar(50) // DELETE_POST | DELETE_COMMENT | BAN_USER | UNBAN_USER | DELETE_IMAGE | DISMISS_REPORT | CREATE_AD | UPDATE_AD | DELETE_AD | GRANT_ROLE | REVOKE_ROLE | WARN_USER | VERIFY_PET | UNVERIFY_PET | DELETE_ACCOUNT | APPROVE_VERIFICATION_REQUEST | REJECT_VERIFICATION_REQUEST | HIDE_POST | UNHIDE_POST | SHADOWBAN_USER | UNSHADOWBAN_USER | SET_AI_DISCLOSURE | ENABLE_MAINTENANCE_MODE | DISABLE_MAINTENANCE_MODE | PIN_POST | UNPIN_POST | SEND_BROADCAST | DELETE_BROADCAST | CREATE_MUSIC_TRACK | UPDATE_MUSIC_TRACK | DELETE_MUSIC_TRACK + targetType String @db.VarChar(20) // POST | COMMENT | USER | IMAGE | AD | REPORT | PET | SYSTEM | MUSIC_TRACK targetId String reason String? @db.VarChar(500) moderatorId String // ownerId