94 KiB
Executable file
Session Resume — Wakdo
Document de reprise entre sessions de travail. A consulter en premier quand tu reprends le projet.
Derniere session : 2026-06-19 — Fix borne same-origin + GOAL re-alignement maquette (P5 front) + reste P4
Auteur : BYAN. Session marathon. Depart : le user a constate que la borne « n'etait
pas cablee » (clic produit sans effet). Diagnostic prouve sur la vraie stack, puis un
cycle FD complet (borne-realign-maquette, COMPLETED) + un /goal de 8 items livres en
autonomie, chacun en PR auto-merge sur CI verte.
1. Fix borne same-origin (PR #62)
data.js faisait des fetch('/api/*') RELATIFS -> resolus sur l'origine borne
(corentin-wakdo.stark.a3n.fr) ou il n'y a pas d'API -> fallback SPA index.html (HTML,
pas JSON) -> catalogue vide. Le middleware CORS de #61 n'etait donc pas sollicite.
Decision (secu + conventions) : SAME-ORIGIN. Le vhost kiosk relaie /api/* vers PHP-FPM
(ProxyPassMatch + ProxyFCGISetEnvIf qui force SCRIPT_FILENAME sur admin/index.php,
sinon FPM rejette via security.limit_extensions). CORS conserve en defense. conventions.md §10 reecrit.
2. Decomposition maquette (PR #63)
maquette-borne.pdf decompose : 10 ecrans en PNG (docs/design/screens/) + docs/design/ maquette-vs-build.md (mapping maquette<->build : la maquette est mono-ecran avec panneau persistant, le build etait multi-pages).
3. GOAL — 8 items livres (PR #64-#71)
- #64 L1 : panneau commande persistant + bandeau categories + charte.
- #65 L2 : composeur menu SLOT-DRIVEN /api/menus (remplace la compo libre ; ferme dette P4 #3).
- #66 L3 : modale options produit (remplace la page product.html ; grille -> modales).
- #67 seed : recettes des 53 produits (db/seeds/0003_ingredients_recipes.sql, 50 ingredients) -> stock vivant.
- #68 L4 : SOUMISSION REELLE de commande (checkout.js panier->/api/orders create+pay) + ecran chevalet. Avant : checkout 100% simule.
- #69 cleanup : memoisation des loaders data.js (promesse) + contraste a11y selection.
- #70 orders admin : /admin/orders (order.read) + KPIs vente dans /admin/stats (OrderQueryRepository).
- #71 /api/allergens : endpoint public (id/code/name) ; la borne garde son JSON statique (descriptions). Item 0 = gate CI js-tests requis (dev+main).
Decouvertes corrigees
- La borne ne soumettait aucune commande (payment.html simulait) -> soumission reelle cablee.
- Migration 0003_order_service_tag.sql non appliquee sur la stack dev (3 j d'uptime) -> la creation de commande echouait (Unknown column service_tag). Reconciliee dans schema_migrations ; doublon de migration ecarte (catch d'une revue adversariale).
- Incident compose (reseau recree) :
wakdo-webrecree viadocker compose -f docker-compose.prod.yml up -d --no-deps --force-recreate(la stack tourne via prod.yml + Traefik reseauadmin_proxy).
Verification
351 tests PHP (unit + integration DB) + 64 JS, PHPStan L6 propre. e2e reel : commande K1 creee + payee, stock decremente exactement (-5 Steak hache). Chaque lot a eu une revue adversariale par workflow (must-fix integres).
Nettoyage git (fin de session)
Branches purgees : local + forge = dev + main seulement (17 branches feature mergees
supprimees cote forge, 6 locales). dev = 7ab9a5a (#71).
EN COURS — accompagnement menu Frite/Potatoes + Maxi (approuve, NON code)
Le user a constate que le composeur menu propose les 5 produits frites (Petite/Moyenne/ Grande Frite + Potatoes/Grande Potatoes) comme accompagnement. Regle voulue (et conforme maquette ecran 4 : 2 choix Frites/Potatoes) :
- Menu = 2 choix d'accompagnement : Frites (Moyenne Frite) + Potatoes.
- Maxi -> version Grande associee automatiquement (Grande Frite / Grande Potatoes).
- Petite Frite + tailles individuelles = a la carte seulement (section frites), hors menu.
Approche choisie par le user : variante en base (data-driven, le stock decremente le bon produit). Plan a executer (TDD + revue + commit/PR/auto-merge) :
- Migration
db/migrations/0004_product_maxi_variant.sql:ALTER TABLE product ADD COLUMN maxi_variant_product_id INT UNSIGNED NULL+ FK -> product(id). A appliquer sur dev. - Seed
db/seeds/0004_menu_side_maxi.sql(idempotent) :UPDATE product SET maxi_variant_product_id=24 WHERE name='Moyenne Frite'(24 = Grande Frite) ;=26 WHERE name='Potatoes'(26 = Grande Potatoes).DELETEdes options de slotsidepour ne garder que Moyenne Frite (23) + Potatoes (25) ; retirer Petite Frite (22), Grande Frite (24), Grande Potatoes (26) des options menu.
ProductRepository::find(src/app/Catalogue/ProductRepository.php:50) : ajoutermaxi_variant_product_idaux colonnes du SELECT (absent aujourd'hui).OrderRepository::resolveSelections(src/app/Order/OrderRepository.php:395) : passer leformat; valider la selection BASE contre les options du slot, puis si format='maxi' ET le produit a un maxi_variant non nul -> STOCKER l'id de la variante (label de la variante).consumption()decremente alors la Grande variante (stock correct).resolveLine(qui connait le format) passe$formataresolveSelections.- Tests : OrderRepository DbTest (menu Maxi + accompagnement -> selection stockee = Grande variante + stock decremente Grande Frite, pas Moyenne) ; unit du swap dans resolveSelections.
- Borne : le composeur affiche 2 options automatiquement (slots /api/menus restreints par le seed) -> pas de code borne. Afficher le libelle Maxi au recap = optionnel, differable.
Ids frites (dev) : Petite 22, Moyenne 23, Grande 24, Potatoes 25, Grande Potatoes 26.
Reste / a faire
- VALIDATION VISUELLE utilisateur sur ecran reel (gros changement front, pas encore vu en vrai).
- Differes (LOW, notes) : format menu deduit de supplement_cents (theorique, seed +150) ; multi-slots de meme slot_type (menus famille) ; descriptions allergenes cote schema si on veut basculer la borne sur /api/allergens.
- Donnees demo : commande de test K1 en base dev (stock -5, sans impact).
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo && git merge --ff-only forgejo/dev
git log --oneline -12 dev # #62 fix borne ... #71 allergens
docker compose ps # stack dev (prod.yml + Traefik)
Session : 2026-06-18 (suite 2) — P4 read API borne (#60) + cablage CORS/data.js (#61)
Auteur : BYAN. Deux cycles FD menes en entier (BRAINSTORM -> PRUNE -> DISPATCH -> BUILD -> VALIDATE), chacun livre en PR auto-merge sur CI verte. But : brancher la borne kiosk sur le catalogue en base, a la place des fichiers JSON statiques.
Livre
- PR #60 — read API catalogue borne (mergee dans dev, squash
a35db88) : 5 endpoints publics anonymes en lecture seule (docs/api/conventions.md5.2) :GET /api/categories,/api/products,/api/products/{id},/api/menus,/api/menus/{id}(detail avec slots).CatalogueController+ methodes de lecture filtrees sur Category/Product/MenuRepository (is_available=1ET categorie active : la borne ne voit que le commandable, en liste comme en detail). Enveloppe{data,total}, champs canoniques snake_case ;vat_rateexclu,is_availableretire des payloads,is_requiredde slot en booleen, sans timestamp. Dispo calculee RG-T21 differee (recettes non seedees). - PR #61 — cablage borne (CORS + data.js) (auto-merge arme a la redaction) :
App\Core\Cors: middleware CORS scope/api/, origine unique et exacte (CORS_ALLOWED_ORIGIN, sans joker),GET/POST/OPTIONS, headerContent-Type, sans credentials, fail-closed ; preflightOPTIONS -> 204avant le routeur ; decoration de la reponse y compris le 500 ducatch.CORS_ALLOWED_ORIGINdeja cable (.env.example+ docker-compose).data.jsreecrit : consomme/api/categories|products|menus, deballe{data}, traduit la forme canonique vers la forme borne (nom/prix/image/type), regroupe par slug de categorie, glisse les menus sous la clemenus. Signatures publiques inchangees -> pages intactes.loadAllergensreste statique.
Revue adversariale (workflow multi-agents, une par cycle)
- Read API : 1 finding LOW (lacune de test : slot sans option) -> test ajoute.
- Cablage : 2 findings, corriges.
- CRITIQUE :
findProduct(id)supposait des ids uniques sur l'ensemble du catalogue (vrai pour l'ancien JSON statique). En base,productetmenusont deux tables auto-increment distinctes demarrant a 1 -> collision (id 4 = burger Big Mac ET Menu Big Mac), cliquer un burger ouvrait le composeur de menu. Corrige :findProduct(id, categorySlug)desambigue par categorie (id unique dans une categorie) ;page-product.jspasse le slug deja present dans l'URL ; 2 tests de regression. - LOW : la reponse 500 du
catchn'etait pas decoree CORS ->$request/$corsconstruits hors dutry+ decoration de la 500.
- CRITIQUE :
Etat tests / CI
PHP unit 305 / 859 assertions, integration 40 / 253 (WAKDO_DB_TESTS=1, vraie base dev),
PHPStan L6 propre ; JS data.js 10 tests (node:test, fetch mocke). CI Forgejo : merge
natif squash sur checks requis (secret-scan, php-lint, static-tests).
Decisions actees
- L'API de lecture parle le dictionnaire (snake_case canonique) ; le rapprochement vers la
forme heritee de la borne se fait en un point unique,
data.js(conventions.md 8.3). - Le composeur de menu reste libre (il ne consomme pas les slots
/api/menus) pour ce chunk ; sa refonte sur les slots est differee. - Regle de livraison (user) : livrer via commit + PR + auto-merge natif sur CI verte, sans
gate manuel a chaque commit (memoire
feedback_commit_discipline).
File d'attente (suite)
- Verif cross-origin reelle : le
.envpointeCORS_ALLOWED_ORIGINsur l'origine serveur. Pour valider borne -> API en local, mettreCORS_ALLOWED_ORIGINsur l'origine du kiosk (APP_URL_KIOSK) + recreerwakdo-app, puis E2E #45. - Seed des recettes (
product_ingredient) -> active le decrement de stock depay()(chunk 1b) ET la dispo calculee RG-T21 dans les endpoints read. - Refonte du composeur de menu borne pour consommer les slots
/api/menus(B1 burger impose, B2 Normal/Maxi) au lieu de la composition libre. - Gate CI : ajouter
CI / js-testsaux checks requis (sinon un JS rouge pourrait merger). - Optionnel :
/api/allergens(la borne garde son JSON), prix en euros vs centimes.
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo && git merge --ff-only forgejo/dev
git log --oneline -6 dev # #60 read API + #61 cablage borne
docker compose up -d
Session : 2026-06-17 (suite) — P3 Users/RBAC/Stats + Makefile -> docker compose
Auteur : BYAN. Deuxieme cycle FD du jour (20260617-102548-p3-users-rbac-stats,
COMPLETED) puis un chore d'infra. P3 back-office desormais complet.
Livre (dev = 9d75fab)
- Lot S — Stats (#37) :
StatsController+StatsRepository->/admin/stats(permissionstats.read). KPIs disponibles : compteurs catalogue + sante stock (bandes RG-T21). Ferme le 404 du landing manager. KPIs de vente differes P4. - Lot U — Users (#38) :
UserController+UserRepository(mlt domaine 10). CRUD comptes, desactivation, anonymisation RGPD (mlt 10.5, tombstone). Chaque mutation = PIN equipier + audit (RG-T13/14), throttle (RG-T22). Garde-fous : pas d'auto-desactivation (403), dernier admin actif protege. Unicite email -> 409. - Lot R — RBAC (#39) :
RoleController+RoleRepository(mlt 10.4). Matrice roles x permissions (cases scalairesperm_<id>) + roles custom (RG-4) +role_visible_source. PIN + audit avec DIFF des permissions (RG-6). Garde admin (garderole.manage+ reste actif), code immuable, 409 code dupli. - Chore (#40) — Makefile ->
docker compose up: service one-shotwakdo-migrate(image mariadb) applique migrations (suivischema_migrations) + seed (suiviseeds_applied) idempotents viadb/migrate-container.sh(connexion reseau) ;wakdo-app/webattendent sa completion. Makefile supprime. Le « une commande » (Cr 7.c.4) passe demake initadocker compose up. Cr 7.b porte par les scripts Bash. Docs realignees + correction CI = Forgejo Actions (pas GitHub). Detail :docs/journal/2026-06-17--makefile-to-compose-migrate.md. - Chore (#41) —
docker-compose.ymlstandalone portable : le repo ship un compose qui tourne EN LOCAL sans config (docker compose up -d-> http://kiosk.localhost:8080- http://admin.localhost:8080), facon app open-source. Reseau interne seul,
wakdo-webpublie${HTTP_PORT:-8080}:80, plus de Traefik dans le fichier versionne, zero commentaire. RenommageTRAEFIK_DOMAIN_*->APP_HOST_KIOSK/ADMIN(vhosts ApacheServerName, *.localhost en local)..env.examplelocal-first (valeurs dev qui marchent sans edition). Prod =docker-compose.prod.ymlGITIGNORE, propre a chaque hote (meme stack + Traefik, sans port hote) :docker compose -f docker-compose.prod.yml up -d. Valide viadocker compose config(les deux fichiers) ; smoke-test runtime a faire sur machine propre (container_name fixes -> pas de up parallele a la stack en cours).
- http://admin.localhost:8080), facon app open-source. Reseau interne seul,
- Doc set socle (#42/#43/#44) :
docs/ARCHITECTURE.md(10 sections) +docs/DEVELOPER.md(#42) ;docs/adr/(index + 9 ADR : from-scratch, MVC serveur, stock %, PIN+audit, throttle PIN, 409/422, RGPD anonymise, Makefile->compose, standalone+prod) (#43) ;docs/domaines/(index + 7 fiches : auth, catalogue, stock-recettes, users, rbac, stats, borne) (#44). Decoupage en 3 PR par cohesion (squash). A pousser/lire sur la Forge.
Etat tests / CI
unit 263 + integration 301/916 assertions (WAKDO_DB_TESTS=1) + 7 tests JS + 2 parcours
E2E (borne + admin, Playwright, lance a la main), PHPStan L6, CI Forgejo verte. Branches
feature nettoyees (local + remote).
Fait depuis
- Smoke-test standalone : PASSE (2026-06-17). Lance dans un projet jetable isole
(
-p wakdotest, override container_name, port 8099) pour ne pas toucher la stack dev 26h : migrate exit 0 (2 mig + 2 seeds, 5 roles/23 perms/admin), bornekiosk.localhostHTTP 200 (<title>Wakdo - Bienvenue</title>), adminadmin.localhostHTTP 200 (Wakdo back-office), healthz 200. Le renommageAPP_HOST_*marche au runtime. Projet jetable + volumes/images supprimes ensuite. .envLOCAL migre :TRAEFIK_DOMAIN_*->APP_HOST_*(memes valeurs FQDN). Le.envSERVEUR reste a migrer (idem) avant son prochain deploiement.- Playwright E2E etape 1 : PASSE (#45, dev). Parcours borne complet (welcome ->
boissons -> produit -> ajout panier -> panier -> paiement -> confirmation), headless en
conteneur officiel, contre une stack JETABLE isolee (
tests/e2e/run.sh). A trouve + corrige un bug a11y :#pay-btn(un<a>) gardaitaria-disabled="true"car.disabledest un no-op sur un<a>-> pilote viaaria-disabled(commit2b51be3). Detail conteneur : hostnames de test en.test(Chromium force*.localhost->127.0.0.1). - Playwright E2E etape 2 : PASSE (#46, dev). Parcours admin : garde -> login
(admin@wakdo.local / mdp dev seede + CSRF) -> /admin/dashboard -> logout. A revele un
probleme secu/usage : cookie de session
secure=trueen dur -> session intenable en HTTP local -> login admin KO. Corrige ensecureconditionnel au HTTPS (SessionManager::cookieSecure, X-Forwarded-Proto ; prod inchange) -> ADR-0010. Valide : PHPStan L6, 263 unit, 2 E2E verts.
File d'attente (decidee avec le user)
- Deploiement serveur (Thanos) : migrer le
.envserveur (TRAEFIK_DOMAIN_*->APP_HOST_*, memes valeurs ;HTTP_PORTinutile en prod), placer sondocker-compose.prod.yml(gitignore), back-fillseeds_appliedavant le 1er up avecwakdo-migrate(sinon re-seed -> conflits). Le.envlocal est deja migre. - Playwright E2E — etape 3 (CI) : etapes 1 (borne) + 2 (admin) FAITES. Reste le
job CI Forgejo qui monte la stack jetable + lance Playwright en conteneur
(image
mcr.microsoft.com/playwright:v1.49.1-jammy, doit matcher la devDep). NB : le runner CI doit pouvoir faire du docker-in-docker / acceder au socket (a verifier). - Front : page de LOGIN a retravailler (demande user : "la page login est moche"). Initiative UI dediee ; ne PAS confondre avec le dashboard admin (qui, lui, va).
- Doc set — suite possible : diagrammes/captures, ou doc commande quand P4 sort.
Footgun : branches
docs/*heurtent le dossierdocs/dansforgejo-pr-automerge.sh(git log "$HEAD"ambigu) -> passer le titre en 3e arg. - Reste P4 : domaine commande (KPIs vente, liens nav orders, swap borne->API).
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo && git merge --ff-only forgejo/dev
docker compose up -d # stack complete en une commande (migrate+seed via wakdo-migrate)
Session : 2026-06-17 — P3 Stock + Recettes + Borne allergenes (cycle FD complet, 4 PR mergees)
Auteur : BYAN. Cycle FD 20260616-134152-p3-ingredients-stock mene a terme (reprise a DISPATCH -> BUILD -> VALIDATE). Scope Stock + recettes, etendu en cours a la borne allergenes, livre en 4 PR sequentielles toutes mergees sur dev en auto-merge sur CI verte.
Livre (dev = 1ecd783)
- PR-0 #33 — Harmonisation HTTP 409 : les reponses de CONFLIT (SQLSTATE 23000 : unicite + hard-delete bloque par FK RESTRICT) passent de 422 a 409 sur Category/Product/Menu (aligne le code sur le contrat
byan-api.md) ; la validation simple reste 422. IngredientController nait directement en 409. - PR-A #34 — Stock ingredients :
IngredientRepository(CRUD, stock %/bande calcules,restocktx,inventoryCounttx ecrivant une ligne meme a delta=0 RG-3,movementsborne,isReferenced) ;IngredientController(CRUDingredient.managesans PIN ; RESTOCKstock.managesans PIN ; INVENTORY_COUNTstock.count+ PIN equipier,pin.failed+throttle en 1 tx, sansaudit_logau succes RG-T14 ; movementsstock.read, user_id visible manager/admin RG-4) ; vuesadmin/ingredients/*+ lien nav Stock ; hard-delete bloque -> 409. - PR-B #35 — Recettes + dispo calculee :
ProductRepository(composition,setCompositiondelete-and-reinsert tx,ingredientExists,compositionCount,autoUnavailableIds,isOrderableRG-T21) ; editeur recetteProductController::recipeForm/saveRecipe(ingredient.manage, sans PIN) + vueadmin/products/recipe.php+product-recipe.js(vanilla CSP-safe) ; badge "Rupture auto" (RG-T21) dans la liste produits ; dette #27 fermee (nb de lignesproduct_ingredientcascade-supprimees trace dans le resume d'audit a la suppression produit). - PR-C #36 — Borne allergenes : icone "i" sur carte ET fiche produit ouvrant une modale GENERALE des 14 allergenes INCO (
allergens.jsCSP-safe,data/allergens.json,loadAllergens()dansdata.jsavec point de swap P4 ->/api/allergens). Premier harnais de tests front du depot : node:test + jsdom (tests/js/, 7 tests), job CIjs-tests(Node 20 epingle via NodeSource).
Decisions actees (2026-06-17)
- Inventaire = seule action sensible du domaine stock (RG-T13 liste 9.2, hors 8.8 CRUD et 9.1 restock). Succes ->
stock_movement.user_id, sansaudit_log(RG-T14). Echec PIN ->pin.failed+ throttle dans UNE transaction (RG-T22). - "i" allergenes = info GENERALE (14 INCO), pas un calcul par produit. Mapping
ingredient_allergenet allergenes calcules par produit restent differes. - Harnais JS : ESM declare LOCALEMENT (
src/public/borne/assets/js/package.json+tests/js/package.json), racine en CommonJS -> hooks.claude/_byan/binintacts. (Une 1ere tentative"type":"module"a la racine cassait les hooks CommonJS -> corrige avant commit.)
Etat tests / CI
259 tests PHP / 777 assertions (WAKDO_DB_TESTS=1), PHPStan L6 propre ; 7 tests JS (node:test + jsdom). CI dev verte : secret-scan, php-lint, static-tests, js-tests.
A faire (suivi)
- Gate CI : ajouter
CI / js-tests (pull_request)aux checks REQUIS de la branch protection (scripts/forgejo-branch-protection.sh). Au merge de #36 l'auto-merge natif (merge_when_checks_succeed) n'a pas attendujs-tests(pas encore requis) ; il a valide a posteriori surdev(vert). Sans ce gate, une PR au JS rouge pourrait merger. - P3 restant : Users + matrice RBAC ; Stats (ferme le finding
manager.default_route = /admin/stats404). - Differe : mapping
ingredient_allergen+ allergenes calcules par produit ; decrement atomique RG-T20 + swap borne JSON->API = domaine commande P4 (debloque liens navorders#23, purgeORDER_RETENTION#25). - Hygiene user : vars
.envauth/throttle absentes (l'app tourne sur ses defauts code) ; revoquer anciens PAT GitHub.
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo && git merge --ff-only forgejo/dev
git log --oneline -6 dev
# FD p3-ingredients-stock en phase VALIDATE (a clore en COMPLETED apres validation finale).
Session : 2026-06-16 — Audit "du reel" + 13 PR de remediation + Menus (#32) + demarrage Ingredients/stock
Vue d'ensemble
Session longue, quatre temps :
- Diagnostic branche
dev(CI "rouges" + graphe "bizarre"). - Audit sur pieces du travail du 2026-06-15 (demande : "du reel, pas le journal") via un sweep multi-agents + verification adversariale -> 13 PR de remediation, toutes mergees.
- Feature Menus construite en cycle FD complet (PR #32, mergee).
- Demarrage du cycle FD Ingredients/stock -> EN PAUSE a la phase DISPATCH.
1. Diagnostic dev (resolu, rien de casse)
- "CI pas vertes" = 8 echecs
auto-mergecosmetiques (double-fire : un 2e run tente de merger une PR deja mergee -> non-200 ; job non-bloquant) + 3static-testshistoriques (PR #9, php-xml/mbstring manquants, corriges le jour meme).devHEAD etait vert. - "Graphe bizarre" = refs de suivi locales non prunees (branches squash-mergees, supprimees cote serveur).
git fetch --all --prunenettoie. Le squash ne cree pas de 2e parent -> moignons rouges (cosmetique).
2. Audit + remediation (PR #19-#31, toutes mergees)
- CRITIQUE : durcissement
php.iniabsent du conteneur en service (image perimee) -> rebuildwakdo-app(runtime, fait + verifie). - HIGH : la CI ne lancait aucun test d'integration DB (auto-skip) -> #21 (service MariaDB +
WAKDO_DB_TESTS=1+--fail-on-skipped). - MEDIUM : XSS kiosk innerHTML #20 ; liens nav morts #23 ; user DB
GRANT ALL-> moindre privilege #24 ; purge RGPD/throttle cron #25. - LOW : enum email sur reset #26 ; contrat FK suppression produit #27 ; lien page PIN #28 ; bouton mort
PASSWORD_ALGO#29 ; atomicite chemin echec PIN #30 ; drift JSON borne #31. - + maquettes
.htmlnon authentifiees retirees #19 ; note d'audit jurydocs/journal/2026-06-16--audit-reel-livrables-p2-p3.md#22. - Incident :
docker compose up -d <service>nu a tue le reseau (vars${...}absentes du.env-> drift) -> recupdown+upsans perte. Memoireops-compose-single-service-network(utiliser--no-deps --force-recreate).
3. Menus (PR #32, mergee)
CRUD menus composes (mlt 8.4-8.6) : burger de base + slots (menu_slot/menu_slot_option), prix Normal/Maxi. Slots en vanilla JS (champ cache slots_json, CSP-safe). delete = PIN equipier + audit ; create/update sans PIN ; update = delete-and-reinsert des slots. Lien nav Menus reactive. Acces : menu.create/update admin+manager, menu.delete admin seul, menu.read tous.
Etat Git
dev = c2a4854 (toutes les PR #19-#32 mergees ; local == forgejo == github). Working tree propre sur dev. Branches feature supprimees au merge. 201 tests verts (597 assertions avec WAKDO_DB_TESTS=1), PHPStan L6 propre, CI verte (avec tests d'integration DB).
4. EN COURS : FD Ingredients/stock (PAUSE a DISPATCH)
fd_id = 20260616-134152-p3-ingredients-stock, phase DISPATCH (voirbyan_fd_status).- Scope decide : Stock + recettes, livre en 2 PR sequentielles :
- PR-A Stock :
IngredientRepository(CRUD + calcul stock %/bande +restocktx +inventoryCounttx + registrestock_movement+isReferenced) ;IngredientController(CRUDingredient.manage; RESTOCKstock.manage; INVENTORY_COUNTstock.count+ PIN ; mouvementsstock.read) ; vuesadmin/ingredients/{index,form,restock,inventory,movements}+ lien nav Stock ; tests (unit + integration + FakeDatabase). - PR-B Recettes :
product_ingredient(quantite normal/maxi,is_removable/is_addable,extra_price_cents), editeur imbrique facon slots (vanilla JS). Debloque RG-T21 (dispo produit calculee) + ferme la dette #27 (trace cascade).
- PR-A Stock :
- Decisions actees : inventaire = PIN + trace
stock_movement.user_idSANSaudit_log(RG-T14 exclut le stock du double-journal) ; soft-deleteis_active, hard-delete bloque (FKproduct_ingredient/stock_movementRESTRICT -> 422). - Modele :
ingredient(stock_quantitysigne ;stock_capacity>0= 100% ;pack_size;low_stock_pct=10/critical_stock_pct=5aveccritical<low) ;stock_movementappend-only (sale/cancellation/restock/inventory_correction). - Permissions :
ingredient.manage+stock.manage= admin+manager ;stock.count+stock.read= tous les roles. - A LA REPRISE : dire "go PR-A" -> chunk 1 =
IngredientRepository+IngredientRepositoryDbTest(meme decoupe que Menus, chaque chunk verifie).
A faire (apres le stock)
- P3 restant : Users + matrice RBAC ; Stats (ferme le finding
manager.default_route = /admin/stats404). - Differe : allergenes
ingredient_allergen; affichage dispo calculee RG-T21 (vient avec PR-B) ; domaine commande P4 (debloque les liens navorders#23, la purgeORDER_RETENTION#25). - Hygiene cote user : les vars auth/throttle (
ARGON2_*,ACCOUNT_LOCKOUT_*,PIN_THROTTLE_*, ...) sont absentes du.envreel (l'app tourne sur ses defauts code) ; revoquer les anciens PAT GitHub.
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo && git merge --ff-only forgejo/dev
git log --oneline -6 dev
# FD en cours : phase DISPATCH. Dire "go PR-A" pour reprendre le build (IngredientRepository).
Session : 2026-06-15 (suite 5) — P3 : throttle PIN (RG-T22, #18) merge
Vue d'ensemble
Fermeture du finding HIGH de la revue Produits (PIN d'action sensible sans limitation de tentatives).
Conception via un panel multi-agents (3 lentilles Ockham / efficacite-menace / anti-DoS -> synthese ->
passe adversariale, holds = true), construction en TDD avec les correctifs de l'adversaire integres,
revue adversariale de l'implementation (holds = true), puis merge sur dev en auto-merge (PR #18).
Resume de session detaille (format jury RNCP) : docs/journal/2026-06-15--p3-throttle-pin-rg-t22.md.
Decision actee
Compter les echecs de PIN par utilisateur AGISSANT ($guard->userId), pas par email cible
(contournable par rotation) ni par IP (collateral sur poste a session partagee). Table dediee
pin_throttle (entite 22) cle sur actor_user_id (FK ON DELETE CASCADE), separee des compteurs de
connexion : un echec de PIN n'incremente aucun compteur de login (pas d'escalade DoS). Bornes propres
(PIN_THROTTLE_*, base 30s / plafond 300s, plus permissives que le login : controle de dissuasion).
Ce qui a ete livre (merge ; PR #18 ; dev = ad5203d)
App\Auth\PinThrottle(isLocked / recordFailure upsert atomique + backoff / reset), dimension'pin'deThrottlePolicy,PinVerifier::payTimingDecoy(parite de timing), cablageProductControllerupdate/destroy (gate avant verification, pas depin.failedsous verrou actif = anti-flood, reset sur l'acteur de session).- Migration
0002_pin_throttle.sql(appliquee a la base dev) ; docs Merise 21 -> 22 entites (RG-T22) ;.env.example+docker-compose.yml(PIN_THROTTLE_*). - 188 tests verts (525 assertions), PHPStan L6 propre. Branche supprimee (local + remote).
Etat Git
dev ad5203d (auth #11 ... produits #17 + throttle PIN #18 ; local == forgejo == github)
Hors-scope untracked : package*.json, SESSION_RESUME.md, journal P1 2026-06-04.
A faire a la reprise
- Suite P3 : Menus (+ slots), Ingredients/stock, Users + matrice RBAC, Stats.
- Differe : etendre le cron de purge a
pin_throttle(predicat dansmlt.md13.5) ; alerte de volumepin.failedcote supervision ; seed ingredients/recettes ; revoquer anciens PAT GitHub.
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo dev && git merge --ff-only forgejo/dev
git log --oneline -8 dev
Session : 2026-06-15 (suite 4) — P3 : CRUD Produits (#17)
Vue d'ensemble
Suite directe de la session P3. Le CRUD Produits est livre et merge (PR #17, squash sur dev),
memes patterns que Categories : App\Catalogue\ProductRepository sur DatabaseInterface,
ProductController non-final, double FakeDatabase, tests unit + integration auto-skippee,
revue adversariale par chunk. C'est le premier usage reel du PIN d'action sensible (RG-T13)
sur des mutations metier, avec ecriture audit_log dans la meme transaction (RG-T08 / RG-T14).
CRUD Produits (merge ; PR #17 ; dev = 2756fb4)
App\Catalogue\ProductRepository(DatabaseInterface) : all/find/create/update/delete +categoryExists, allowlist de colonnes a l'ecriture (RG-T16).ProductController(index/create/store/edit/update/confirmDelete/destroy) : chaque actionguard('product.manage')(RG-T03), mutations CSRF (RG-T01), validation serveur bornee (RG-T18 : categorie existante, nom <=120, prix > 0 et <= UINT32, TVA dans {55,100}, image <=255, display_order 0..65535).- PIN conditionnel (8.2 RG-4) : a l'update, le PIN equipier est exige uniquement si
price_centsOUvat_ratechange (les deux sont fiscalement sensibles : sur_place 10% vs a_emporter 5.5%) ; sinon write simple sans PIN. A la suppression, le PIN est exige dans tous les cas. - Modele PIN = identifiant equipier + PIN :
PinVerifier::resolveActingUser(email, pin)(ajoute ce chunk) resout l'identite de l'equipier qui valide (SELECT filtreis_active = 1), et c'est cetacting_user_id(pas l'utilisateur de session) qui est ecrit dansaudit_log(RG-T14), dans la MEME transaction que la mutation (RG-T08). - Suppression FK-safe : hard delete seulement si le produit n'est pas reference (order_item /
menu.burger_product_id, FK RESTRICT) ; sinon
PDOExceptionSQLSTATE 23000 traduit en 422. - Vues
admin/products/{index,form,delete}, ajout des routes danssrc/public/admin/index.php. - 172 tests verts (452 assertions), PHPStan L6 propre.
Revue : 6 findings confirmes (0 refute)
- HIGH — PIN d'action sensible sans limitation de tentatives.
PinVerifierverifie avec parite de timing (leurre argon2id) mais sans compteur ni backoff : un insider tenant dejaproduct.managepeut iterer les PIN (4 chiffres = 10^4) contre l'email d'un collegue et forger l'acting_user_idde l'audit. Le login a sonlogin_throttle(RG-8) ; le PIN n'a pas d'equivalent. Mitigation shippee dans ce chunk : chaque PIN refuse ecrit unaudit_logpin.failed(acteur NULL, cible, email tente) -> la tentative devient detectable et alertable. Le throttle PIN degressif complet reste a faire (chunk dedie, cf. plus bas). - LOW — case
is_available: sur re-rendu d'erreur, une case decochee revenait cochee (fallback?? 1applique aussi au re-rendu). Corrige : la valeur ne retombe sur le defaut que pour le formulaire de creation, le re-rendu reflete l'etat soumis. - 4 MEDIUM = lacunes de couverture / resistance aux mutations (le code de prod etait correct, les
correctifs durcissent les tests) :
- chemin TVA-only (vat 55) non teste -> ajout
testUpdateVatChangeRequiresPin+...WithValidPinAudits. - route
resolveActingUserduFakeDatabasene forcait pasis_active = 1(un mutant retirant le predicat passait) -> route durcie + assertion SQL. - test de suppression n'assertait pas que l'acteur audit = l'equipier resolu -> assertions actor (uid === 9, rid === 4) ajoutees sur update et destroy.
FakeDatabasene prouvait pas que l'INSERTaudit_logtombe ENTRE begin et commit (deux listes disjointes) -> ajout d'uneventLogentrelace + assertions d'ordre (begin < audit < commit).
- chemin TVA-only (vat 55) non teste -> ajout
Etat Git (post-chunk)
dev 2756fb4 (auth #11 + RBAC #12 + PIN #13 + shell #14 + categories #15 + set-PIN #16 + produits #17 ; == forgejo/dev)
Branche feat/p3-products-crud supprimee (remote auto-merge + local). 172 tests, PHPStan L6 propre.
Hors-scope untracked : package*.json, SESSION_RESUME.md, journal P1.
A faire a la reprise — d'abord le throttle PIN (chunk dedie), AVANT Menus / Stock
- Throttle PIN d'action sensible (chunk dedie, prioritaire) : fermer le finding HIGH. Decision de
schema a trancher d'abord : ne PAS reutiliser les colonnes
user.failed_login_attempts/lockout_untildu login (un attaquant qui spamme le PIN d'une victime verrouillerait son LOGIN = DoS sur la victime). Pistes : compteur PIN dedie (colonnespin_failed_attempts/pin_lockout_untilsuruser, OU tablepin_throttle), dimension per-user ET per-IP (comme RG-8), reponse generique (ne pas reveler quels emails existent), reset sur succes. ReutiliseThrottlePolicy. Ajouter une RG Merise dediee + migration + tests. La mitigationpin.failedreste en place entre-temps. - Ensuite : Menus (+ slots), Ingredients/stock, Users + matrice RBAC, Stats.
- Differe : seed ingredients/recettes ; revoquer anciens PAT GitHub.
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo dev && git merge --ff-only forgejo/dev
git log --oneline -7 dev
Session : 2026-06-15 (suite 3) — P3 : shell (#14) + CRUD Categories (#15) + set-PIN (#16)
Vue d'ensemble
P3 (CRUD admin) demarre. Architecture tranchee : pages rendues serveur (PHP MVC), pas d'API
JSON pour le back-office (coherent avec l'auth, demontre le MVC). Routes back-office sous /admin/...
(le seed fixe role.default_route a /admin/dashboard, /admin/stats, etc.). Deux chunks merges,
memes patterns que P2 (services/repos sur DatabaseInterface, controleurs non-final, FakeDatabase,
tests unit + integration auto-skippee, revue adversariale par chunk).
Shell admin (merge ; PR #14)
Controllergagne un hooklayoutName()(defaut inchange) ; le back-office rend dansadmin/layout.AdminController(base) :guard(permission?)= RG-6/RG-T02 (302/loginsi session KO) puis RG-T03 (403 si permission manquante), sinonGuardResult;adminView()injecte identite + permissions + CSRF + flash ; helperssetFlash/takeFlash.DashboardController->GET /admin/dashboard;UserDirectory(nom + libelle role topbar).- Vues
admin/{layout,dashboard,forbidden}: nav conditionnee aux permissions, logout POST CSRF, sorties echappees (RG-T15). Premier cablage reel duSessionGuardsur une page. - Revue : 5 findings corriges (initiales multibyte, couverture 403, test d'echappement, marqueur de fragment, commentaire d'heritage).
CRUD Categories (merge ; PR #15) — pattern de reference
App\Catalogue\CategoryRepository: couche d'acces des entites CRUD (all/find/create/update/ setActive/nameExists/slugExists), testable viaDatabaseInterface.CategoryController(index/create/store/edit/update/toggle) : chaque actionguard('category.manage')(RG-T03), mutations CSRF (RG-T01) + validation serveur (RG-T18 : requis/format/bornes/unicite, display_order 0..65535) + allowlist de colonnes (RG-T16). Pas de suppression dure (FK RESTRICT) : basculeis_active. Violation d'unicite concurrente traduite en 422. Flash apres redirection.- Vues
admin/categories/{index,form}+admin/not_found. Revue : 6 findings corriges (borne display_order, violation unique -> 422, +4 tests de regression).
Set-PIN self-service (merge ; PR #16)
ProfileController->GET/POST /admin/profile/pin: l'utilisateur connecte definit/change SON propre PIN (cible =guard.userIdde session, pas un champ de form -> pas d'IDOR). CSRF + validation serveur (numerique + bornes viameetsLengthPolicy, confirmation). Hash argon2id. Ecriture gardee sur 1 ligne affectee (pas de faux succes).UserRepository:setPinHash/pinIsSet.- Decision PIN actee : modele identifiant equipier + PIN pour les actions sensibles (attribution
individuelle).
PinVerifier::resolveActingUser(email, pin)reste a ajouter en chunk Produits. - E2E : l'admin a un PIN dev =
4729en base (pose via la page), ce qui debloque le gate Produits. - Revue : 3 findings corriges (fallback
?? 0retire, gate ligne affectee, assertion cible = session).
Etat Git (post-chunks)
dev f63ac98 (auth #11 + RBAC #12 + PIN #13 + shell #14 + categories #15 + set-PIN #16 ; == forgejo/dev)
152 tests (unit + integration DB auto-skippee), PHPStan L6 propre. Branches feature supprimees.
Hors-scope untracked : package*.json, SESSION_RESUME.md, journal P1.
Pattern CRUD admin (a reutiliser pour produits/menus/users)
App\Catalogue\<Entite>Repository(DatabaseInterface) : requetes preparees, unicite.<Entite>Controller extends AdminController: par action ->guard(<permission>)-> (mutation :Csrf::validate) -> validation serveur + allowlist -> repo -> redirect +setFlash, ou re-rendu 422.- Vues
admin/<entite>/{index,form}rendues dans le shell ; tout texte echappe. - Actions sensibles (RG-T13) ->
PinVerifier+audit_log(RG-T14) dans la meme transaction. - Pas de suppression dure si FK RESTRICT -> desactivation.
- Tests : controleur (double via hooks), repository (integration DB auto-skippee).
A faire a la reprise
- CRUD Produits (chunk en cours) : cas riche (price_cents, vat_rate {55,100}, category_id FK,
is_available, image, display_order). Premier usage reel de
PinVerifier: PIN exige uniquement si prix/TVA change (8.2 RG-4) et a la suppression (8.3), modele identifiant equipier + PIN viaPinVerifier::resolveActingUser(email, pin)(a ajouter) ->acting_user_idecrit dansaudit_logdans la meme transaction (RG-T14). Suppression dure seulement si non reference (FK RESTRICT depuis order_item / menu.burger_product_id) sinon 422. Reutilise les bornes d'entiers durcies (revue categories). - Ensuite : Menus (+ slots), Ingredients/stock, Users + matrice RBAC, Stats.
- Differe : seed ingredients/recettes ; revoquer anciens PAT GitHub.
Session : 2026-06-15 (suite 2) — RBAC P2 (PR #12) + moteur PIN (PR #13), tous deux merges
Vue d'ensemble
Poursuite directe de la session auth. RBAC livre et merge (PR #12), puis moteur PIN d'action
sensible construit (commit/PR en attente apres revue). Memes patterns que l'auth : services
dependant de DatabaseInterface, controleurs non-final pour le seam de test, double
FakeDatabase, tests unit + integration auto-skippee, revue adversariale par panel.
RBAC (merge ; dev = f979a23 ; PR #12)
Authorizer:can(role_id, code)/permissionsFor(role_id)/roleCode(role_id); verifie une PERMISSION (RG-T03), rechargee depuis la base a chaque appel (10.4 RG-3) ; un roleis_active = 0ne confere rien.AuthenticatedController(dansApp\Controllers, pas le Core, pour ne pas inverser la dependance) : cableSessionGuard(RG-6/RG-T02) +Authorizer.MeController->GET /api/me:401 AUTH_REQUIREDsi session absente/expiree/inactive, sinon identite + permissions. Premier consommateur reel duSessionGuard(enfin cable).- Revue : 3 findings corriges (
roleCodene filtrait pasis_active; couverture du predicatis_activeviaFakeDatabase.roleActive+ un test d'integrationAuthorizerDbTestcontre le vrai schema ; assertions de liaison par code de permission). 1 refute (leSessionGuardne relit pasrole_iden cours de session = by-design 10.4 RG-3 : la session stockerole_id, seules les permissions se rechargent).
PIN (merge ; PR #13)
PinVerifier:verify(user_id, pin)contreuser.pin_hash(argon2id, default-deny, filtreis_active = 1) ;meetsLengthPolicy(chiffres ASCII, bornes min/maxSTAFF_PIN_MIN/MAX_LENGTH, RG-T18). Primitif RG-T13 reutilise par chaque operation sensible en P3.- 119 tests verts (unit + integration, dont la garde du filtre
is_activecontre le vrai schema), PHPStan L6 propre. - Revue : 3 findings corriges (decoy argon2id sur le chemin sans PIN pour egaliser le timing ;
politique de longueur durcie
ctype_digit+ max ; couverture du filtreis_active). 2 refutes (throttle PIN = concern orchestrateur P3 ; cast(string)redondant inoffensif). - Perimetre P2 = le primitif seul. Les operations sensibles gardees (annulation, prix/TVA,
suppressions, correction d'inventaire, gestion user/RBAC, effacement PII), la definition d'un PIN
(set/change) et le cablage PIN +
audit_logdans la meme transaction sont P3 (flux deja specifie dansdocs/uml/security-sequence.mdpour CANCEL_ORDER).
Etat Git
dev 7c35f8e (auth PR #11 + RBAC PR #12 + PIN PR #13 ; == forgejo/dev ; push-mirror -> GitHub)
Branches feature supprimees (remote auto-merge + local). Working tree sur dev, propre.
Hors-scope untracked : package*.json, SESSION_RESUME.md, journal P1
A faire a la reprise
- P3 CRUD admin : les pages admin deviennent des vues rendues serveur passant par
AuthenticatedController. Chaque operation cable alorsSessionGuard+Authorizer::can(permission)PinVerifier(actions sensibles) + ecritureaudit_logdans la meme transaction (RG-T08/RG-T14). C'est en P3 queSessionGuard/Authorizer/PinVerifiersont reellement appliques aux operations, et que les pages statiques (.htmlservies par Apache) deviennent protegeables.
- Modele d'attribution PIN sur poste partage a trancher en P3 : PIN seul (identifie l'individu)
vs identifiant equipier + PIN. Le primitif
verify(user_id, pin)supporte les deux. - Differe : seed ingredients/recettes ; revoquer les anciens PAT GitHub.
Session : 2026-06-15 (suite) — P2 Auth back-office mergee (PR #11) + doc API + convention snake_case
Vue d'ensemble
Livraison de la couche authentification back-office (P2), conçue via un panel de design
(3 architectes : testabilite / securite / simplicite) puis durcie par une revue adversariale
(6 findings confirmes corriges). Mergee sur dev en auto-merge sur CI verte (PR #11, squash =
1b0b20c). En bonus : doc API et arbitrage de la convention de nommage.
Ce qui a ete fait
- Prerequis compose :
ARGON2_*,ACCOUNT_LOCKOUT_*,IP_THROTTLE_*,STAFF_PIN_MIN_LENGTH,PASSWORD_RESET_TTLpasses au conteneurwakdo-app(deja dans.env.example). - Core etendu (additif) :
Request::formBody()(POST urlencode) +Request::clientIp()(IP reelle = dernier hopX-Forwarded-Forderriere Traefik, validee, repliREMOTE_ADDR) ;Database::transaction(callable): void(atomicite RG-T08) +DatabaseInterface(seam de test) ; accesseurs lectureResponse(body/header/headers). - Domaine
App\Auth:AuthService(12.1 login + 12.2 logout),PasswordResetService(12.3),SessionGuard(RG-6 + RG-T02 — ecrit et teste mais PAS encore cable : c'est le travail RBAC),ThrottlePolicy(backoff degressif),PasswordHasher(argon2id + leurre de timing en cache statique process),Csrf(synchroniseur + rotation),SessionManager(seul a toucher$_SESSION/cookie, mode test memoire),Mailer/LogMailer(lien reset journalise, pas de SMTP en P2),AuthResult/GuardResult. - Controllers + vues + routes :
AuthController+PasswordResetController(non-finalpour le seam de test), vues serveurauth/{login,forgot,reset}.php(CSRF cache,htmlspecialchars), 7 routes sur le vhost admin (/login,/logout,/forgot_password,/reset_password, ...). - Tests : 98 verts (unit sans DB + integration DB auto-skippee). PHPStan L6 propre.
- Doc API :
docs/api/conventions.md(conventions + listing des endpoints, en service + projete).
Decisions actees
- Login = vue PHP rendue serveur (form POST + 302 vers
role.default_route), pas une API JSON : le back-office est du MVC serveur. - Convention de nommage des URL = minuscule + snake_case (apres challenge utilisateur + fact-check :
le minuscule est source RFC 3986, aucun standard n'impose
-vs_, la coherence avec la DB et les champs JSON tranche pour_). Routes :/forgot_password,/reset_password;/api/<ressource>au pluriel snake (/api/order_items). Les champs JSON suivent le dictionnaire (snake_case). - Bug attrape en E2E :
PDO::ATTR_EMULATE_PREPARES = falseinterdit de lier un meme placeholder nomme plusieurs fois dans une requete -> placeholders distincts. - Corrections de revue : parite du profil d'ecritures sur email inconnu (
UPDATEno-op surid = 0, anti-enumeration) ; increment du compteur IPlogin_throttlerendu atomique cote SQL (anti lost-update) ; leurre argon2id mis en cache statique (parite de timing sans surcout par requete).
Boucle de verification locale (pas de PHP sur l'hote)
# unit + analyse (image PHP du projet, conteneur jetable) :
docker run --rm -v "$PWD":/app -w /app wakdo-wakdo-app php phpunit.phar -c phpunit.xml
docker run --rm -v "$PWD":/app -w /app wakdo-wakdo-app php -d memory_limit=-1 phpstan.phar analyse --no-progress --error-format=raw
# integration DB (auto-skip sans le flag) :
docker run --rm --network wakdo_wakdo_internal --env-file .env -e WAKDO_DB_TESTS=1 -v "$PWD":/app -w /app wakdo-wakdo-app php phpunit.phar -c phpunit.xml
Les *.phar (phpunit 11.5.2 / phpstan 1.12.27) sont gitignores ; les telecharger si absents.
Etat Git (post-session)
dev 1b0b20c (P2 auth merge, == forgejo/dev ; push-mirror -> GitHub auto)
feat/p2-auth : supprimee cote remote par l'auto-merge ; branche locale stale (supprimable)
Working tree : hors-scope habituels untracked (package*.json, SESSION_RESUME, journal P1)
A faire a la reprise — RBAC (demarre juste apres cette mise a jour)
- Service d'autorisation :
can(role_id, permission_code)viarole_permissionJOINpermission, recharge depuis la DB a chaque verification (mct/mlt 10.4 RG-3 ; la session ne stocke querole_id). Verifie une permission, pas un nom de role (RG-T03). - Cabler
SessionGuard::check()en tete des routes protegees (idle/absolu/is_active), avec redirection vers/loginsi invalide. En P2 il n'y a pas encore de route protegee : on en cree une reelle pour brancher et tester la chaine (ex./devient le landing authentifie, et/ou/api/me). - PIN actions sensibles (RG-T13) sur le sous-ensemble sensible : annulation, prix/TVA, RBAC,
gestion utilisateur, correction d'inventaire (cf.
docs/uml/security-sequence.md). - S'appuie sur le seed (5 roles + 23 permissions + matrice deja en base).
Session : 2026-06-15 (P1 conception finie + traduction FR + P2 demarre : DB + seed + Core)
Vue d'ensemble
Session marathon, trois phases :
- Pivot security-by-design boucle (A->G) : threat model, infra/config secu, CI/CD Forgejo Actions, diagrammes MCD + MLD. P1 conception terminee.
- Traduction FR de la prose des 5 docs Merise (identifiants/code inchanges), via 2 workflows. Convention projet : FR ASCII (sans accents).
- P2 demarre (le code !) : DDL 21 tables + runners migrations/seed, seed data, Core PHP from-scratch
(squelette MVC, namespace
App\->src/app/). Tout merge surdev, identique Forgejo == GitHub.
P2 back squelette (en cours, deja merge sur dev)
- DB foundation (PR #6) :
db/migrations/0001_init_schema.sql(21 tables, verifie executable sur MariaDB reel),db/migrate.sh+db/seed.sh(idempotents),make migrate/make seedcables. - Seed (PR #8) : 5 roles + 23 permissions + matrice (manager =
user.readlecture seule) + 14 allergenes INCO + 1 admin (argon2id,admin@wakdo.local/WakdoAdmin2026!dev) + catalogue (9 cat / 53 produits / 13 menus + composition). Differe : ingredients/recettes (couche stock, P3). - Core PHP (PR #9 + #10) :
src/app/{Core,Controllers,Views}(App\ -> src/app), front controllersrc/public/admin/index.php. Autoloader PSR-4, Config getenv, Database PDO (prepared, lazy), Router, HealthController (GET /api/health-> DB reelle, categories:9). PHPUnit (.phar) + PHPStan L6, sans Composer.
Ce qui a ete fait (lots du pivot SbD)
- A threat model STRIDE + classification 4 niveaux (
PROJECT_CONTEXT SS19+security-sequence.md). - B
PROJECT_CONTEXT: drift GitHub->Forgejo Actions corrige, couche secu integree, planning rechiffre (P0 22 / P1 38 / P7 22 ; total 272h), decision #16 SbD. - C infra/config :
.env.example(argon2id/lockout/throttle IP+compte/retention RGPD),php.inidurci (allow_url_*off, cgi.fix_pathinfo=0, IDs session, disable_functions RCE),.gitleaks.toml,scripts/forgejo-branch-protection.sh, doc runner. act_runner enregistre. - D
SECURITY.md, checklist secu dans PR template,.forgejo/workflows/ci.yml(secret-scan gitleaks + php-lint + static-tests PHPStan/PHPUnit gardes jusqu'a P2),scripts/forgejo-pr-automerge.sh. Auto-merge teste et valide (PR #2, #3, #4). - E diagrammes MCD : 4 sous-domaines en Mermaid + SVG (
mcd-{catalogue,ingredients-stock,order,rbac}), vieux.drawiov0.1 supprimes,mcd.mdSS3/SS11 reecrites. - F PR #3
feat/p1-conception -> devauto-mergee sur CI verte (squash), branche supprimee. - G push-mirror Forgejo->GitHub configure+teste (sync auto a chaque commit) ; historique git verifie sans secret (gitleaks + scan manuel). Reste cote user : revoquer anciens PAT GitHub (Session 6).
- + diagrammes MLD : 4 sous-domaines relationnels (Mermaid+SVG,
mld-*), PR #4 auto-mergee.
Etat Git (post-session) — tout aligne local == Forgejo == GitHub
main 5104040 (derniere release)
dev c8f5370 (P1 conception FR + P2 : DB foundation + seed + Core skeleton src/app)
Code applicatif : src/app/{Core,Controllers,Views} (App\ -> src/app), front src/public/admin/index.php
Branches locales : dev, main (aucune feature en cours). Working tree : hors-scope BYAN + SESSION_RESUME (local)
Infra / forge / CI (a retenir)
git.acadenice.com= Thanos, PROD (serveur distinct 72.61.105.12). NE PAS confondre avec le forgejo local de starkgit.stark.a3n.fr. Voir memoireproject_forge_topology.- CI Forgejo Actions activee au niveau instance (
FORGEJO__actions__ENABLED=true, fait par le user). Runnerforgejo-runner-wakdotourne sur stark, pointe la prod. Apres restart du forgejo prod ->docker restart forgejo-runner-wakdo(sinon boucle 404). - CI static-tests = SANS Composer : phpstan.phar + phpunit.phar epingles. Le runner (node:20-bookworm,
PHP 8.2) installe
php-xml php-mbstring(sinon PHPUnit manque dom/mbstring) — deja dans ci.yml. - Auto-merge OPT-IN par label
auto-merge: le gate verifie le label EN SHELL via l'API (GET issues/PR/labels+ grep), PAS viaif: contains(labels...)de Forgejo (NON fiable : avait merge PR #9 sans label -> corrige PR #10). PR verte + label -> fusionne ; PR verte sans label -> reste ouverte. - Required checks (dev+main) : les 3 contextes precis
CI / {secret-scan,php-lint,static-tests} (pull_request)(pas le globCI / *qui incluait le job auto-merge skippe). Push-mirror -> GitHub auto.
En attente du user
- Relecture des diagrammes MCD + MLD (4+4 sous-domaines) — le user lisait les docs a la pause. Si un layout ne plait pas, ajuster via une petite PR.
- Decision : auto-merger directement ou faire valider les diagrammes avant merge la prochaine fois.
A faire a la reprise (P2 suite)
- Auth : sessions PHP + argon2id (login), regeneration d'ID a la connexion, idle 4h / absolute 10h.
Prerequis : passer les vars
ARGON2_*/SESSION_*/ lockout / throttle au conteneur wakdo-app (blocenvironment:dudocker-compose.yml) — PAS encore fait (seules DB_/APP_/SESSION_/CORS_ y sont). - RBAC : middleware de permissions (teste une permission, pas un nom de role), protection routes admin
- PIN pour actions sensibles. S'appuie sur le seed (roles/permissions/matrice deja en base).
- Seed ingredients/recettes (differe) : decisions de modelisation (quels ingredients, quantites) avec le user.
- Hygiene : revoquer les anciens PAT GitHub (Session 6).
Reprendre
cd /home/acadenice/corentin_wakdo
git checkout dev && git fetch forgejo dev && git merge --ff-only forgejo/dev
git log --oneline -6 dev
Session 2026-06-12 (relecture security-by-design + modele stock en % + lot A threat model)
Note : ce doc avait derive (fige a Session 7, 2026-05-21). Entre-temps : v0.2 prod-like 19 entites + migration Forgejo (2026-06-04, voir
docs/journal/2026-06-04--*.md) puis demarrage du pivot security-by-design (2026-06-11). Le bloc ci-dessous repart de l'etat reel.
Vue d'ensemble
Consolidation du pivot security-by-design sur feat/p1-conception. Trois temps :
- Relecture des 3 decisions securite (RGPD, oversell, brute-force) : les 3 directions validees. Le challenge a fait emerger une simplification (oversell) et un upgrade (stock %).
- Change-set applique aux 5 docs Merise via 1 workflow (5 editeurs paralleles + 4 critiques adversariaux), puis correctifs manuels des residus rates par les critiques.
- Lot A ecrit via 1 workflow (2 auteurs + 2 critiques) : threat model + classification dans
PROJECT_CONTEXT §19, etdocs/uml/security-sequence.md.
Decisions actees cette session
- Stock en vrais % :
ingredientportestock_capacity(INT, CHECK > 0 = reference 100% + garde anti div/0),low_stock_pct(def 10),critical_stock_pct(def 5) ;stock_quantitysigne (peut etre negatif).stock_pct = ROUND(stock_quantity/stock_capacity*100)calcule. 3 bandes : normal / alerte (le manager retire viais_availableOU re-stocke) / auto-OOS sous le critique. - Disponibilite produit CALCULEE (RG-T21) : commandable ssi
is_available=1 AND chaque ingredient non-retirable > critical. Pas de cascade ni flag ; retrait manuel = override dur. login_throttle= table (entite 21) : throttle brute-force per-IP, en plus du compteur per-compte suruser.- Drop
SELECT ... FOR UPDATE: decrement stock =UPDATE ... stock = stock - :unitsatomique (plus de read-gate, plus de risque deadlock).idempotency_keyconserve. - Drift MCD §5.1 corrige :
product_ingredient.quantity->quantity_normal/quantity_maxi.
Etat Git (post-session)
Branche : feat/p1-conception
5 commits POSES cette session (non pushes - le push partira avec la PR) :
fadf0bd DICT - SbD data layer, 21 entities
a1692b6 MCD - SbD entities + % stock model, drift fix
14348ba MLD - audit_log + login_throttle tables, % stock columns
0f57a44 MCT - SbD operations, PIN gating, computed availability
5c34f6b MLT - RG-T13-T21, atomic decrement, throttle, RGPD
Working tree UNCOMMITTED (tenu volontairement) :
docs/PROJECT_CONTEXT.md (§19 threat model + classification ECRIT ; tenu car lot B
va aussi toucher §7/§11)
docs/uml/security-sequence.md (NOUVEAU, lot A, fini, verifie)
docs/uml/{sequence-passer-commande,state-commande,use-cases}.md (drift-fix v0.2, pret,
a grouper avec security-sequence.md)
+ journal 2026-06-04 untracked ; hors-scope BYAN (.claude, Makefile, docker-compose, package*)
A faire a la reprise (ordre)
- B :
PROJECT_CONTEXT §7/§11(retirer « MVP », 21 entites, rechiffrer planning) -> puis commit PROJECT_CONTEXT (§19 + §7/§11) + les 4 docs UML. - C : infra/config secu (
.env.exampleargon2/lockout/retention/seuils,php.inidurci, secret-scan, ruling branch-protection). - D : SDLC (
SECURITY.md, checklist PR template, jobs CI Forgejo PHPStan/secret-scan). - E : regenerer les drawio MCD/MLD pour 21 entites (les
.mdsont en Mermaid inline). - F : clore -> PR
feat/p1-conception -> dev(base =dev!), rafraichir ce doc. - G : roter le token Forgejo expose ; decider push-mirror Forgejo->GitHub.
Reprendre
cd /home/acadenice/corentin_wakdo
git branch --show-current # feat/p1-conception
git log --oneline -6 # voir les 5 commits SbD
git status --short # PROJECT_CONTEXT + UML uncommitted
Session precedente : 2026-05-21 (Session 7 - P1 conception : 5 docs Merise/UML + machine a etats commande unifiee)
Vue d'ensemble
Session centree sur la reprise de P1 conception. Trois resultats :
- Rapatriement P1 sur
feat/p1-conception: les fichiers P1 (mcd.md + diagrammes) flottaient dans le working tree de la branche demodemo/p5-front-and-p3-admin. Portes proprement surfeat/p1-conception(stash des fichiers BYAN hors-scope, switch, pop). Les 4.drawioy etaient deja commites (64f5a27), identiques au working tree. - 5 docs P1 produits via 2 agents (expert-merise-agile + architect), puis normalises : MCT, MLT, use-cases, state-commande, sequence-passer-commande.
- Machine a etats de commande unifiee : resolution d'une contradiction qui preexistait entre
dictionary.md,PROJECT_CONTEXT.mdet le brief initial. Vocabulaire desormais coherent sur toute la doc.
Etat Git actuel (post-Session 7)
Repo : /home/acadenice/corentin_wakdo/
Branche courante : feat/p1-conception (rien commite cette session)
Working tree P1 (untracked, a commiter apres validation drawio) :
docs/merise/mcd.md (MCD, refs encore vers SVG Mermaid - cf. pivot drawio non termine)
docs/merise/mct.md (NEW - 24 operations metier)
docs/merise/mlt.md (NEW - preconditions/regles/postconditions)
docs/uml/use-cases.md (NEW)
docs/uml/state-commande.md (NEW)
docs/uml/sequence-passer-commande.md (NEW)
docs/merise/_diagrams/*.mmd + *.svg (Mermaid leftover, a supprimer si on finit le pivot drawio)
Working tree modifie (tracked) :
docs/PROJECT_CONTEXT.md (ligne statut realignee sur machine canonique)
.drawio : commites sur feat/p1-conception (clean), en attente validation visuelle user sur le site drawio.
Hors-scope BYAN (persistants, jamais commites) :
.claude/CLAUDE.md, .claude/rules/byan-agents.md, Makefile, package.json, package-lock.json
Decision majeure : machine a etats de commande (CANONIQUE)
Trois vocabulaires se contredisaient (ENUM dictionnaire avec paiement / PROJECT_CONTEXT sans paiement / noms FR introduits par erreur dans le brief Merise). Tranche par le user :
- Deux phases : le client compose (
pending_payment) PUIS paie (paid), apres quoi la commande passe en preparation. Le paiement EXISTE dans le cycle. - Termes en anglais (code-facing), valeurs ENUM du dictionnaire.
- Machine retenue :
pending_payment -> paid -> preparing -> ready -> delivered cancelledatteignable depuis tout etat non remis (pending_payment,paid,preparing,ready) : annulable a tout moment tant que non livree (modification / annulation / remboursement client).deliveredetcancelledfinaux.
Applique partout : dictionary.md (deja correct), PROJECT_CONTEXT.md (corrige ligne 61), mct.md, mlt.md, state-commande.md, use-cases.md, sequence-passer-commande.md.
Autres decisions actees Session 7
| Decision | Contexte |
|---|---|
| Outil diagramme MCD = drawio | User valide les 4 .drawio lui-meme sur le site (pas encore valides). Pivot Mermaid->drawio a finir cote pipeline + refs mcd.md |
| Pas de parcours employe dedie | Les employes sont couverts par le diagramme de cas d'utilisation (use-cases) + diagramme d'etats. Ockham, evite le doublon |
| Production parallele en respectant les dependances | On fait ce qui ne depend PAS du MCD (dependance nulle ou faible). On NE fait PAS ce qui en depend moyennement ou fortement (MLD, class-diagram) tant que les .drawio ne sont pas valides |
| MOT saute (rappel) | Coherent Session 4 (raccourci agile MCT -> MLT direct) |
Decisions secondaires EN SUSPENS (remontees par l'agent Merise, a trancher avant MLD)
source(canal : kiosk/comptoir/drive) vsmode_consommation(fiscal : sur_place/a_emporter/drive) : deux dimensions distinctes.sourceest absent du dictionnaire et du MCD. A ajouter avant de generer le DDL.user_idsurcommande: aucune tracabilite de l'equipier qui saisit / prend en charge / livre. A amender dans le MCD si stats par equipier souhaitees.
(Points mineurs documentes dans mct.md section 14 et mlt.md section 13 : service_day non materialise, etc.)
A faire lors de la reprise (ordre recommande)
- User valide les 4
.drawiosur le site drawio (preview Markdown ne rend pas Mermaid sans extension ; les .drawio/.svg s'affichent en revanche). - Trancher les 2 decisions secondaires (
sourcevsmode_consommation,user_idsur commande) - elles debloquent le MLD + class-diagram. - Finir le pivot drawio (si confirme) : cible Makefile
docs-render-drawio(imagejgraph/drawiodispo localement), regenerer les SVG depuis les .drawio, reecrire les refs dans mcd.md (actuellement vers SVG Mermaid), supprimer les.mmd/.svgMermaid. - Produire MLD + class-diagram une fois le MCD valide et les decisions secondaires tranchees.
- Commiter le lot P1 conception (option : 1 commit par doc) sur
feat/p1-conception, puis PR versdev(vigilance : base =dev, pasmain).
Commande exacte pour reprendre
cd /home/acadenice/corentin_wakdo
git status
git branch --show-current # attendu : feat/p1-conception
ls docs/merise/ # mcd.md, mct.md, mlt.md, dictionary.md
ls docs/uml/ # use-cases.md, state-commande.md, sequence-passer-commande.md
Session precedente : 2026-05-09 (Session 6 - drawio + P5 front complet en remote control)
Vue d'ensemble
Session ~3-4h en remote control mobile qui a couvert 2 gros chantiers et un long detour sur l'automation des PRs :
- Pivot Mermaid -> drawio sur le MCD : 4 fichiers
.drawioXML generes pour gain de controle layout (planarite du global non resoluble par mmdc) - Front P5 complet anticipe : 2 runs d'agent UX (Sally) ont produit 7 pages HTML kiosk + 7 modules JS vanilla + JSON fallback statique. Flux complet welcome -> confirmation, live sur le vhost.
- Setup automation PR via API : detour sur fine-grained PATs (3 tentatives KO sur policy org AcadeNice "approval required"), resolu avec un classic PAT
ghp_en attendant l'approbation admin lundi.
2 PR ouvertes sur GitHub :
- #4 ready : front P5 complet (7 commits)
- #5 draft : 4 .drawio sources, en attente cleanup et suite Merise/UML
Etat Git actuel (post-Session 6)
Repo : /home/acadenice/corentin_wakdo/
Remote : git@github-wakdo:AcadeNice/wakdo_corentin.git
Branches :
main 00a3f82 (v0.1.0)
dev 68db2ee
feat/p1-conception 64f5a27 (PR #5 draft : 4 .drawio committed)
feat/p5-front-landing 6a7e772 (PR #4 ready : 7 commits P5 complet) <- HEAD post-session
feat/infra-docker b09c461 (mergee, conservee)
feat/p1-assets-import 24e733b (mergee, conservee)
feat/p1-stubs-and-dictionary d1a9876 (mergee, conservee)
Tags :
v0.1.0 00a3f82 Infrastructure foundation
Working tree out-of-scope (BYAN, persistent depuis sessions precedentes) :
.claude/CLAUDE.md, .claude/rules/byan-agents.md, Makefile
package.json, package-lock.json
docs/SESSION_RESUME.md (ce fichier)
Working tree P1 (uncommitted, voyage entre branches lors des switches) :
docs/merise/mcd.md
docs/merise/_diagrams/*.mmd (Mermaid leftover, a supprimer apres render drawio)
docs/merise/_diagrams/*.svg (Mermaid render, idem)
PRs ouvertes
| # | Titre | Branche | Base | Statut |
|---|---|---|---|---|
| 4 | feat(front): P5 kiosk complete flow with vanilla JS and JSON fallback | feat/p5-front-landing |
dev |
Ready for review |
| 5 | docs(merise): MCD diagrams in drawio XML (4 files) | feat/p1-conception |
dev |
Draft |
Decisions actees Session 6
| Decision | Contexte |
|---|---|
| Switch Mermaid -> drawio pour MCD | Planarite du global non resoluble par mmdc auto-layout, controle manuel requis |
| 4 .drawio separes (1 par diagramme) | Plus simple a editer et diff que multi-page |
| Front P5 anticipe pendant P1 | Data contract gele par brief ecole (JSON sources), front consomme JSON = consomme future API au mapping pres |
Classic PAT (ghp_) au lieu de fine-grained AcadeNice |
Org AcadeNice policy "approval required", admin pas dispo le weekend |
Branche front renommee p1 -> p5 |
Front borne = livrable P5 per plan SDLC (independant de la phase de realisation) |
| Auto-validation 7 checks par l'agent | Remote control mobile = pas de validation visuelle facile, agent doit s'auto-verifier |
Mode JSON fallback statique dans borne/data/ |
Apache bind-mount ne sert pas _sources/, copie statique = solution simple. Swap point unique dans data.js pour P4 |
| TVA 10% (taux restauration FR 2024 simplifie) | TODO P3 : valider avec comptable les variations sur place vs a emporter, alcool, etc. |
gh dans Docker = mauvaise idee |
Stack Docker = runtime app, pas dev tooling. gh ou curl appartient a l'host. |
Token GitHub stocke dans .env (gitignore) |
Standard, pas de leak en commits, lu via source .env au moment du curl |
Ce qui a ete fait chronologiquement
Bloc 1 - Pivot Mermaid -> drawio + 4 sources XML
- Decision drawio uniquement, 4 fichiers separes, manual layout
- Generation des 4 fichiers
.drawioXML avec entites + cardinalites Merise(min,max)a partir des sources Mermaid - Commit
64f5a27:docs(merise): add drawio XML sources for MCD diagrams
Bloc 2 - 1er agent UX (welcome + categories scaffold)
- Spawn agent UX-designer (Sally) en background avec scope 2 ecrans (welcome + categories), flag
isolation: "worktree" - L'agent a base sa branche sur
feat/p1-conceptionau lieu dedev(le worktree n'a pas vraiment isole comme attendu) - Rebase
feat/p1-front-landing --onto dev 64f5a27pour droper le commit drawio comme parent - Renommage
feat/p1-front-landing->feat/p5-front-landing(front borne = livrable P5)
Bloc 3 - Setup automation PR (long detour sur les PATs)
- Push des 2 branches (SSH agent socket
/tmp/ssh-Evc7jT0fk2rs/agent.2611024) - Tentative
ghCLI dans Docker -> mauvaise idee, abandonne - Tentative fine-grained PAT #1 : Resource owner = Imugiii -> 404 sur wakdo_corentin (org repo invisible pour PAT a owner perso)
- Fine-grained PAT #2 : meme probleme (Resource owner encore = Imugiii)
- Fine-grained PAT #3 avec Resource owner = AcadeNice -> token en "Pending review" (org policy "approval required")
- Fallback classic PAT (
ghp_) -> fonctionne des generation, scoperepo, admin sur le repo - PR #4 (front ready) + PR #5 (drawio draft) creees via
POST /repos/AcadeNice/wakdo_corentin/pulls
Bloc 4 - 2e agent UX (P5 complet)
- Spawn agent UX en background sur
feat/p5-front-landingavec scope etendu : 5 nouvelles pages + JS state + JSON fallback - Auto-validation 7 checks dans le brief (assets exist, links resolve, JSON valid, HTML closed, JS syntax, http server e2e, JSON fetch)
- Livrable : 5 pages HTML, 7 modules JS, 2 JSON normalises copies dans
borne/data/, CSS etendu de 438 -> 1257 lignes - 6 commits thematiques (
6f5daca->6a7e772), 7/7 auto-checks PASS - Push, mise a jour PR #4 (titre + body) via
PATCH /repos/.../pulls/4 - Test live kiosk : les endpoints repondent 200 (welcome, categories, products, product, cart, payment, confirmation, JSON, CSS, JS, images)
Commande exacte pour reprendre
cd /home/acadenice/corentin_wakdo
git status
git branch --show-current
# Si HEAD = feat/p5-front-landing : tu peux tester le front sur https://corentin-wakdo.stark.a3n.fr/
# Pour reprendre P1 :
git checkout feat/p1-conception
A faire lors de la reprise (ordre recommande)
- Review visuelle PR #4 : tester le flux kiosk complet sur https://corentin-wakdo.stark.a3n.fr/, valider, merger dans
dev(via web ou via API) - Drawio render automatique : ajouter cible Makefile
make docs-render-drawioqui utilise le containerrlespinasse/drawio-exportpour generer les SVG depuis les.drawioXML. Evite l'export manuel sur drawio web (galere sur mobile). - Continuer P1 conception sur
feat/p1-conception:docs/merise/mct.mddocs/merise/mlt.mddocs/merise/mld.mddocs/uml/class-diagram.mddocs/uml/use-cases.mddocs/uml/state-commande.mddocs/uml/sequence-passer-commande.md
- Commit final mcd.md : une fois les SVG drawio generes, commit
mcd.md+ suppression des.mmd/anciens.svgMermaid + Makefile mis a jour (dropdocs-rendermmdc, garder uniquementdocs-render-drawio) - Passage PR #5 draft -> ready (via PATCH API) quand tout le P1 conception est dedans
- Hygiene secu PATs : revoquer dans GitHub Settings :
- 3 fine-grained
github_pat_...(suffixes BE4y, UiZc, ljeC) - classic
ghp_Rr5EkM4...(a rotater quand fine-grained AcadeNice approuve par admin lundi)
- 3 fine-grained
Note technique - isolation worktree
Le flag isolation: "worktree" sur l'Agent tool n'a pas cree de vrai worktree isole - les agents ont travaille directement sur le main repo (git worktree list ne montre qu'une entree). Pas grave en pratique mais a savoir pour les prochains spawns : instruire explicitement l'agent de ne pas switch de branche dans le main repo, ou de bosser en branche dediee pre-checked-out.
Session precedente : 2026-04-30 soir (Session 5 - notes perso + demarrage P1 conception + setup pipeline diagrammes)
Vue d'ensemble
Session moyenne (~3h) qui a couvert :
- Cloture P1 dictionnaire : commit + push + PR #3 mergee dans
dev - 4 notes perso ecrites (gitignore) : apache-fastcgi-pitfalls, docker-network-pools-rfc1918, enum-vs-table-reference, merise-yagni-quantite + index README mis a jour
- Demarrage P1 conception sur nouvelle branche
feat/p1-conception(renommee depuisfeat/p1-merise-conceptionpour inclure UML) - MCD redige (
docs/merise/mcd.md) avec 3 sous-domaines (Catalogue/Commande/RBAC) en Mermaid + tableau recap cardinalites Merise - Pipeline mmdc setup : .mmd sources + SVG generes +
make docs-rendertarget - Blocage layout MCD global : 10 entites + 10 associations = probleme planarite intrinseque, decision laissee en suspens
Aucun commit fait sur la branche feat/p1-conception — tout reste dans le working tree pour reprise propre.
Etat Git actuel (post-Session 5)
Repo : /home/acadenice/corentin_wakdo/
Remote : git@github-wakdo:AcadeNice/wakdo_corentin.git
Branches :
main 00a3f82 (v0.1.0)
dev 68db2ee (= main + PR#1 + PR#2 + PR#3 mergees)
feat/infra-docker b09c461 (mergee, conservee)
feat/p1-assets-import 24e733b (mergee, conservee)
feat/p1-stubs-and-dictionary d1a9876 (mergee via PR#3, conservee)
feat/p1-conception 68db2ee (NOUVELLE, ZERO COMMIT, working tree only)
Tags :
v0.1.0 00a3f82 Infrastructure foundation
Working tree sur feat/p1-conception (a commit a la prochaine session) :
docs/merise/mcd.md (NEW - 411 lignes)
docs/merise/_diagrams/mcd-global.mmd (NEW)
docs/merise/_diagrams/mcd-global.svg (NEW)
docs/merise/_diagrams/mcd-catalogue.mmd (NEW)
docs/merise/_diagrams/mcd-catalogue.svg (NEW)
docs/merise/_diagrams/mcd-commande.mmd (NEW)
docs/merise/_diagrams/mcd-commande.svg (NEW)
docs/merise/_diagrams/mcd-rbac.mmd (NEW)
docs/merise/_diagrams/mcd-rbac.svg (NEW)
Makefile (modified - target docs-render ajoute)
docs/notes/README.md (modified, gitignore - 7 entries ajoutees)
docs/notes/apache-fastcgi-pitfalls.md (NEW, gitignore)
docs/notes/docker-network-pools-rfc1918.md (NEW, gitignore)
docs/notes/enum-vs-table-reference.md (NEW, gitignore)
docs/notes/merise-yagni-quantite.md (NEW, gitignore)
Working tree out-of-scope (BYAN, deja modifies en sessions precedentes) :
.claude/CLAUDE.md
.claude/rules/byan-agents.md
package.json, package-lock.json
docs/SESSION_RESUME.md
Decisions actees Session 5
| Decision | Contexte |
|---|---|
Branche renommee feat/p1-conception (au lieu de feat/p1-merise-conception) |
Pour inclure UML dans le scope de la PR |
| UML ajoute au scope P1 conception | RNCP 37805 attend Merise + UML, pas que Merise |
| Granularite commits PR : option α (1 commit par doc) | Coherent avec l'historique, squashable en fin de PR si besoin |
| Pipeline diagrammes : option B (mmdc local + SVG embed) | Rendu portable Cursor/GitHub/PDF/Notion, regenerable via make docs-render |
| Ecriture des 4 notes perso AVANT le travail Merise | Sujets frais dans le contexte (Session 4 + dictionnaire) |
| Auteur des notes = "BYAN" | Coherent avec section 17 PROJECT_CONTEXT (transparence methodologie) |
4 hedgings appliques (toujours/forcement -> tend a/implique) |
Hook PreToolUse fact-check intransigeant |
Decision EN SUSPENS (a trancher en premier la prochaine session)
Layout du diagramme global MCD : avec 10 entites et 10 associations (dont
2 polymorphiques sur LIGNE_COMMANDE -> PRODUIT et MENU), il y a un probleme
de planarite : impossible de placer toutes les entites sans croiser au moins
2 lignes. Mermaid auto-layout galere, Excalidraw manuel n'aide pas vraiment.
3 options en attente d'arbitrage :
- A. Drop le global — supprimer section 3 du MCD, garder section 6 (tableau recap des cardinalites) + section 4 (3 sous-domaines Mermaid propres). Coherent avec l'approche Merise (decomposer si > 5 entites). Defendable au jury : "j'ai decompose, tableau recap = vue integree".
- B. Excalidraw manuel — refaire le global a la main dans Excalidraw,
export
.excalidraw.svg(avec scene embedee), embed dans le MCD. Coute 20-30 min de layout manuel, perd la regen automatique. - C. Garder Mermaid en l'etat — assumer que le layout est croise mais jouer le compromis "decomposition prime sur visuel global".
Le user a dit "le choix n'est pas encore fait" (Session 5 fin de soiree, fatigue sur le sujet). A reprendre tete reposee.
Ce qui a ete fait chronologiquement
Bloc 1 - Cloture dictionnaire (commit + PR)
- Verification etat initial : branche
feat/p1-stubs-and-dictionaryavecb8f7d35(stubs+fixes) commit,docs/merise/dictionary.mduncommitted - Commit
d1a9876:docs(merise): data dictionary v0.1 - 10 entities + Mermaid ER diagram + 7 modeling notes - Push branche, PR #3 ouverte manuellement (gh CLI absent), mergee sur
dev git fetch + checkout dev + merge --ff-only origin/dev: sync OK sur68db2ee
Bloc 2 - 4 notes perso (gitignore)
- Bascule sur
Readau lieu degrep/sedapres blocage du hooktool-failure-guardsur "internal error" string presente dansvhost.conf(pattern legitime du commentaire, faux positif Bash output) apache-fastcgi-pitfalls.md(405 lignes) - 3 pieges Session 4 (DirectoryIndex, allowed_clients, R=200) + Q&A jurydocker-network-pools-rfc1918.md(376 lignes) - saturation pools Docker sur stark, choix192.168.148.0/24, RFC 1918, Q&A juryenum-vs-table-reference.md(381 lignes) - matrice de decision ENUM vs table, application aux 4 ENUMs Wakdo, Q&A jurymerise-yagni-quantite.md(337 lignes) - YAGNI applique amenu_produit, audit source ecole 13 menus mono-portion, Q&A jurydocs/notes/README.mdindex mis a jour : 7 nouvelles entrees (3 Session 4 deja redigees + 4 nouvelles)
Bloc 3 - Setup branche conception + cadrage
- Branche
feat/p1-merise-conceptioncreee depuisdev, puis renommee enfeat/p1-conceptionapres discussion sur l'ajout UML au scope - Decision : 8 documents prevus pour la PR :
- Merise : MCD, MCT, MLT, MLD (4 docs dans
docs/merise/) - UML : classes, use cases, etats, sequence (4 docs dans
docs/uml/)
- Merise : MCD, MCT, MLT, MLD (4 docs dans
docs/uml/cree
Bloc 4 - MCD redige + setup pipeline diagrammes
- Premier draft MCD avec 4 diagrammes ASCII art (global + 3 sous-domaines)
- tableau recap cardinalites Merise
(0,N)/(1,1)
- tableau recap cardinalites Merise
- User trouve l'ASCII moche -> bascule sur Mermaid
erDiagraminline - User ne voit pas le rendu Mermaid dans Cursor (pas d'extension installee) -> bascule sur SVG via mmdc
- Setup
docs/merise/_diagrams/: 4 fichiers.mmdextraits + 4 SVG generes vianpx mmdc - MCD edite : 4 blocs Mermaid remplaces par
<img src="_diagrams/*.svg"> - Makefile : target
docs-renderajoute, scanne tous lesdocs/**/_diagrams/*.mmddu projet, regen SVG (testee, OK 4/4) - User constate que le global a des lignes croisees, tente Excalidraw, n'arrive pas a un layout logique -> decision laissee en suspens
Commande exacte pour reprendre
cd /home/acadenice/corentin_wakdo
git status # confirmer working tree intact
git branch --show-current # doit etre feat/p1-conception
git log --oneline dev..HEAD # doit etre vide (zero commit sur la branche)
ls docs/merise/ # mcd.md + _diagrams/ presents
ls docs/notes/ # 4 notes Session 5 + README maj
A faire lors de la reprise (ordre recommande)
-
Trancher le layout MCD global (option A / B / C ci-dessus). Si A, editer mcd.md pour supprimer section 3, decrementer les numeros, et supprimer
_diagrams/mcd-global.{mmd,svg}. Si B, faire le travail Excalidraw manuel. Si C, ne rien faire et continuer. -
Commit le MCD (option α : 1 commit par doc) :
git add docs/merise/mcd.md docs/merise/_diagrams/ Makefile git commit -m "docs(merise): MCD v0.1 + pipeline mmdc -> SVG via make docs-render" -
Continuer P1 conception, dans l'ordre :
docs/merise/mct.md- operations metier + acteurs + fluxdocs/merise/mlt.md- workflow logique (preconditions / regles / postconditions)docs/merise/mld.md- schema relationnel formeldocs/uml/class-diagram.md- vue OOP (prepare PHP P2)docs/uml/use-cases.md- acteurs + goals (kiosk client, manager, ...)docs/uml/state-commande.md- machine a etatscommande.statutdocs/uml/sequence-passer-commande.md- flux passer commande
-
Push + PR vers
devquand les 7 docs restants sont commit. Vigilance : verifierbase = dev(pasmain!). -
Apres merge : continuer P1 implementation (DDL + seed + fallback) sur une branche
feat/p1-implementationseparee.
Session precedente : 2026-04-30 jour (Session 4 etendue - smoke test infra + import assets + P1 demarre)
Vue d'ensemble
Session tres longue (~6h cumulees) qui a couvert 3 grandes phases en une seule journee :
- Smoke test infra Docker sur le serveur stark :
make initvalide bout en bout, 4 services healthy, certs Let's Encrypt provisionnes - Import assets ecole : 71 images normalisees + 2 JSON sources + maquette Figma PDF
- Demarrage P1 Merise : stubs unblock-403 + dictionnaire de donnees v0.1 (10 entites)
3 PR ont ete fusionnees (1 incident main->dev recupere) et 1 PR reste ouverte (la branche de la 3e phase n'est pas encore push).
Etat Git actuel (post-Session 4)
Repo : /home/acadenice/corentin_wakdo/
Remote : git@github-wakdo:AcadeNice/wakdo_corentin.git
Branches :
main 00a3f82 (v0.1.0 - infra foundation)
dev 84d2559 (= main + PR#2 assets)
feat/infra-docker b09c461 (mergee dans main via PR#1, conservee)
feat/p1-assets-import 24e733b (mergee dans dev via PR#2, conservee)
feat/p1-stubs-and-dictionary b8f7d35 (LOCAL UNIQUEMENT - NON PUSHEE)
+ dictionnaire UNCOMMITTED dans le working tree
Tags :
v0.1.0 00a3f82 Infrastructure foundation (annotated, pushe)
Working tree out-of-scope (volontairement non commit) :
.claude/CLAUDE.md, .claude/rules/* (modifies hors-projet, BYAN)
package.json, package-lock.json (BYAN)
docs/SESSION_RESUME.md (ce fichier - local perso)
Vue chronologique des PR
00a3f82 (main, dev, v0.1.0) Merge PR #1 from feat/infra-docker
- INCIDENT : PR ouverte par defaut sur 'main' au lieu de 'dev'
- REMEDIATION : git checkout dev && git merge --ff-only origin/main && git push origin dev
- LECON : verifier le selecteur 'base branch' sur GitHub avant 'Create pull request'
- 9 commits infra : compose, dockerfiles, smoke test fixes, FQDN switch, journal session 4
84d2559 (dev) Merge PR #2 from feat/p1-assets-import
- PR sur la bonne base 'dev' cette fois
- 1 commit : import des 2 JSON sources + 71 images normalisees + maquette PDF
Ce qui a ete fait (chronologique session)
Phase 1 - smoke test infra (avant pause)
- Conflit
.envBYAN/Wakdo traite par fusion en 1 fichier (gitignore) - Switch FQDN
acadenice.fr->stark.a3n.fr(zone wildcard existante, evite la provisioning DNS prerequise par le challenge HTTP-01 de Traefik) - Smoke
make initcasse 3 fois et corrige :- Subnet explicite
192.168.148.0/24(pools Docker satures) init: truesur cron (dcron PID 1 setpgid)- Healthz statique dans
/usr/local/apache2/htdocs/(RewriteRule R=200 declenchait ErrorDocument template)
- Subnet explicite
- Validation HTTPS externe : 4 services healthy, certs OK,
/healthzisole - Journal session ecrit (
docs/journal/2026-04-30--smoke-test-infra.md) - PR #1 -> incident main au lieu de dev -> remediation FF dev=main
- Tag
v0.1.0annote sur le merge commit - Memoire
feedback_no_absolutes.mdenregistree (hook fact-check sensible)
Phase 2 - import assets ecole
- Drop zone
docs/_inbox/recue (9 Mo, 71 images + 2 JSON + 1 PDF + 1 readme) - Diagnostic : naming "wacdo" vs notre "Wakdo", casse incoherente, 7 typos dans JSON
- Rangement final :
docs/merise/_sources/(2 JSON + source-school.md provenance)docs/design/(maquette PDF + README pointant Figma)src/public/borne/assets/images/(71 images normalisees kebab-case lowercase)
- Workaround
chownvia container ephemere (src/ etait owned root par Docker bind-mount) - PR #2 -> dev (workflow correct cette fois)
Phase 3 - demarrage P1 Merise
- Decisions cadrage P1 actees :
- MOT skippe (raccourci agile MCT -> MLT direct)
- Composition flexible (
menu_produitavecroleetposition) - Pas de
quantitesur menu_produit (YAGNI - 13 menus mono-portion) - 9 entites + 1 jointure RBAC : Categorie, Produit, Menu, MenuProduit, Commande, LigneCommande, User, Role, Permission, RolePermission
- Pas de stock numerique (juste
est_disponibleboolean) - Pas de stats agregees (live queries)
- Pas d'allergenes/nutrition pour MVP
- Stubs minimaux pour debloquer le 403 :
src/public/borne/index.html(HTML statique avec logo, vhost kiosk)src/public/admin/index.php(PHP qui prouve la chaine FastCGI E2E)
- 2 bugs infra exposes par les stubs et fixes :
- Apache
DirectoryIndexne contenait pasindex.php(admin renvoyait 403) - PHP-FPM
listen.allowed_clients = anyrejete par PHP 8.3 (toutes les connexions Apache->PHP-FPM rejetees, FastCGI cassait silencieusement)
- Apache
- Validation HTTPS externe : kiosk -> 200 HTML, admin -> 200 PHP rendu (PHP_VERSION et timestamp dynamique substitues)
- Commit
b8f7d35:feat(stubs): unblock 403 with kiosk and admin index pages, plus FastCGI fixes - Dictionnaire de donnees v0.1 redige (
docs/merise/dictionary.md) :- ~340 lignes, 10 entites detaillees
- Diagramme entites-relations en Mermaid (rendu GitHub natif)
- 7 notes de modelisation (FLOAT vs cents, ENUM vs table, STI, polymorphisme, audit fields, RFC 5321 emails, etc.)
- Cross-validation avec
PROJECT_CONTEXT.mdet source ecole
- 3 notes techniques perso (
docs/notes/, gitignore) :rbac-roles-permissions.md: pattern RBAC dynamique vs statique, UI matrice, Q&A jurymonetary-int-cents.md: INT centimes + TVA pour mille, Goldberg ACM 1991, Stripe convention, 5 piegespolymorphic-fk-snapshots.md: 2 colonnes nullables + discriminator + snapshots, Karwin SQL Antipatterns, integrite historique commandes
- Memoire
feedback_notes_author.mdmise a jour : auteur des notes = "BYAN" (pas un nom de LLM specifique), coherent avec la transparence projet section 17 PC
En cours (a reprendre)
Branche locale feat/p1-stubs-and-dictionary avec 1 commit fait + dictionnaire UNCOMMITTED.
Commande exacte pour reprendre
cd /home/acadenice/corentin_wakdo
git status # confirmer ?? docs/merise/dictionary.md
git branch --show-current # doit etre feat/p1-stubs-and-dictionary
git log --oneline dev..HEAD # voir b8f7d35 (stubs+fixes)
A faire lors de la reprise
-
Commit le dictionnaire :
git add docs/merise/dictionary.md git commit -m "docs(merise): data dictionary v0.1 - 10 entities + Mermaid ER diagram + 7 modeling notes Bottom-up derivation from school JSON sources + PROJECT_CONTEXT business rules. Covers : Categorie, Produit, Menu, MenuProduit, Commande, LigneCommande, User, Role, Permission, RolePermission. Decisions documented : prices in INT cents, VAT in per-mille, polymorphic FK with snapshots on ligne_commande, dynamic roles vs static permissions for RBAC." -
Push + PR :
SSH_AUTH_SOCK=/tmp/ssh-Evc7jT0fk2rs/agent.2611024 git push -u origin feat/p1-stubs-and-dictionaryPuis ouvrir PR via :
https://github.com/AcadeNice/wakdo_corentin/compare/dev...feat/p1-stubs-and-dictionary?expand=1VIGILANCE : verifier base =dev(pasmain!) avant de cliquer Create. -
Continuer P1 sur une nouvelle branche
feat/p1-merise-models(apres merge de la precedente) ou sur la meme branche etendue. Suite des etapes :- MCD :
docs/merise/mcd.mdavec un diagramme Mermaid plus formel (entites + associations + cardinalites min/max), distinct du diagramme preview du dictionnaire - MCT :
docs/merise/mct.md- les operations metier (valider commande, encaisser paiement, marquer pret, ...) - MLT :
docs/merise/mlt.md- workflow logique de chaque traitement (preconditions, regles, postconditions, sorties) - MLD :
docs/merise/mld.md- schema relationnel formel - DDL :
db/migrations/0001_init_schema.sql- SQL CREATE TABLE concret - Seed :
db/seeds/0001_demo_data.sql- INSERT des 9 categories + 53 produits + 13 menus a partir des JSON sources, avec normalisation des prix en centimes - Export fallback JSON :
scripts/export-fallback.{sh|php}qui generesrc/public/borne/data/*.jsondepuis le seed (pour mode "Bloc 1 isole")
- MCD :
-
Notes perso restantes a rediger (basse priorite, peut s'etaler sur plusieurs sessions) :
enum-vs-table-reference.md: quand utiliser ENUM vs table referentielledocker-network-pools-rfc1918.md: pool saturation Docker, choix subnet expliciteapache-fastcgi-pitfalls.md: les 3 bugs infra de cette session (DirectoryIndex, listen.allowed_clients, RewriteRule R=200)merise-yagni-quantite.md: application concrete de YAGNI sur menu_produit
-
Optionnels post-merge (peuvent aller sur une branche
feat/infra-polishseparee apres P1) :- Investiguer redirect HTTP->HTTPS qui retourne 404 (interaction avec middleware global du Traefik d'hote)
- Unifier le style init Docker (wakdo-app a tini explicite, wakdo-cron a
init: true- incoherence stylistique a accepter ou unifier)
Workflow git en vigueur
- Convention :
feat/* -> dev(squash merge),dev -> main(avec tagvX.Y.Zannote) - Vigilance PR : verifier explicitement
base branch = dev(le defaut GitHub estmain) - Branches mergees : conservees comme trace historique
- Procedure d'archive si une branche est abandonnee non-mergee :
git tag -a archive/feat-xxx <branch-tip-sha> -m "abandoned: <reason>" git push origin archive/feat-xxx git push origin --delete feat-xxx git branch -D feat-xxx - Tags previsionnels : v0.1.0 (infra), v0.2.0 (P2 stubs+auth+CRUD basic), v0.3.0 (CRUD admin complet), ..., v1.0.0 (livrable jury)
Decisions structurelles actees Session 4
| Decision | Pourquoi |
|---|---|
Fusion .env BYAN+Wakdo |
Outil tiers lit .env du cwd, separation .env.wakdo plus risquee |
FQDN sur *.stark.a3n.fr |
Wildcard DNS existant, evite provisioning prerequis HTTP-01 |
Subnet explicite 192.168.148.0/24 (RFC 1918) |
Pools Docker satures sur hote partage |
init: true sur cron |
dcron en PID 1 sans init reaper boucle sur setpgid Operation not permitted |
| Healthz statique htdocs | RewriteRule R=200 declenche template ErrorDocument |
APP_ENV=dev + APP_DEBUG=true |
Phase de construction, flip vers prod avant demo jury |
| Naming "wacdo" (source) vs "Wakdo" (projet) | wacdo preserve dans _sources/ pour tracabilite ecole |
| Casse images normalisee kebab-case lowercase | Anti-piege case-sensitive Linux dans Docker |
| MOT (modele organisationnel des traitements) skippe | Raccourci agile MCT -> MLT direct |
Composition flexible menu_produit (role+position) |
Defendable evolution future sans refacto |
Pas de quantite sur menu_produit |
YAGNI - 13 menus mono-portion |
| Prix en INT centimes + TVA en pour mille | Anti-FLOAT IEEE 754 (Goldberg ACM 1991) |
Snapshots libelle+prix sur ligne_commande |
Integrite historique audit |
Polymorphisme ligne_commande -> produit OR menu |
2 cols nullable + discriminator + 2 FKs reelles |
| RBAC : roles+role-permission dynamiques, permissions statiques | Permissions liees au code (declarees en migration) |
| Pas de stock numerique en MVP | Juste est_disponible boolean |
| Pas de stats agregees | Live queries SUM/GROUP BY suffisent |
| Pas d'allergenes/nutrition | Hors source ecole, hors scope MVP |
| ENUM pour valeurs metier stables | mode_consommation, statut, role -> 3-7 valeurs, ALTER si extension |
| Auteur notes perso = "BYAN" | Coherent avec section 17 PC (transparence methodologie) |
Prochaines etapes (apres merge feat/p1-stubs-and-dictionary -> dev)
P1 Conception Merise (semaines 2-3) - EN COURS
1. Dictionnaire de donnees v0.1 ECRIT (a commit)
2. MCD a faire
3. MCT a faire
4. (MOT skippe)
5. MLD a faire
6. MLT a faire
7. DDL a faire
8. Seed data a faire
9. JSON fallback a faire
P2 Back squelette (semaines 4-6)
- Core (Router, Autoloader, DB)
- Auth (sessions PHP fichier + argon2id)
- RBAC (Authorization service)
- Front controller `index.php`
P3 CRUD admin (semaines 7-10)
- CRUD produits, menus, categories
- UI roles + assignment matrice permissions
- CRUD users
P4 API REST (semaines 11-12)
- Endpoints /api/categories, /api/menus, /api/produits, /api/orders
- CORS + tests
P5 Front borne (semaines 13-16)
- Integration maquette + Ajax + a11y RGAA
- Mode JSON-seuls (fallback) + mode API-connecte
P6 Tests + finition (semaines 17-18)
P7 DevOps final (semaine 19) - GitHub Actions, crons, docs
P8 Prep soutenance (semaine 20)
Fichiers cles a consulter a la reprise
| Fichier | Contenu |
|---|---|
docs/PROJECT_CONTEXT.md |
Source de verite projet (FQDN sur stark.a3n.fr, section 17 transparence IA) |
docs/_ref/rncp-37805-referentiel.pdf |
Referentiel RNCP officiel |
docs/_ref/rncp-37805-index.md |
Index texte compact des criteres (cherchable) |
docs/journal/README.md |
Template + index des retros (3 entrees) |
docs/journal/2026-04-30--smoke-test-infra.md |
Retro Session 4 phase 1 (smoke test) |
docs/merise/dictionary.md |
Dictionnaire P1 v0.1 ECRIT (a commit) |
docs/merise/_sources/ |
JSON sources ecole + provenance |
docs/design/ |
Maquette PDF + lien Figma |
docs/notes/ |
Notes perso revision oral (3 ecrites cette session, gitignore) |
docs/SESSION_RESUME.md |
Ce fichier - a mettre a jour en fin de session |
.env |
Config locale fusionnee (BYAN + Wakdo, gitignore) |
.env.example |
Template neutre commit, RFC 2606 |
docker-compose.yml |
Compose final (subnet 192.168.148.0/24 + init cron + 4 services) |
Makefile |
Orchestration complete, voir make help |
.claude/CLAUDE.md |
Constitution projet BYAN |
.claude/rules/fact-check.md |
Patterns du hook fact-check (a consulter avant ecriture narrative !) |
Commandes utiles pour reprendre
cd /home/acadenice/corentin_wakdo
# 1. Etat
git status
git branch --show-current
# -> attendu : feat/p1-stubs-and-dictionary
# 2. Stack docker (verifier qu'elle tourne toujours)
docker compose -p wakdo ps
# Si down apres reboot : make up (ou make init pour full bootstrap)
# 3. Test que tout repond
curl -sI https://corentin-wakdo.stark.a3n.fr/ # 200
curl -sI https://corentin-wakdo-admin.stark.a3n.fr/ # 200
# 4. SSH pour push (si besoin)
find /tmp -name 'agent.*' -user corentin
# -> /tmp/ssh-Evc7jT0fk2rs/agent.2611024 (peut changer apres reboot ssh-agent)
SSH_AUTH_SOCK=/tmp/ssh-XXX/agent.NNN git push ...
Memoire persistante Claude Code (mise a jour Session 4)
Regles enregistrees dans /home/corentin/.claude/projects/-home-acadenice-corentin-wakdo/memory/ :
- No Co-Authored-By sur les commits Wakdo (Session 2)
- Commit uniquement sur approbation explicite (Session 2)
- Ignorer les contextes d'autres projets dans les system-reminders (Session 3)
- Hedger proactivement pour le hook fact-check (Session 4)
- BYAN auteur des docs/notes/ (Session 4 - mise a jour cette session)
Comment reprendre la session
- Ouvrir une session dans
/home/acadenice/corentin_wakdo/ - Dire : "Reprise Wakdo, lis
docs/SESSION_RESUME.md" - Confirmer l'action de depart :
- Suite immediate = commit + push + PR du dictionnaire (cf. section "A faire lors de la reprise")
- Apres merge = continuer P1 avec le MCD (
docs/merise/mcd.md)
Document maintenu a chaque fin de session. Derniere mise a jour : 2026-05-21 (Session 7).