// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model Guild { id String @id @unique createdAt DateTime @default(now()) updatedAt DateTime @default(now()) configuration Configuration? questions Question[] EventSchedule EventSchedule[] } model Question { id String @id @default(cuid()) createdAt DateTime updatedAt DateTime @updatedAt threadId String @unique ownerId String channelName String threadMetaUpdatedAt DateTime @default(now()) title String isSolved Boolean @default(false) url String? answer Answer? guild Guild @relation(fields: [guildId], references: [id]) guildId String githubDiscussion GitHubDiscussion? @relation(fields: [githubDiscussionId], references: [id]) githubDiscussionId String? @unique participation Participation[] // tags applied to forum channel posts (by ID) tags QuestionTag[] } model QuestionTag { // discord forum post tag id id String @id name String questions Question[] @@unique([id, name]) } model Participation { id String @id @default(cuid()) question Question @relation(fields: [questionId], references: [id]) questionId String participant DiscordUser @relation(fields: [participantId], references: [id]) // @TODO - track role at the time of participation, accounts for users that _leave_ "staff" participantId String participantRoles DiscordRole[] answer Answer? @@unique([questionId, participantId]) } model DiscordRole { id String @id @unique // Discord Role ID participation Participation[] role AccessLevelRole? } model DiscordUser { id String @id @unique account Account? @relation(fields: [accountId], references: [id]) accountId String? @unique participations Participation[] // we are not storing roles on users because we want to capture point-in-time roles for participation records answers Answer[] attended DiscordEventAttendee[] createdEvents DiscordEvent[] createdSchedules EventSchedule[] } model EventSchedule { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt guild Guild @relation(fields: [guildId], references: [id]) guildId String createdBy DiscordUser @relation(fields: [createdById], references: [id]) createdById String event DiscordEvent[] /// cron expression schedule String // @TODO - add a way to track the timezone of the event } model DiscordEvent { id String @id @unique /// Title of the event title String /// Description of the event (max 1000 characters) description String /// Public image URL of the event imageUrl String? /// Discord Channel ID or external URL location String? /// The date and time of the event start DateTime /// Track who creates the recurring event createdBy DiscordUser @relation(fields: [createdById], references: [id]) createdById String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt schedule EventSchedule? @relation(fields: [scheduleId], references: [id]) scheduleId String? attendees DiscordEventAttendee[] eventScheduleId String } model DiscordEventAttendee { event DiscordEvent @relation(fields: [eventId], references: [id]) eventId String member DiscordUser @relation(fields: [memberId], references: [id]) memberId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt /// time spent attending the event (in minutes) time Int @@unique([eventId, memberId]) } model GitHubDiscussion { id String @id @unique // GitHub Discussion ID url String Question Question? } model Answer { id String @id @default(cuid()) selectedAt DateTime @default(now()) selectedBy String // Discord user ID createdAt DateTime updatedAt DateTime @updatedAt owner DiscordUser @relation(fields: [ownerId], references: [id]) ownerId String // Discord member that answered the question content String url String? question Question @relation(fields: [questionId], references: [id]) questionId String @unique // Question.id participation Participation @relation(fields: [participationId], references: [id]) participationId String @unique } // SQLite does not support enums, https://github.com/prisma/prisma/issues/2219 // enum ConfigurationRoleAccessType { // ADMIN // STAFF // } model AccessLevel { name String @id description String? role AccessLevelRole[] } model AccessLevelRole { id String @id @default(cuid()) accessLevel AccessLevel @relation(fields: [accessLevelId], references: [name]) accessLevelId String Configuration Configuration? @relation(fields: [configurationId], references: [id]) configurationId String? discordRole DiscordRole @relation(fields: [discordRoleId], references: [id]) discordRoleId String @unique } // Configuration of each Discord server for the frontend access controls model Configuration { /// ID of Discord server id String @id @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String roles AccessLevelRole[] githubOrganization String? guild Guild @relation(fields: [id], references: [id]) features ConfigurationFeature[] /// "default" server configuration for the instance, in our case this will be the "AWS Amplify" Discord server. This will be the default choice for the server switcher // isDefaultServer Boolean @default(false) } model ConfigurationFeature { id String @id @default(cuid()) configuration Configuration @relation(fields: [configurationId], references: [id]) configurationId String feature Feature @relation(fields: [featureCode], references: [code]) featureCode String /// whether the feature is enabled for this server enabled Boolean @default(true) @@unique([configurationId, featureCode]) } // general audit log model AuditLog { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt userId String action String data String } // rough feature flag implementation model Feature { // id String @id @default(cuid()) /// the code of the feature/integration (e.g. GITHUB) code String @id @unique type FeatureType @relation(fields: [featureTypeCode], references: [code]) name String description String configurations ConfigurationFeature[] inputs FeatureInputs[] featureTypeCode String } /// type of feature (e.g. INTEGRATION, COMMAND) model FeatureType { code String @id @unique features Feature[] } // inputs used to create features (e.g. GitHub OAuth App ID) model FeatureInputs { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt feature Feature @relation(fields: [featureCode], references: [code]) featureCode String name String secure Boolean @default(false) } // next-auth model Account { id String @id @default(cuid()) type String provider String providerAccountId String refresh_token String? access_token String? expires_at Int? refresh_token_expires_in Int? token_type String? scope String? id_token String? session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String discordUser DiscordUser? @@unique([provider, providerAccountId]) } // next-auth model Session { id String @id @default(cuid()) sessionToken String @unique userId String expires DateTime user User @relation(fields: [userId], references: [id], onDelete: Cascade) } // next-auth model User { id String @id @default(cuid()) name String? email String? @unique emailVerified DateTime? image String? accounts Account[] sessions Session[] // custom props to be added below } // next-auth model VerificationToken { identifier String token String @unique expires DateTime @@unique([identifier, token]) }