9.1 KiB
9.1 KiB
Ticket Executor - Learnings
Session 2026-03-17 (26 tickets)
T-001 — Secrets .env
- Pattern: Replace secrets with
change_me_in_env_localplaceholder, move real values to.env.local - Gotcha:
.env.localmust contain ALL overridden secrets
T-002 — Security API Gitea
- Pattern: Ajouter
security: "is_granted('ROLE_USER')"sur les opérations ApiResource - Learning: Vérifier d'abord les ressources déjà sécurisées pour ne pas dupliquer
T-003 — SVG Upload
- Pattern: Double protection - bloquer à l'upload (retirer du MIME allowlist) + defense-in-depth (Content-Disposition: attachment au download)
- Learning: Toujours vérifier upload ET download controllers
T-004 — MCP create-task / Repos numérotation
- Gotcha critique: PostgreSQL n'autorise PAS
FOR UPDATEavec des fonctions d'agrégation (MAX) - Fix: Utiliser
pg_advisory_xact_lock()au lieu deFOR UPDATEpour les queries avec agrégation - Pattern: Offset les lock keys (+1000000) pour éviter collisions entre Task et ClientTicket
T-005 — Filter ROLE_CLIENT projects
- Pattern: Créer une Doctrine Extension (
QueryCollectionExtensionInterface+QueryItemExtensionInterface) pour filtrer par relation - Learning: Symfony autoconfigure enregistre l'extension automatiquement
T-006 — Block client doc upload
- Pattern: Vérifier le rôle dans le Processor AVANT de résoudre l'IRI de la tâche
- Learning: Le portail client envoie un
clientTicketIRI (pas detaskIRI), donc le check surtaskIrinon-vide suffit
T-007 — MCP role checks
- Pattern: Injecter
Securitydans chaque Tool, vérifier au début de__invoke() - Learning: 22 tools à modifier - bien séparer ROLE_ADMIN (users/clients) vs ROLE_USER (le reste)
T-009 — Password hashing
- Pattern: Champ
plainPasswordnon-persisté, writable uniquement, hashé dans le Processor - Learning: Modifier aussi le frontend (DTO + composant) quand on renomme un champ API
T-010 — Rate limiting
- Gotcha:
login_throttlingnécessitesymfony/rate-limiterinstallé, pas juste dans composer.json - Learning: Toujours vérifier que les packages sont installés, pas juste déclarés
T-012 — Harmoniser repos numérotation
- Pattern: Aligner les contrats (retourner le max, pas le next) et mettre le +1 côté appelant
- Learning: Vérifier TOUS les appelants d'une méthode renommée
T-015 — useAvatarService
- Learning: Quand on migre vers
useApi(), ajouter la détection FormData pour ne pas écraser le Content-Type multipart
T-020 — i18n
- Pattern: Ajouter
useI18n()dans le setup script avant de pouvoir utilisert()dans le JS - Learning: Les templates peuvent utiliser
$t()directement sans import
T-022 — Retirer twig-bundle
- Pattern: Retirer de composer.json + bundles.php + supprimer config YAML + templates
- Learning: API Platform ne requiert PAS twig, c'est juste suggéré pour Swagger UI
Session 2026-06-19 (LST-56 / 0.1 — Socle back modular monolith)
Contexte
- Ticket exécuté via plan TDD dédié (
docs/superpowers/plans/2026-06-19-lst-56-socle-back.md) délégué à un sous-agent (contexte isolé), pilotage MCP/chrono/vérif depuis la session principale. - 4 tâches, 14 nouveaux tests (110 total, 216 assertions, vert), 4 commits (un par tâche).
Patterns
- Strangler 100 % additif : nouveau noyau
src/Shared/(Domain/Contract, Domain/Module, Domain/Sidebar, Domain/Trait, Application, Infrastructure/{ApiPlatform,Doctrine,Security,Database}) sans toucher au métier —make testreste vert sans migration. - Endpoints DTO purs : logique métier dans classes pures testées unitairement (
ModuleRegistry,SidebarFilter), exposées par Providers API Platform minces (ModulesProvider/SidebarProvider) sur des Resources DTO. - resolve_target_entities : contrat
Shared\Domain\Contract\UserInterfacemappé surApp\Entity\User(sera re-pointé versModule\Core\Useren 1.1). Inert tant qu'aucune entité n'utilise le trait.
Gotchas
- API Platform 4 découvre les Resources sous
src/Shared/...sans configmapping.paths— le 404 anticipé dans le plan ne s'est pas produit, aucun ajout dansapi_platform.yamlnécessaire. - Hook pre-commit php-cs-fixer normalise le style du code fourni dans le plan :
\DateTimeImmutable→DateTimeImmutableimporté, FQN→use,static::createClient()→self::. Pur style, tests inchangés. Ne pas lutter contre. config/reference.php: fichier auto-généré qui apparaît modifié dansgit status— ne jamais le committer.
Time tracking
- Le sous-agent a stoppé lui-même le timer d'implémentation (id 1005, 35 min) — garder le time-tracking sur la session principale pour rester maître du chrono si un sous-agent a accès aux tools MCP lesstime.
Session 2026-06-19 (LST-62 / 0.2 — Socle front : shell + auto-détection layers Nuxt)
Contexte
- Plan TDD dédié (
docs/superpowers/plans/2026-06-19-lst-62-socle-front.md), 7 tasks. Exécution en 3 sous-agents (Task 1 back ; Tasks 2-4 fondations front ; Tasks 5-7 middlewares/layout/i18n), pilotage chrono/MCP/vérif sur la session principale. - 7 commits + 1 commit doc de correction du plan. Back : 115 tests verts (110 + 5 nouveaux cas gate rôle).
Patterns
- Gate de rôle additif dans la sidebar : clé
rolesoptionnelle sur section/item dansconfig/sidebar.php;SidebarFilter::filter($sections, $activeModuleIds, $activeRoles = [])masque sans polluerdisabledRoutes(réservé au filtrage par module).SidebarProviderinjecteSymfony\Bundle\SecurityBundle\Securityet passearray_values($user->getRoles()). ROLE_ADMIN seulement (pas le RBAC fin, qui viendra en 1.1/1.2). - Layout front aligné Starseed (vérifié dans le code Starseed) :
srcDir: '.',dir.layouts/middleware → app/, code transverse auto-importé sousshared/{composables,stores,utils}viaimports.dirsEXPLICITE, scanreaddirSync('modules/')→extends+ dossiersmodules/*/composablesajoutés dynamiquement àimports.dirs.useApi/auth/uidéplacés pargit mv(historique préservé) ;timer.ts/mail.tsrestent dansstores/(métier non migré). - Singletons module-level :
useSidebar/useModulesportent leur état enrefau niveau module ; reset explicite au logout depuisauth.global.ts(l'approche Starseed via callbackonAuthSessionCleared()est une alternative non retenue ici).
Gotchas
nuxt typecheckn'est PAS un gate vert sur ce stack : le baseline Lesstime est rouge (~230 ligneserror TS) et la RÉFÉRENCE Starseed (même Nuxt 4.3.1, même layout) ship en prod avec 325 erreurs. Classes structurelles tolérées :Cannot find name 'ref'/'useApi'/'useRoute'/'navigateTo'/'defineStore'…dansshared/(Nuxt 4 typeshared/sous untsconfig.shared.jsonisolé sans les globals d'auto-import, alors queimports.dirsles expose au RUNTIME — vérifié dans.nuxt/imports.d.ts), erreursnuxt.config.ts(node:fs/process/__dirname, pas de@types/node, compilé au runtime par Nuxt),useApi.ts'Property url'. Le vrai gate = zéroCannot find module '~/shared/…'(= vrai import cassé) + auto-imports présents dans.nuxt/imports.d.ts+ smoke runtime. Un sous-agent consciencieux s'est arrêté à tort sur ces erreurs ("bloqueur irréductible") → toujours vérifier le gate contre la réf Starseed avant de conclure à un blocage.- Vérif backend live > typecheck front : le gate de rôle a été prouvé via curl réel (
/api/login_check→ cookie BEARER →GET /api/sidebar) :alice(ROLE_USER) n'a que la section générale,admin(ROLE_ADMIN) a Administration, non-auth = 401. Plus fiable que le typecheck sur ce stack. - i18n
fr.json: une clé racinesidebarpréexistait (avec unmyTasksorphelin) → fusionner les sous-namespaces plutôt que dupliquer la clé racine (JSON invalide sinon).
Statut / time tracking
- Ticket laissé en "En attente de validation" (4), pas "Terminé" : smoke visuel front (dev server + navigateur) et sign-off du délta cosmétique d'ordre de sidebar (décision 3 du plan) relèvent du PO. Implémentation + AC API validés.
- Time-tracking 100 % sur la session principale cette fois (consigne des sous-agents : ne jamais toucher aux outils
mcp__lesstime__*) — respecté.
Meta-learnings
- Parallélisation: Les tickets touchant des fichiers indépendants peuvent tourner en parallèle sans problème
- Commits concurrents: NE PAS lancer deux sous-agents qui committent sur le même repo en parallèle (collision
.git/index.lock) — séquencer. - Gate de vérif fourni par le plan: si un plan fixe un seuil (ex "typecheck 0 erreur"), le confronter à la réalité du projet/réf AVANT de bloquer dessus ; corriger le plan si le seuil est faux.
- MCP status: Toujours mettre "En cours" AVANT de commencer, "Terminé" APRÈS validation
- PostgreSQL gotchas: Tester les queries SQL avec agrégation + locking sur PostgreSQL, pas MySQL
- Agents: Les agents simples (1-3 fichiers) terminent en ~30s, les complexes (22 fichiers) en ~8min