# Wakdo — Project Context **Source de verite du projet.** Ce document est injecte comme contexte dans tous les agents BYAN utilises pour ce projet (expert-merise-agile, architect, dev, ux-designer, tea, quinn, etc.). Il doit etre mis a jour des qu'une decision structurante change. --- ## 1. Identite projet | Champ | Valeur | |---|---| | Nom du projet | **Wakdo** — borne de commande fictive (pastiche McDonald's) | | Auteur | Corentin | | Cadre | Epreuve RNCP 37805 — Titre Developpeur Web, B2, option **DevOps** | | Centre | Acadenice | | Contexte pro | Alternance en tant qu'admin sys + etudiant B2 DevOps | | Deadline soutenance | **Septembre 2026** | | Budget heures | 10-15 h/semaine — cible ~240 h effectives | | Mode de travail | Solo | | Date de creation du doc | 2026-04-23 | --- ## 2. Contexte metier Wakdo est une **borne de commande tactile** pour un restaurant de restauration rapide. L'utilisateur final (client) compose sa commande sur ecran tactile, valide, recupere un numero, puis retire son produit au comptoir. ### Acteurs | Acteur | Role | Interface | |---|---|---| | **Client** | Passe sa commande sur la borne | Borne tactile (Bloc 1) | | **Accueil** | Saisit commandes au **comptoir** (client au guichet) ou au **drive** (client en voiture via intercom + casque equipier), remet les commandes livrees aux clients | Back-office (Bloc 2) | | **Preparation** | Voit les commandes a preparer triees par heure croissante, les declare "preparees" | Back-office (Bloc 2) | | **Administration** | CRUD sur donnees (produits, menus, prix, images) + gestion utilisateurs + stats | Back-office (Bloc 2) | ### Processus metier cle ``` Client Borne (Bloc 1) API (Bloc 2) BDD │ │ │ │ │─compose panier──────▶│ │ │ │ │─GET menus,produits───▶│───SELECT──────────▶│ │ │◀──────────JSON────────│◀───────────────────│ │─valide────────────────│ │ │ │─saisit numero─────────│ │ │ │ │─POST /api/orders─────▶│───INSERT──────────▶│ │ │◀──────────201─────────│ │ │─recupere au comptoir │ │ │ Preparation voit commande pending → declare "preparee" Accueil voit commande prete → declare "livree" ``` ### Regles metier (MCT - a modeliser en Merise) - Un **menu** = burger + accompagnement (frites OU salade) + boisson + sauce - Les **accompagnements** et **boissons** ont **2 tailles** (normale / grande) - **Grande taille** = +0,50 € sur le prix de base - Une **commande** a un **numero** saisi par le client (remplace le paiement dans le cadre de l'exam) - Statuts commande : `pending` -> `preparing` -> `ready` -> `delivered` (ou `cancelled`) - **Source commande** (trace sur chaque commande) : `kiosk` (borne autonome) | `counter` (comptoir) | `drive` (drive-thru) - La preparation voit les commandes triees par **heure de livraison croissante** (tous canaux confondus) - **Horaires service** : 10h00 → 01h00 du matin (service continu 15h, pas de fermeture intermediaire) - **Pas de notion de "session de service" a modeliser** : les equipiers se relaient, chacun se connecte a sa prise de poste et se deconnecte a la fin. Pas de "shift" a tracer dans la BDD (hors scope RNCP) - **Fenetre de maintenance systeme** : 01h30 → 09h30 (crons lourds, backups, agregations) — evite toute interference avec le service actif - **Notion de "jour de service"** (important pour les stats et l'agregation) : - Un jour de service J = toutes les commandes creees entre **J 10h00** et **J+1 01h00** - Exemple : la soiree du 22/04 = commandes `22/04 10:00 → 23/04 01:00`, regroupees sous `service_day = 2026-04-22` - Une commande creee a 23h55 le 22/04 et livree a 00h30 le 23/04 appartient au meme jour de service (22/04) - **Implementation** : colonne `service_day` calculee sur la table `orders`, ou vue SQL : ```sql service_day = CASE WHEN HOUR(created_at) < 10 THEN DATE(created_at - INTERVAL 1 DAY) ELSE DATE(created_at) END ``` - Les requetes de stats (CA jour, produits top, etc.) utilisent `service_day` et non `DATE(created_at)` brut --- ## 3. Contexte academique — RNCP 37805 **Referentiel** : [certifpro.francecompetences.fr](https://certifpro.francecompetences.fr/api/fiches/refActivity/24345/472313) ### Blocs couverts | Bloc | Nom | Statut | Activites | |---|---|---|---| | **Bloc 1** | Developpement Front-End | Tronc commun obligatoire | A1 (integration), A2 (fonctionnalites JS) | | **Bloc 2** | Developpement Back-End | Tronc commun obligatoire | A3 (data/BDD), A4 (back-end) | | **Bloc 5** | DevOps (option 3) | Option choisie | A7 (automatisation + conteneurisation + CI/CD) | ### Validation - **50 % minimum par bloc** pour le valider - **50 % moyenne globale** pour valider le titre - **Stage** = 20 % de la note finale (couvert par l'alternance) - **Controle continu** 30 % + **Examens jurys** 50 % --- ## 4. Strategie de projet ### Strategie B — unifiee **Un seul codebase, deux FQDN d'exposition publique.** Le front Bloc 1 et le back Bloc 2 coexistent dans la meme arborescence. Une bascule mode JSON-seuls (Bloc 1 isole) vs mode API-connecte doit rester possible via configuration. **Pourquoi pas strategie A (deux rendus isoles)** : le Bloc 5 DevOps impose une conteneurisation **unique** qui lance la stack complete avec `make init` en une commande (Cr 7.c.4). Deux codebases isolees seraient incoherentes avec cette exigence. ### Compatibilite evaluation par bloc - **Jury Bloc 1** : voit le front seul ; le front peut tomber en fallback sur JSON statiques fournis (`src/public/borne/data/*.json`) si l'API est indisponible. - **Jury Bloc 2** : voit le back-office + teste l'API via curl/Postman de maniere autonome, sans dependre du front. - **Jury Bloc 5** : lance `make init` ou `docker compose up`, verifie la CI/CD, les crons, l'archi, les scripts. --- ## 5. Architecture ### 2 FQDN exposes | FQDN | Role | Bloc | Auth | |---|---|---|---| | `corentin-wakdo.acadenice.fr` | Borne client (kiosk tactile) | Bloc 1 | Public | | `corentin-wakdo-admin.acadenice.fr` | Back-office + API REST (sous `/api/*`) | Bloc 2 | Sessions (back-office) + tokens (API ecriture) | **CORS** : la borne (`corentin-wakdo.acadenice.fr`) consomme l'API (`corentin-wakdo-admin.acadenice.fr/api/*`). Headers CORS explicites avec origine precise (pas de wildcard `*`), argumentable comme durcissement securite face au jury. ### Services Docker ``` ┌─────────────────────────────────────────────────────────────────┐ │ Traefik (existant) │ │ (admin_proxy network) │ └──────────┬────────────────────────────┬─────────────────────────┘ │ │ wakdo.acadenice.fr wakdo-admin.acadenice.fr │ │ ▼ ▼ ┌──────────────────────────────────────────┐ │ wakdo-web (Apache Alpine) │ │ Front controller + reverse vers FPM │ └──────────┬───────────────────────────────┘ │ FastCGI :9000 ▼ ┌──────────────────────────────────────────┐ │ wakdo-app (PHP 8.3-fpm Alpine) │ │ POO MVC — borne.php, admin.php, api.php │ └──────────┬───────────────────────────────┘ │ PDO MySQL ▼ ┌──────────────────────────────────────────┐ │ wakdo-db (MariaDB 11) │ │ volume persistant │ └──────────────────────────────────────────┘ ┌──────────────────────────────────────────┐ │ wakdo-cron (Alpine + PHP CLI) │ │ crond — backup BDD, purge sessions, ... │ └──────────────────────────────────────────┘ ``` Reseaux : - `admin_proxy` (external) — expose `wakdo-web` a Traefik - `wakdo_internal` (bridge, interne) — isole `wakdo-app`, `wakdo-db`, `wakdo-cron` --- ## 6. Stack technique lockee | Couche | Choix | Version | Raison | |---|---|---|---| | Front langages | HTML5 + CSS3 + JavaScript | Standards 2024+ | Exigence Bloc 1 (vanilla) | | Front framework | **Aucun** | — | Sujet Bloc 1 impose | | Front dep JS | **Aucune** | — | Exigence explicite | | Back langage | PHP | **8.3** LTS | Moderne, support jusqu'a 2027 | | Back framework | **Aucun** | — | Sujet Bloc 2 "from scratch" | | Autoloader | **Manuel** (spl_autoload_register, PSR-4) | — | Defend "from scratch", Cr 4.c.3 compatible | | Tests | **PHPUnit** via `.phar` autonome | 11.x | Cr 4.g.2 sans Composer | | Composer | **Non utilise** | — | Colle au "from scratch" | | BDD | MariaDB | **11** LTS | Compatible MySQL, LTS 2028 | | Driver BDD | PDO (prepared statements uniquement) | natif PHP | Cr 4.e.1 anti-injection | | Serveur web | Apache httpd | Alpine latest | Reverse proxy vers PHP-FPM | | Serveur app | PHP-FPM | 8.3-fpm-alpine | Contenairisation propre | | Reverse proxy | Traefik (deja en place) | existant | `admin_proxy` network | | TLS | Let's Encrypt via Traefik | auto | `acme.json` existant | | Conteneurisation | Docker + docker compose | v2 | Cr 7.c | | Orchestration locale | Makefile | — | Cr 7.b (script) + Cr 7.c.4 (une commande) | | CI/CD | GitHub Actions | — | Cr 7.d | | Versioning | Git + GitHub | — | Cr 4.f (collaboration) | | Hooks Git | pre-commit + commit-msg | versionnes dans `.githooks/` | Conventional Commits | --- ## 7. Scope fonctionnel ### Bloc 1 — Borne client (Front) **IN scope :** - Affichage dynamique menus + produits (charges par Ajax depuis API ou JSON fallback) - Composition panier : produits unitaires OU menus (burger + accompagnement + boisson + sauce) - Options taille (normale / grande, +0,50 € sur grande) pour accompagnements et boissons - Options de personnalisation simples (ex : sans oignon, avec fromage) - Recapitulatif panier (ajout, modification quantite, suppression) - Validation commande + saisie numero (remplace paiement) - Envoi POST JSON de la commande vers l'API - Ecran de confirmation avec numero - Responsive cible 1920x1080 portrait (borne) **+ adaptatif** autres resolutions - **Accessibilite RGAA** : police OpenDys pour dyslexiques, navigation clavier, contrastes, alts, pas d'info via couleur seule - **SEO / semantique** : balises HTML5 (`article`, `aside`, `nav`), schema.org, meta tags uniques, canonical, favicon **OUT scope :** - Paiement reel (remplace par numero de commande) - Authentification client (pas de compte fidelite) - Multi-langue (FR uniquement) - Offline mode ### Bloc 2 — Back-office + API (Back) **IN scope — Back-office :** - Authentification sessions securisees (hash bcrypt/argon2, protection CSRF, fixation session) — duree de session adaptee a un poste complet d'equipier (idle timeout 4h, absolute timeout 10h) - 3 roles RBAC : `admin`, `preparation`, `accueil` - **Admin** : CRUD categories, produits (nom, description, prix, image, dispo), menus (composition + options), utilisateurs - **Preparation** : liste commandes a preparer triees par heure livraison croissante, bouton "declarer preparee" - **Accueil** : saisir commande manuellement (comptoir ou drive-thru via casque/intercom), bouton "declarer livree" ; champ `source` enregistre sur chaque commande (`counter` ou `drive`) - Upload images produits (validation type MIME + taille + stockage dans volume `wakdo_uploads`) - Historique commandes par statut - Stats de base (commandes du jour, CA jour, produits top) **IN scope — API REST :** - `GET /api/categories` — liste categories produits - `GET /api/products` — liste produits (filtrable par categorie) - `GET /api/menus` — liste menus avec compositions et options - `POST /api/orders` — creer une commande (body JSON, retour `{id, number, status}`) - `GET /api/orders/{number}` — recuperer statut commande - Headers CORS explicites pour l'origine borne - Reponses JSON standardisees : `{data: ..., error: null}` ou `{data: null, error: {code, message}}` **IN scope — Transverse :** - Architecture **MVC** stricte (Models / Views / Controllers) - **Heritage** entre classes (ex : `BaseController` -> `AdminController` -> `ProductController`) - **Namespaces** + autoloader PSR-4 manuel - **Anti-injection** : PDO prepared statements exclusivement - **RGPD** : hash mdp, droit consultation/modif/suppr user, info stockage/utilisation donnees **OUT scope :** - Paiement reel, systeme comptable - Multi-restaurants / multi-bornes - Fidelite client - Rapports avances / exports CSV ### Bloc 5 — DevOps **IN scope :** - Dockerfile custom PHP-FPM avec extensions - `docker-compose.yml` orchestrant les 4 services (web, app, db, cron) - `Makefile` avec cible `make init` qui lance tout en une commande (Cr 7.c.4) - Scripts Bash d'automatisation (backup, deploy, migrate) - **Cron tab** avec au moins 3 jobs planifies dans la fenetre de maintenance (01h30-09h30) : - `0 3 * * *` — backup BDD quotidien a 03h00 (entre fin service 01h et ouverture 10h) - `*/15 * * * *` — purge sessions expirees toutes les 15 min (leger, peut tourner en service) - `30 4 * * *` — agregation stats commandes a 04h30 sur le **jour de service** ecoule (10h J-1 → 01h J) - **CI GitHub Actions** : lint PHP + PHPUnit sur PR -> dev - **CD GitHub Actions** : deploy auto sur merge main (SSH + pull + `make rebuild`) - `.env.example` documente, secrets hors du repo - Healthcheck Traefik + readiness probes - Logs centralises (stdout des conteneurs) - Documentation deploiement + architecture (schemas dans `docs/`) **OUT scope :** - Kubernetes / Swarm - Monitoring complet type Prometheus/Grafana (trop chronophage) - Multi-environnements (pre-prod, staging) - Blue-green deployment --- ## 8. Criteres RNCP — mapping feature ### Bloc 1 | Critere | Libelle court | Feature Wakdo couvrant | |---|---|---| | Cr 1.a.1 | Integration conforme maquette | Integration HTML/CSS fidele au prototype | | Cr 1.a.2 | Normes W3C + accessibilite | Validator W3C vert + RGAA | | Cr 1.a.3 | Tests validator passent | Test en soutenance via W3C validator | | Cr 1.a.4 | Code commente, indente | Conventions de code appliquees partout | | Cr 1.a.5 | Balises semantiques | `
`, `