diff --git a/Dockerfile b/Dockerfile index 774fa47..9f405fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ WORKDIR /app ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 -RUN apk add --no-cache python3 make g++ +RUN apk add --no-cache python3 make g++ sqlite RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs diff --git a/prisma/generated/prisma/internal/class.ts b/prisma/generated/prisma/internal/class.ts index a2091e4..577b5fb 100644 --- a/prisma/generated/prisma/internal/class.ts +++ b/prisma/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.1.0", "engineVersion": "ab635e6b9d606fa5c8fb8b1a7f909c3c3c1c98ba", "activeProvider": "sqlite", - "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n password String\n username String @unique\n role Role @default(USER)\n score Int @default(0)\n level Int @default(1)\n hp Int @default(1000)\n maxHp Int @default(1000)\n xp Int @default(0)\n maxXp Int @default(5000)\n avatar String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n bio String?\n characterClass CharacterClass?\n eventFeedbacks EventFeedback[]\n eventRegistrations EventRegistration[]\n preferences UserPreferences?\n challengesAsChallenger Challenge[] @relation(\"Challenger\")\n challengesAsChallenged Challenge[] @relation(\"Challenged\")\n challengesAsAdmin Challenge[] @relation(\"AdminValidator\")\n challengesAsWinner Challenge[] @relation(\"ChallengeWinner\")\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n theme String? @default(\"default\")\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel Event {\n id String @id @default(cuid())\n date DateTime\n name String\n description String\n type EventType\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n feedbacks EventFeedback[]\n registrations EventRegistration[]\n\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n createdAt DateTime @default(now())\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel EventFeedback {\n id String @id @default(cuid())\n userId String\n eventId String\n rating Int\n comment String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel SitePreferences {\n id String @id @default(\"global\")\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n primaryColor String? @default(\"#0be4cc\")\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n ATELIER\n KATA\n PRESENTATION\n LEARNING_HOUR\n}\n\nenum CharacterClass {\n WARRIOR\n MAGE\n ROGUE\n RANGER\n PALADIN\n ENGINEER\n MERCHANT\n SCHOLAR\n BERSERKER\n NECROMANCER\n}\n\nenum ChallengeStatus {\n PENDING\n ACCEPTED\n COMPLETED\n REJECTED\n CANCELLED\n}\n\nmodel Challenge {\n id String @id @default(cuid())\n challengerId String // Joueur qui lance le défi\n challengedId String // Joueur qui reçoit le défi\n challenger User @relation(\"Challenger\", fields: [challengerId], references: [id], onDelete: Cascade)\n challenged User @relation(\"Challenged\", fields: [challengedId], references: [id], onDelete: Cascade)\n title String // Titre du défi\n description String // Description détaillée du défi\n pointsReward Int @default(100) // Points à gagner pour le gagnant\n status ChallengeStatus @default(PENDING)\n adminId String? // Admin qui valide le défi\n admin User? @relation(\"AdminValidator\", fields: [adminId], references: [id], onDelete: SetNull)\n adminComment String? // Commentaire de l'admin lors de la validation/rejet\n winnerId String? // ID du gagnant (challengerId ou challengedId)\n winner User? @relation(\"ChallengeWinner\", fields: [winnerId], references: [id], onDelete: SetNull)\n createdAt DateTime @default(now())\n acceptedAt DateTime? // Date d'acceptation du défi\n completedAt DateTime? // Date de validation par l'admin\n updatedAt DateTime @updatedAt\n\n @@index([challengerId])\n @@index([challengedId])\n @@index([status])\n @@index([adminId])\n}\n", + "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"./generated/prisma\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n password String\n username String @unique\n role Role @default(USER)\n score Int @default(0)\n level Int @default(1)\n hp Int @default(1000)\n maxHp Int @default(1000)\n xp Int @default(0)\n maxXp Int @default(5000)\n avatar String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n bio String?\n characterClass CharacterClass?\n eventFeedbacks EventFeedback[]\n eventRegistrations EventRegistration[]\n preferences UserPreferences?\n challengesAsChallenger Challenge[] @relation(\"Challenger\")\n challengesAsChallenged Challenge[] @relation(\"Challenged\")\n challengesAsAdmin Challenge[] @relation(\"AdminValidator\")\n challengesAsWinner Challenge[] @relation(\"ChallengeWinner\")\n\n @@index([score])\n @@index([email])\n}\n\nmodel UserPreferences {\n id String @id @default(cuid())\n userId String @unique\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n theme String? @default(\"default\")\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel Event {\n id String @id @default(cuid())\n date DateTime\n name String\n description String\n type EventType\n room String?\n time String?\n maxPlaces Int?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n feedbacks EventFeedback[]\n registrations EventRegistration[]\n\n @@index([date])\n}\n\nmodel EventRegistration {\n id String @id @default(cuid())\n userId String\n eventId String\n createdAt DateTime @default(now())\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel EventFeedback {\n id String @id @default(cuid())\n userId String\n eventId String\n rating Int\n comment String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([userId, eventId])\n @@index([userId])\n @@index([eventId])\n}\n\nmodel SitePreferences {\n id String @id @default(\"global\")\n homeBackground String?\n eventsBackground String?\n leaderboardBackground String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nenum Role {\n USER\n ADMIN\n}\n\nenum EventType {\n ATELIER\n KATA\n PRESENTATION\n LEARNING_HOUR\n}\n\nenum CharacterClass {\n WARRIOR\n MAGE\n ROGUE\n RANGER\n PALADIN\n ENGINEER\n MERCHANT\n SCHOLAR\n BERSERKER\n NECROMANCER\n}\n\nenum ChallengeStatus {\n PENDING\n ACCEPTED\n COMPLETED\n REJECTED\n CANCELLED\n}\n\nmodel Challenge {\n id String @id @default(cuid())\n challengerId String // Joueur qui lance le défi\n challengedId String // Joueur qui reçoit le défi\n challenger User @relation(\"Challenger\", fields: [challengerId], references: [id], onDelete: Cascade)\n challenged User @relation(\"Challenged\", fields: [challengedId], references: [id], onDelete: Cascade)\n title String // Titre du défi\n description String // Description détaillée du défi\n pointsReward Int @default(100) // Points à gagner pour le gagnant\n status ChallengeStatus @default(PENDING)\n adminId String? // Admin qui valide le défi\n admin User? @relation(\"AdminValidator\", fields: [adminId], references: [id], onDelete: SetNull)\n adminComment String? // Commentaire de l'admin lors de la validation/rejet\n winnerId String? // ID du gagnant (challengerId ou challengedId)\n winner User? @relation(\"ChallengeWinner\", fields: [winnerId], references: [id], onDelete: SetNull)\n createdAt DateTime @default(now())\n acceptedAt DateTime? // Date d'acceptation du défi\n completedAt DateTime? // Date de validation par l'admin\n updatedAt DateTime @updatedAt\n\n @@index([challengerId])\n @@index([challengedId])\n @@index([status])\n @@index([adminId])\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"username\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"Role\"},{\"name\":\"score\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"level\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"hp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxHp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"xp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxXp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"eventFeedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventFeedbackToUser\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"challengesAsChallenger\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenger\"},{\"name\":\"challengesAsChallenged\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenged\"},{\"name\":\"challengesAsAdmin\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"AdminValidator\"},{\"name\":\"challengesAsWinner\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"ChallengeWinner\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"theme\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"}],\"dbName\":null},\"Event\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"EventType\"},{\"name\":\"room\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"time\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"maxPlaces\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"feedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"registrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventToEventRegistration\"}],\"dbName\":null},\"EventRegistration\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"EventFeedback\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rating\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventFeedbackToUser\"}],\"dbName\":null},\"SitePreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"primaryColor\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"Challenge\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengedId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challenger\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenger\"},{\"name\":\"challenged\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenged\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"pointsReward\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ChallengeStatus\"},{\"name\":\"adminId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"admin\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AdminValidator\"},{\"name\":\"adminComment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winnerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winner\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ChallengeWinner\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"username\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"Role\"},{\"name\":\"score\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"level\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"hp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxHp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"xp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"maxXp\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"avatar\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterClass\",\"kind\":\"enum\",\"type\":\"CharacterClass\"},{\"name\":\"eventFeedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventFeedbackToUser\"},{\"name\":\"eventRegistrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventRegistrationToUser\"},{\"name\":\"preferences\",\"kind\":\"object\",\"type\":\"UserPreferences\",\"relationName\":\"UserToUserPreferences\"},{\"name\":\"challengesAsChallenger\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenger\"},{\"name\":\"challengesAsChallenged\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"Challenged\"},{\"name\":\"challengesAsAdmin\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"AdminValidator\"},{\"name\":\"challengesAsWinner\",\"kind\":\"object\",\"type\":\"Challenge\",\"relationName\":\"ChallengeWinner\"}],\"dbName\":null},\"UserPreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"theme\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToUserPreferences\"}],\"dbName\":null},\"Event\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"EventType\"},{\"name\":\"room\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"time\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"maxPlaces\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"feedbacks\",\"kind\":\"object\",\"type\":\"EventFeedback\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"registrations\",\"kind\":\"object\",\"type\":\"EventRegistration\",\"relationName\":\"EventToEventRegistration\"}],\"dbName\":null},\"EventRegistration\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventRegistration\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventRegistrationToUser\"}],\"dbName\":null},\"EventFeedback\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rating\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"event\",\"kind\":\"object\",\"type\":\"Event\",\"relationName\":\"EventToEventFeedback\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"EventFeedbackToUser\"}],\"dbName\":null},\"SitePreferences\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"homeBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"eventsBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"leaderboardBackground\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Challenge\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengedId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challenger\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenger\"},{\"name\":\"challenged\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"Challenged\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"pointsReward\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"ChallengeStatus\"},{\"name\":\"adminId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"admin\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AdminValidator\"},{\"name\":\"adminComment\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winnerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"winner\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ChallengeWinner\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') diff --git a/prisma/generated/prisma/internal/prismaNamespace.ts b/prisma/generated/prisma/internal/prismaNamespace.ts index aa9acb2..153ccf8 100644 --- a/prisma/generated/prisma/internal/prismaNamespace.ts +++ b/prisma/generated/prisma/internal/prismaNamespace.ts @@ -1045,8 +1045,7 @@ export const SitePreferencesScalarFieldEnum = { eventsBackground: 'eventsBackground', leaderboardBackground: 'leaderboardBackground', createdAt: 'createdAt', - updatedAt: 'updatedAt', - primaryColor: 'primaryColor' + updatedAt: 'updatedAt' } as const export type SitePreferencesScalarFieldEnum = (typeof SitePreferencesScalarFieldEnum)[keyof typeof SitePreferencesScalarFieldEnum] diff --git a/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts b/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts index bca0ad1..1c87e37 100644 --- a/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -154,8 +154,7 @@ export const SitePreferencesScalarFieldEnum = { eventsBackground: 'eventsBackground', leaderboardBackground: 'leaderboardBackground', createdAt: 'createdAt', - updatedAt: 'updatedAt', - primaryColor: 'primaryColor' + updatedAt: 'updatedAt' } as const export type SitePreferencesScalarFieldEnum = (typeof SitePreferencesScalarFieldEnum)[keyof typeof SitePreferencesScalarFieldEnum] diff --git a/prisma/generated/prisma/models/SitePreferences.ts b/prisma/generated/prisma/models/SitePreferences.ts index 761e1a6..6500669 100644 --- a/prisma/generated/prisma/models/SitePreferences.ts +++ b/prisma/generated/prisma/models/SitePreferences.ts @@ -31,7 +31,6 @@ export type SitePreferencesMinAggregateOutputType = { leaderboardBackground: string | null createdAt: Date | null updatedAt: Date | null - primaryColor: string | null } export type SitePreferencesMaxAggregateOutputType = { @@ -41,7 +40,6 @@ export type SitePreferencesMaxAggregateOutputType = { leaderboardBackground: string | null createdAt: Date | null updatedAt: Date | null - primaryColor: string | null } export type SitePreferencesCountAggregateOutputType = { @@ -51,7 +49,6 @@ export type SitePreferencesCountAggregateOutputType = { leaderboardBackground: number createdAt: number updatedAt: number - primaryColor: number _all: number } @@ -63,7 +60,6 @@ export type SitePreferencesMinAggregateInputType = { leaderboardBackground?: true createdAt?: true updatedAt?: true - primaryColor?: true } export type SitePreferencesMaxAggregateInputType = { @@ -73,7 +69,6 @@ export type SitePreferencesMaxAggregateInputType = { leaderboardBackground?: true createdAt?: true updatedAt?: true - primaryColor?: true } export type SitePreferencesCountAggregateInputType = { @@ -83,7 +78,6 @@ export type SitePreferencesCountAggregateInputType = { leaderboardBackground?: true createdAt?: true updatedAt?: true - primaryColor?: true _all?: true } @@ -166,7 +160,6 @@ export type SitePreferencesGroupByOutputType = { leaderboardBackground: string | null createdAt: Date updatedAt: Date - primaryColor: string | null _count: SitePreferencesCountAggregateOutputType | null _min: SitePreferencesMinAggregateOutputType | null _max: SitePreferencesMaxAggregateOutputType | null @@ -197,7 +190,6 @@ export type SitePreferencesWhereInput = { leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null createdAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string updatedAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string - primaryColor?: Prisma.StringNullableFilter<"SitePreferences"> | string | null } export type SitePreferencesOrderByWithRelationInput = { @@ -207,7 +199,6 @@ export type SitePreferencesOrderByWithRelationInput = { leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder - primaryColor?: Prisma.SortOrderInput | Prisma.SortOrder } export type SitePreferencesWhereUniqueInput = Prisma.AtLeast<{ @@ -220,7 +211,6 @@ export type SitePreferencesWhereUniqueInput = Prisma.AtLeast<{ leaderboardBackground?: Prisma.StringNullableFilter<"SitePreferences"> | string | null createdAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string updatedAt?: Prisma.DateTimeFilter<"SitePreferences"> | Date | string - primaryColor?: Prisma.StringNullableFilter<"SitePreferences"> | string | null }, "id"> export type SitePreferencesOrderByWithAggregationInput = { @@ -230,7 +220,6 @@ export type SitePreferencesOrderByWithAggregationInput = { leaderboardBackground?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder - primaryColor?: Prisma.SortOrderInput | Prisma.SortOrder _count?: Prisma.SitePreferencesCountOrderByAggregateInput _max?: Prisma.SitePreferencesMaxOrderByAggregateInput _min?: Prisma.SitePreferencesMinOrderByAggregateInput @@ -246,7 +235,6 @@ export type SitePreferencesScalarWhereWithAggregatesInput = { leaderboardBackground?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null createdAt?: Prisma.DateTimeWithAggregatesFilter<"SitePreferences"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"SitePreferences"> | Date | string - primaryColor?: Prisma.StringNullableWithAggregatesFilter<"SitePreferences"> | string | null } export type SitePreferencesCreateInput = { @@ -256,7 +244,6 @@ export type SitePreferencesCreateInput = { leaderboardBackground?: string | null createdAt?: Date | string updatedAt?: Date | string - primaryColor?: string | null } export type SitePreferencesUncheckedCreateInput = { @@ -266,7 +253,6 @@ export type SitePreferencesUncheckedCreateInput = { leaderboardBackground?: string | null createdAt?: Date | string updatedAt?: Date | string - primaryColor?: string | null } export type SitePreferencesUpdateInput = { @@ -276,7 +262,6 @@ export type SitePreferencesUpdateInput = { leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string - primaryColor?: Prisma.NullableStringFieldUpdateOperationsInput | string | null } export type SitePreferencesUncheckedUpdateInput = { @@ -286,7 +271,6 @@ export type SitePreferencesUncheckedUpdateInput = { leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string - primaryColor?: Prisma.NullableStringFieldUpdateOperationsInput | string | null } export type SitePreferencesCreateManyInput = { @@ -296,7 +280,6 @@ export type SitePreferencesCreateManyInput = { leaderboardBackground?: string | null createdAt?: Date | string updatedAt?: Date | string - primaryColor?: string | null } export type SitePreferencesUpdateManyMutationInput = { @@ -306,7 +289,6 @@ export type SitePreferencesUpdateManyMutationInput = { leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string - primaryColor?: Prisma.NullableStringFieldUpdateOperationsInput | string | null } export type SitePreferencesUncheckedUpdateManyInput = { @@ -316,7 +298,6 @@ export type SitePreferencesUncheckedUpdateManyInput = { leaderboardBackground?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string - primaryColor?: Prisma.NullableStringFieldUpdateOperationsInput | string | null } export type SitePreferencesCountOrderByAggregateInput = { @@ -326,7 +307,6 @@ export type SitePreferencesCountOrderByAggregateInput = { leaderboardBackground?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder - primaryColor?: Prisma.SortOrder } export type SitePreferencesMaxOrderByAggregateInput = { @@ -336,7 +316,6 @@ export type SitePreferencesMaxOrderByAggregateInput = { leaderboardBackground?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder - primaryColor?: Prisma.SortOrder } export type SitePreferencesMinOrderByAggregateInput = { @@ -346,7 +325,6 @@ export type SitePreferencesMinOrderByAggregateInput = { leaderboardBackground?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder - primaryColor?: Prisma.SortOrder } @@ -358,7 +336,6 @@ export type SitePreferencesSelect export type SitePreferencesSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -368,7 +345,6 @@ export type SitePreferencesSelectCreateManyAndReturn export type SitePreferencesSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -378,7 +354,6 @@ export type SitePreferencesSelectUpdateManyAndReturn export type SitePreferencesSelectScalar = { @@ -388,10 +363,9 @@ export type SitePreferencesSelectScalar = { leaderboardBackground?: boolean createdAt?: boolean updatedAt?: boolean - primaryColor?: boolean } -export type SitePreferencesOmit = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "createdAt" | "updatedAt" | "primaryColor", ExtArgs["result"]["sitePreferences"]> +export type SitePreferencesOmit = runtime.Types.Extensions.GetOmit<"id" | "homeBackground" | "eventsBackground" | "leaderboardBackground" | "createdAt" | "updatedAt", ExtArgs["result"]["sitePreferences"]> export type $SitePreferencesPayload = { name: "SitePreferences" @@ -403,7 +377,6 @@ export type $SitePreferencesPayload composites: {} } @@ -833,7 +806,6 @@ export interface SitePreferencesFieldRefs { readonly leaderboardBackground: Prisma.FieldRef<"SitePreferences", 'String'> readonly createdAt: Prisma.FieldRef<"SitePreferences", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"SitePreferences", 'DateTime'> - readonly primaryColor: Prisma.FieldRef<"SitePreferences", 'String'> } diff --git a/prisma/migrations/20251215170000_remove_primary_color/migration.sql b/prisma/migrations/20251215170000_remove_primary_color/migration.sql new file mode 100644 index 0000000..9b2e39a --- /dev/null +++ b/prisma/migrations/20251215170000_remove_primary_color/migration.sql @@ -0,0 +1,22 @@ +-- AlterTable +-- SQLite doesn't support DROP COLUMN directly, so we need to recreate the table +CREATE TABLE "SitePreferences_new" ( + "id" TEXT NOT NULL PRIMARY KEY, + "homeBackground" TEXT, + "eventsBackground" TEXT, + "leaderboardBackground" TEXT, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); + +-- Copy data without primaryColor column +INSERT INTO "SitePreferences_new" ("id", "homeBackground", "eventsBackground", "leaderboardBackground", "createdAt", "updatedAt") +SELECT "id", "homeBackground", "eventsBackground", "leaderboardBackground", "createdAt", "updatedAt" +FROM "SitePreferences"; + +-- Drop old table +DROP TABLE "SitePreferences"; + +-- Rename new table +ALTER TABLE "SitePreferences_new" RENAME TO "SitePreferences"; + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 78f6597..8f64f80 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -101,7 +101,6 @@ model SitePreferences { leaderboardBackground String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - primaryColor String? @default("#0be4cc") } enum Role { diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index b18299f..5086066 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -45,34 +45,65 @@ deploy_migrations() { echo "Resolving failed migration: $MIGRATION_NAME" - # Try to resolve as applied (migration might have partially succeeded) + # First, try the standard Prisma resolve command RESOLVE_OUTPUT=$(pnpm dlx prisma migrate resolve --applied "$MIGRATION_NAME" 2>&1) RESOLVE_EXIT=$? echo "$RESOLVE_OUTPUT" - if [ $RESOLVE_EXIT -eq 0 ]; then - echo "Migration resolved successfully, retrying deploy..." - # Retry migration deploy - if pnpm dlx prisma migrate deploy 2>&1; then - echo "Migrations deployed successfully after resolution" - return 0 - else - echo "Migration deploy still failed after resolution, but continuing..." - return 0 - fi - else - # Check if migration is already marked as applied - if echo "$RESOLVE_OUTPUT" | grep -q "already recorded as applied"; then - echo "Migration is already marked as applied, retrying deploy..." - pnpm dlx prisma migrate deploy 2>&1 || true - return 0 + # If Prisma resolve fails (e.g., migration files not found), resolve directly in database + if [ $RESOLVE_EXIT -ne 0 ]; then + if echo "$RESOLVE_OUTPUT" | grep -q "P3017\|could not be found"; then + echo "Migration files not found, resolving directly in database..." + + # Use sqlite3 to mark migration as applied directly in _prisma_migrations table + # Check if sqlite3 is available + if command -v sqlite3 >/dev/null 2>&1; then + # Extract database path from DATABASE_URL (format: file:/app/data/dev.db) + DB_PATH=$(echo "$DATABASE_URL" | sed 's|file:||') + if [ -z "$DB_PATH" ] || [ "$DB_PATH" = "$DATABASE_URL" ]; then + DB_PATH="/app/data/dev.db" + fi + + # Ensure database file exists + if [ ! -f "$DB_PATH" ]; then + echo "Database file not found at $DB_PATH" + else + echo "Updating migration status in database: $DB_PATH" + # Get current timestamp in milliseconds + TIMESTAMP=$(date +%s)000 + # Update the migration record + sqlite3 "$DB_PATH" "UPDATE _prisma_migrations SET finished_at = $TIMESTAMP, rolled_back_at = NULL WHERE migration_name = '$MIGRATION_NAME' AND finished_at IS NULL;" 2>&1 + + if [ $? -eq 0 ]; then + echo "Migration marked as applied in database" + # Verify the update + RESULT=$(sqlite3 "$DB_PATH" "SELECT migration_name, finished_at FROM _prisma_migrations WHERE migration_name = '$MIGRATION_NAME';" 2>&1) + echo "Migration status: $RESULT" + else + echo "Failed to update database directly" + fi + fi + else + echo "sqlite3 not available, cannot resolve directly in database" + echo "Install sqlite3 in Dockerfile: RUN apk add --no-cache sqlite" + fi + elif echo "$RESOLVE_OUTPUT" | grep -q "already recorded as applied"; then + echo "Migration is already marked as applied" else echo "Failed to resolve migration: $RESOLVE_OUTPUT" - echo "Continuing anyway - app might still work if migration was partially applied" - return 0 fi fi + + # Retry migration deploy after resolution attempt + echo "Retrying migration deploy..." + if pnpm dlx prisma migrate deploy 2>&1; then + echo "Migrations deployed successfully after resolution" + return 0 + else + echo "Migration deploy still failed after resolution, but continuing..." + return 0 + fi } # Deploy migrations (don't fail if it errors - app might still work)