# Gaufrement Bon — site vitrine Site vitrine et back-office pour **Gaufrement Bon** (gaufres artisanales à Bagnols-sur-Cèze) : page d’accueil, carte des gaufres, galerie photo, contenus éditables, et interface d’administration. ## Fonctionnalités - **Site public** : hero, menu par catégories (sucrées, salées, du mois), galerie, avis Google (synchronisés en base), horaires et contact. - **Administration** (`/admin`) : connexion par session, gestion du menu, de la galerie et des textes / images du site. - **Upload d’images** : redimensionnement via Sharp, stockage dans `public/uploads/`. - **Base SQLite** : Prisma 7, migrations versionnées, seed au premier démarrage Docker. ## Stack - [Next.js 15](https://nextjs.org) (App Router, Turbopack, sortie `standalone`) - React 19, Tailwind CSS 4 - Prisma + SQLite (`better-sqlite3`) - Auth JWT en cookie (`jose`), rate limiting (mémoire ou [Upstash Redis](https://upstash.com)) ## Prérequis - Node.js 22+ - npm ## Développement local ```bash npm install npx prisma migrate deploy # crée dev.db si besoin npm run db:seed # optionnel : données de démo + compte admin npm run dev ``` Ouvrir [http://localhost:3000](http://localhost:3000). L’admin est sur [http://localhost:3000/admin](http://localhost:3000/admin). Sans fichier `.env`, les valeurs par défaut suivantes s’appliquent : | Variable | Défaut local | |----------|----------------| | `DATABASE_URL` | `file:./dev.db` | | `AUTH_SECRET` | secret de dev (à changer en prod) | | `ADMIN_EMAIL` | `admin@lagaufredor.local` | | `ADMIN_PASSWORD` | `changeme123` | | `GOOGLE_PLACES_API_KEY` | *(aucun — section avis masquée)* | | `GOOGLE_PLACE_ID` | ID par défaut dans `src/lib/constants.ts` | Exemple `.env` : ```env DATABASE_URL="file:./dev.db" AUTH_SECRET="remplacer-par-une-longue-chaine-aleatoire" ADMIN_EMAIL="admin@example.com" ADMIN_PASSWORD="mot-de-passe-fort" # Optionnel — avis Google Maps (Places API New) # GOOGLE_PLACES_API_KEY= # GOOGLE_PLACE_ID=ChIJN_OqSb2ltRIRhA21X2loXQI # Optionnel — rate limiting distribué # UPSTASH_REDIS_REST_URL= # UPSTASH_REDIS_REST_TOKEN= ``` ## Scripts npm | Commande | Description | |----------|-------------| | `npm run dev` | Serveur de dev (port 3000) | | `npm run build` | Build production (migrations + generate Prisma) | | `npm run start` | Serveur Next en production | | `npm run db:seed` | Seed manuel (menu, galerie, contenus, admin) | | `npm run lint` | ESLint | ## Docker Image publiée : `foufure/gauffre:latest`. ### Compose local (build + run) ```bash export AUTH_SECRET="$(openssl rand -base64 32)" docker compose up -d --build ``` Application sur [http://localhost:3007](http://localhost:3007) (port hôte `3007` → conteneur `3000`). Volumes : base SQLite (`gauffre-data`) et fichiers uploadés (`gauffre-uploads`). ### Déploiement serveur Fichier dédié : `docker-compose.server.yml` (HTTPS assuré par Nginx + Certbot sur l’hôte). ```bash export AUTH_SECRET="$(openssl rand -base64 32)" export ADMIN_EMAIL="admin@example.com" export ADMIN_PASSWORD="mot-de-passe-fort" docker compose -f docker-compose.server.yml up -d ``` Exemple de proxy Nginx : `proxy_pass http://127.0.0.1:3007;` Port hôte configurable via `HOST_PORT` (défaut `3007`). Au démarrage du conteneur, `docker/entrypoint.sh` exécute les migrations Prisma et le seed, puis lance `node server.js`. ### Publier l’image sur Docker Hub ```bash docker login ./scripts/docker-hub-push.sh # tag latest ./scripts/docker-hub-push.sh v1.0.0 # tag personnalisé ``` Variables optionnelles : `DOCKER_USER` (défaut `foufure`), `IMAGE_NAME` (défaut `gauffre`). ## Structure (aperçu) ``` src/app/ # Pages et routes API (public + /admin) src/components/site/ # UI vitrine src/components/admin/ # UI back-office src/lib/ # Prisma, auth, uploads, contenus prisma/ # Schéma, migrations, seed public/gallery/ # Images statiques par défaut public/uploads/ # Images uploadées (persistées en Docker) docker/ # Entrypoint conteneur ``` ## Sécurité en production - Définir un `AUTH_SECRET` long et aléatoire (`openssl rand -base64 32`). - Changer `ADMIN_EMAIL` et `ADMIN_PASSWORD` avant le premier seed, ou créer l’admin puis modifier le mot de passe. - Servir le site derrière HTTPS (Nginx ou équivalent). - Configurer Upstash si plusieurs instances partagent le rate limiting. - Pour afficher les avis Google sous la galerie : activer la [Places API (New)](https://developers.google.com/maps/documentation/places/web-service/overview) sur un projet Google Cloud, créer une clé API, et définir `GOOGLE_PLACES_API_KEY`. L’ID de lieu (`GOOGLE_PLACE_ID`) est préconfiguré pour Gaufrement Bon ; vérifiez-le avec l’[outil Place ID](https://developers.google.com/maps/documentation/javascript/place-id) si besoin. ## Licence Projet privé.