Server: - quiz-round handles image_reveal like a text-answer format (tolerant match on acceptedAnswers), exposing imageUrl in the round payload; degressive scoring comes for free from the existing speed bonus (earlier = blurrier = more points) - repo includes image_reveal in the pool (requires imageUrl + acceptedAnswers) - back-office: image upload (@fastify/multipart) saved to UPLOADS_DIR and served statically on /uploads (@fastify/static); create supports image_reveal - env: UPLOADS_DIR; gitignore uploads/ Client: - admin form: "Image à deviner" — upload + preview + accepted answers - in-game: ImageReveal shows the image with a time-cadenced decreasing blur (synced via server timestamps) + text input; reveal shows the clear image and the answer shared: QuizQuestionPayload.imageUrl Verified against real server+DB: upload (url), static serve (200), create (201), validation (400). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
26 lines
1.1 KiB
TypeScript
26 lines
1.1 KiB
TypeScript
// Configuration lue depuis l'environnement. Bun charge .env automatiquement.
|
|
// Secrets (YouTube, DB) viendront s'ajouter ici — jamais en dur.
|
|
|
|
function num(value: string | undefined, fallback: number): number {
|
|
const parsed = Number(value)
|
|
return Number.isFinite(parsed) ? parsed : fallback
|
|
}
|
|
|
|
export const env = {
|
|
nodeEnv: process.env.NODE_ENV ?? "development",
|
|
host: process.env.HOST ?? "0.0.0.0",
|
|
port: num(process.env.PORT, 3001),
|
|
/** Connexion PostgreSQL. Vide → pas de DB, fallback banque en dur. */
|
|
databaseUrl: process.env.DATABASE_URL ?? "",
|
|
/** Jeton du back-office quiz. Vide → back-office désactivé. */
|
|
adminToken: process.env.ADMIN_TOKEN ?? "",
|
|
/** Dossier de stockage des images (image_reveal), servi en statique sur /uploads. */
|
|
uploadsDir: process.env.UPLOADS_DIR ?? "./uploads",
|
|
/** Origines autorisées pour CORS / Socket.IO (séparées par des virgules). */
|
|
corsOrigins: (process.env.CORS_ORIGINS ?? "http://localhost:5173")
|
|
.split(",")
|
|
.map((o) => o.trim())
|
|
.filter(Boolean),
|
|
}
|
|
|
|
export const isDev = env.nodeEnv !== "production"
|