Plateforme web de commande et gestion de pizzas itinérantes.
Stack
- Front : Vite + React + Tailwind
- Back : Firebase Auth + Realtime Database (RTDB) + Cloud Functions
- Paiement : Stripe Checkout (validation réelle via webhook)
- Aucun secret Stripe côté front (jamais de
sk_...niwhsec_...). - Le front n’écrit jamais un statut
paid: seulstripeWebhook(Functions) le fait après vérif de signature. - Les prix sont toujours en cents (int) dans la data.
- Le détail camion doit marcher par clé RTDB ou par slug (ex :
/TEST_04_01).
- Setup / env / Firebase / Stripe :
SETUP.md - Filet anti-régression :
CHECKLIST_SMOKE_TEST.md
- Installer les dépendances (front + functions)
npm installnpm --prefix functions install
- Créer
.env.localdepuis.env.examplepuis renseigner :
VITE_FIREBASE_*- RTDB :
VITE_FIREBASE_DATABASE_URL(obligatoire) VITE_STRIPE_PUBLISHABLE_KEY- (Optionnel)
VITE_FUNCTIONS_ORIGINsi vos Functions ne sont pas enus-central1
- Lancer le front
npm run dev
- (Optionnel) Lancer les émulateurs Firebase
npm run firebase:emulators
Tout le détail (Firebase Console + CLI + secrets Stripe) est dans
SETUP.md.
Les routes sont centralisées dans src/app/routes.jsx.
| Fonction | Route |
|---|---|
| Explore (public) | /explore |
| Panier (public) | /panier |
| Checkout (public UI, auth requise au paiement) | /checkout |
| Success checkout | /checkout/success |
| Tracking commande | /order/:orderId |
| Détail camion (slug ou id RTDB) | /:truckId |
| Pro (pizzaiolo) | /pro/* (ex: /pro/menu, /pro/live) |
Routes legacy compatibles : /truck/:truckId, /t/:truckId, /trucks/:truckId.
Paths principaux :
public/trucks/{truckId}
public/trucks/{truckId}/menu/items
orders/{orderId}
truckOrders/{truckId}/{orderId} = true
pizzaiolos/{uid}/truckId
Notes importantes :
- Les camions sont stockés sous une clé RTDB (ex :
-Oi6p2NbOfSJ2gI3atRg). - Le champ
slug(ex :TEST_04_01) est utilisé pour la route/:truckId. - Dans certains jeux de données,
idpeut êtrenullen base : côté front, l’ID canonique est la clé RTDB.
Le front appelle une Function HTTP createCheckoutSession en envoyant :
Authorization: Bearer <Firebase ID token>orderIden body
La Function :
- reconstruit les line items côté serveur
- crée la session Stripe Checkout
- écrit
paymentStatus = "pending"+sessionIdsur la commande
Le webhook stripeWebhook :
- vérifie la signature Stripe
- sur
checkout.session.completed: écritpaymentStatus = "paid"etstatus = "received"
Important : le workflow d’avancement des statuts est manuel côté pizzaiolo (les anciennes transitions automatiques sont désactivées).
src/app/: router, guards, providerssrc/pages/: pages (orchestrateurs)src/features/: logique métier (hooks/utils/components) réutilisable
Le gros de la logique d’édition menu a été sorti de la page :
- Hook d’édition :
src/features/menu/hooks/usePizzaioloMenuEditor.js - Draft UI/state :
src/features/menu/hooks/pizzaiolo/usePizzaioloMenuDraft.js - Builder payload RTDB :
src/features/menu/utils/buildMenuItemData.js - UI découpée :
src/features/menu/components/pizzaiolo/*(barrel export)
-
Loader infini sur une page camion
- Vérifier que RTDB a un index sur
slug(voirdatabase.rules.json). - Vérifier
VITE_FIREBASE_DATABASE_URL. - La route canon est
/:truckId(slug ou clé).
- Vérifier que RTDB a un index sur
-
Checkout appelle la mauvaise région
- Par défaut, le front cible
https://us-central1-<PROJECT_ID>.cloudfunctions.net. - Si vous déployez vos Functions ailleurs, définir
VITE_FUNCTIONS_ORIGINdans.env.local.
- Par défaut, le front cible
npm run dev: dev servernpm run build: build prodnpm run lint: eslintnpm run firebase:emulators: émulateursnpm run firebase:deploy: build + deploy
- Ne jamais commiter
.env*(sauf.env.example). - Front : uniquement
VITE_STRIPE_PUBLISHABLE_KEY. - Back (Functions) : secrets Stripe via Secrets Manager.
- Vite : https://vite.dev/
- Firebase (Auth, RTDB, Functions) : https://firebase.google.com/docs
- Stripe Checkout + webhooks : https://stripe.com/docs