Méthodologie

Des agents IA écrivent le code.
Notre méthode le rend juste.

Chaque fonctionnalité commence par une story qui fixe les décisions, et les agents codent en suivant la même architecture sur chaque app. Avec ce cadre, environ 90 % du code qu'ils produisent est bon du premier coup. Les 10 % restants, Youcef les repère à la relecture et remet l'agent sur la bonne façon de faire.

Tous les exemples de cette page viennent d'UpDrive, l'app des chauffeurs VTC que plus de 1 000 chauffeurs paient chaque mois.

Parler de mon application
1 🧭 Spec produit le vocabulaire du métier les décisions tranchées 2 📋 ⓘ Stories 1 story = 1 fonctionnalité le hors-périmètre écrit le cas d'échec écrit 3 🤖 Agent Dev suit le layou-dev-kit domain → data → UI 4 🧪 Contrôle qualité lint, tests, architecture traductions et composants relecture par Youcef 5 🚀 Mise en ligne web + TestFlight l'app est déployée 6 🔍 ⓘ Agent QA rejoue la story sur l'app en ligne thème clair et sombre PASS → story terminée FAIL → nouvelle story La story le contrat

L'architecture d'abord

  • le layou-dev-kit est relu avant de coder
  • les mêmes patterns sur chaque écran

Contrôle rouge : on reboucle

  • correction automatique, 3 tours au plus
  • au-delà, un humain reprend la main

Une chaîne, quatre cibles

  • web, iOS, Android, macOS
  • le même commit pour toutes

Survolez une étape pour l'isoler, un point • pour la règle qu'il porte. Les étapes ⓘ ouvrent le vrai fichier. Faites glisser le schéma. Touchez une étape ⓘ pour ouvrir le vrai fichier.

La story

Les décisions sont prises avant le code.

Une story décrit une fonctionnalité du point de vue de l'utilisateur, puis tranche tout ce qui pourrait se discuter pendant le développement. Si une décision change en route, on corrige la story avant le code. Six mois plus tard, elle explique encore pourquoi le code est comme ça.

Ce que tranche la story « distance et durée auto » d'UpDrive

  • Le choix technique, avec sa raison. Routes API (New), parce que l'ancien SDK JavaScript est inutilisable depuis Dart.
  • Ce qui reste hors du périmètre. Pas de carte, pas de nouveau champ en base. Cette ligne évite de refaire la moitié de l'app au passage.
  • Ce qui se passe si ça échoue. L'API ne répond pas ? Le champ reste vide et le chauffeur saisit à la main. Pas de crash, pas de 0,00 € affiché sans prévenir.
  • Des tâches numérotées. De T0 à T7. Une story qui ne se découpe pas est trop grosse.
Lire la story complète

Ce que dit l'en-tête du fichier

  • status: où en est la story dans la boucle
  • fr: FR-16 l'exigence de la spec qu'elle couvre
  • dev_kit: ../layou-dev-kit l'architecture relue avant d'écrire une ligne
  • depends_on: ce qui doit exister avant, pour que deux stories avancent en parallèle sans se gêner
---
title: "Story : distance et durée auto (Google Routes API)"
status: ready-for-review
created: 2026-06-17
fr: FR-16                  # l'exigence du PRD que la story couvre
epic: "E4 : Calculateur"
author: John (PM)
dev_kit: ../layou-dev-kit  # l'archi relue AVANT de coder
depends_on: story-address-autocomplete.md
---

## Story
As a **chauffeur VTC qui remplit un Transfert**,
I want **que la distance et la durée se remplissent toutes seules**,
so that **je ne les tape plus à la main et mon tarif colle au réel.**

## Décisions produit (figées avec Youcef le 2026-06-17)
| Sujet | Décision |
|---|---|
| API | Routes API (New), compatible CORS depuis Flutter web |
| Éditabilité | une AIDE, jamais un verrou : le chauffeur corrige |
| Aller-retour | 2 appels (A→B + B→A) puis somme. Pas de ×2 naïf |
| Échec API | on ne remplit rien. Champ vide, saisie manuelle |

## Hors scope
Proxy Cloud Function · polyline/carte · nouveau champ Firestore.

## Tâches
T0 vérifier la clé au curl · T1 domaine (entity + usecase)
T2 data (repo Routes API) · T3 calculateur · T4 les 3 forms
T5 recalcul du tarif · T6 tests · T7 analyze

L'architecture

La même architecture sur chaque app, dès la première version.

Elle est écrite dans un dépôt à part, le layou-dev-kit, et chaque story pointe dessus. Une première version n'a donc pas de code jetable : quand l'app grandit, on construit sur ce qui existe.

Les huit règles qu'aucune story ne contourne
  1. presentation n'importe jamais data.
  2. domain n'importe ni data, ni presentation, ni Firebase, ni Flutter UI.
  3. La racine lib/ = shell, router, startup, DI. Rien d'autre.
  4. Tout SDK externe est wrappé avant d'atteindre le code de l'app.
  5. Usecase obligatoire pour les writes, les effets de bord, les décisions métier.
  6. Ordre d'implémentation : domain → data → app → presentation.
  7. UI : screen → connector → organism → molecule.
  8. Clean Architecture dès le jour 1. Même pour un MVP.
Voir l'architecture en détail →

Les 10 %

Environ 90 % du code des agents est bon du premier coup. Le reste passe par Youcef.

Le cadre fait l'essentiel du travail : une story précise et une architecture que l'agent relit avant d'écrire. Ce qui sort quand même de la route, Youcef le repère à la relecture, grâce à dix ans d'apps en production, et réoriente l'agent sur la bonne façon de faire.

  • Un contrôle rouge renvoie l'agent corriger, trois tours au plus. Au-delà, un humain reprend la main.
  • La spec, les arbitrages produit et le feu vert de mise en ligne restent à nous.

La recette

Une story est finie quand elle marche sur l'app en ligne.

Des tests verts ne suffisent pas. L'agent QA ouvre l'app déployée dans un navigateur et rejoue la story écran par écran, comme le ferait un utilisateur.

  • Sur l'adresse de production, sans maquette ni émulateur.
  • Chaque écran en thème clair et en thème sombre.
  • Une capture à chaque étape, pour relire tout le parcours d'un coup d'œil.
  • Un échec redevient une story, avec ses décisions, et repart dans la boucle.
Pour les équipes techniques : piloter une app Flutter

Une app Flutter web rend dans un <canvas> : il n'y a rien à cliquer dans le DOM. Chaque élément interactif porte donc un Semantics(identifier:) stable, ce qui rend l'app pilotable de l'extérieur.

Une suite de tests par epic (epic-1-auth, epic-4-calculator…) et un run-all qui les enchaîne. Ce qui n'est pas encore construit est écrit dans le plan de test, pour ne pas remonter de faux bugs.

L'agent QA lit la même story que l'agent dev : il ne teste que ce qui a été décidé par écrit.

// Flutter web rend dans un <canvas> : pas de DOM à cliquer.
// Donc chaque élément interactif porte un Semantics(identifier:)
// stable → dans le DOM : flt-semantics-identifier="nav_fab_create"
// C'est CE détail qui rend l'app pilotable de l'extérieur.

const URL = process.env.UPDRIVE_URL || 'https://updrive-prod.web.app';

function bySemantics(page, identifier) {
  return page.locator(`[flt-semantics-identifier="${identifier}"]`).first();
}

async function fillField(page, identifier, value) {
  const node = bySemantics(page, identifier);
  await node.waitFor({ state: 'visible', timeout: 5000 });
  await node.click({ force: true });      // focus le VRAI champ
  await page.keyboard.press('End');
  for (let i = 0; i < 60; i++) await page.keyboard.press('Backspace');
  await page.keyboard.insertText(value);  // seul chemin fiable ici
}

// La recette rejoue la story, écran par écran : inscription →
// dashboard → calculateur → facture → listing. En light ET dark.
// Screenshot à chaque étape.

Parlons de votre application.

30 minutes pour décider ce que l'app doit débloquer et ce qui part en premier. Vous repartez avec un prix et une date.

Réserver l'appel de cadrage