diff --git a/AGENTS.md b/AGENTS.md index 66d2a67..40d9a38 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,3 +1,117 @@ -# Codex instructions +# AGENTS.md — Loi du dépôt Thrustline + +Ce fichier s'applique à tout le dépôt. Toute instruction plus locale doit être +compatible avec ces règles. + +## Mission + +Thrustline est une application Windows distribuable de gestion de compagnie +aérienne virtuelle pour Microsoft Flight Simulator. La refonte vise en priorité : + +1. stabilité et récupération après erreur ; +2. sécurité d'un client distribué et modifiable ; +3. intégrité de l'économie et des données ; +4. compatibilité MSFS/SimConnect ; +5. maintenabilité, testabilité et mises à jour sûres. + +## Sources de vérité + +Lire avant tout travail : + +1. `docs/CURRENT_STATE.md` — ce qui existe réellement ; +2. `docs/ROADMAP.md` — ordre des phases ; +3. le ticket concerné dans `docs/tickets/` ; +4. les documents spécialisés indiqués par le ticket. + +Références permanentes : + +- `docs/PRODUCT.md` — périmètre et règles produit ; +- `docs/ARCHITECTURE.md` — architecture cible et frontières ; +- `docs/SECURITY.md` — règles de sécurité ; +- `docs/QUALITY.md` — stratégie de tests et critères de qualité ; +- `docs/WORKFLOW.md` — cycle complet d'un ticket. + +Le code et les migrations appliquées priment sur une documentation périmée. +Signaler et corriger les divergences dans le même ticket si elles sont directement +liées au changement. + +## Règles de travail + +- Implémenter un seul ticket à la fois. +- Ne pas anticiper les tickets futurs. +- Ne pas refactorer un système sans rapport. +- Respecter strictement `Allowed areas` et `Do not touch`. +- Préserver les modifications utilisateur non liées. +- Ne pas changer l'architecture sans ADR accepté. +- Éviter toute dépendance nouvelle si une solution simple existe déjà. +- Arrêter et demander une décision si une ambiguïté change le produit, la + sécurité, les données ou l'architecture. +- Un problème découvert hors périmètre devient un follow-up dans + `docs/KNOWN_ISSUES.md`, pas une modification opportuniste. + +## Frontières techniques + +- `app/` : Tauri v2, React, TypeScript, Vite, UI et orchestration cliente. +- `sim-bridge/` : .NET 8, SimConnect, télémétrie locale, REST/SignalR. +- `supabase/` : Auth, PostgreSQL, RLS, Realtime, RPC et Edge Functions. +- `legacy/` : lecture seule jusqu'à son archivage explicite. + +Le desktop, le sidecar et MSFS sont des clients non fiables. Le serveur est +autoritaire pour l'argent, la propriété, la réputation, la progression et les +transitions sensibles. Aucun secret backend ne doit être livré au client. + +## Qualité d'implémentation + +- TypeScript strict, C# nullable et Rust sans avertissement introduit. +- Pages React minces ; règles métier et accès données hors des composants. +- Mutations sensibles via commande serveur transactionnelle et idempotente. +- Migrations Supabase append-only. +- Contrats partagés versionnés et consommateurs mis à jour ensemble. +- Erreurs actionnables pour l'utilisateur, détails techniques dans des logs + redigés. +- Aucun secret, JWT, donnée personnelle ou header d'authentification dans Git ou + les logs. + +## Validation + +Exécuter les contrôles proportionnés au ticket, puis consigner les résultats : + +```powershell +# Frontend +Set-Location app +npm test +npm run build + +# Sidecar +Set-Location ..\sim-bridge +dotnet build --configuration Release +dotnet test --configuration Release + +# Tauri +Set-Location ..\app\src-tauri +cargo check --locked + +# Invariants du dépôt +Set-Location ..\.. +.\scripts\security-check.ps1 +``` + +Les changements SQL exigent des tests locaux/staging d'isolation entre deux +utilisateurs. Les changements SimConnect exigent un replay de trace ou un test +manuel MSFS documenté. Ne jamais annoncer comme réussi un contrôle non exécuté. + +## Fin de ticket + +Un ticket n'est `Done` que si : + +- ses critères d'acceptation sont satisfaits ; +- les tests automatisés pertinents passent ; +- sa vérification manuelle a été effectuée ou clairement déléguée ; +- les risques et limites sont consignés ; +- `docs/CURRENT_STATE.md` est mis à jour si l'état réel change ; +- le ticket contient son Completion Report ; +- aucun changement hors périmètre n'est inclus. + +Le rapport final doit donner : résumé, fichiers modifiés, commandes exécutées, +résultats, vérification manuelle, risques, follow-ups et documentation mise à jour. -Read and follow `codex.md` at the repository root before making changes. It contains the project architecture, setup commands, conventions, safety constraints, and validation expectations for the active Thrustline implementation. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..19ae421 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contribuer à Thrustline + +Thrustline suit un workflow par tickets afin de protéger la stabilité, la +sécurité et l'intégrité des données. + +## Avant de contribuer + +1. Lire `AGENTS.md`. +2. Lire `docs/CURRENT_STATE.md`. +3. Choisir un ticket `Ready` dans `docs/tickets/`. +4. Ne pas commencer un ticket Draft ou Backlog sans l'affiner. + +## Branche + +Utiliser `type/TXXXX-description`, par exemple : + +```text +foundation/T0001-baseline-reproductible +security/T0012-tests-rls +fix/T0042-reconnexion-simconnect +``` + +## Pull request + +Une PR couvre un ticket. Elle contient : + +- lien/ID du ticket ; +- résumé et fichiers principaux ; +- tests et commandes exécutés ; +- étapes de vérification manuelle ; +- impact sécurité/données ; +- risques, limites et rollback ; +- follow-ups hors périmètre. + +## Qualité + +Suivre `docs/QUALITY.md` et les validations du ticket. Ne pas masquer un test +échoué ni annoncer un contrôle non exécuté. + +## Sécurité + +Ne jamais ouvrir une issue publique contenant une faille exploitable, un secret ou +des données personnelles. Suivre `SECURITY.md`. + diff --git a/PLAN.md b/PLAN.md index 19cf0dd..aa02f67 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1,217 +1,7 @@ -# Thrustline — Plan d'implementation +# Plan de refonte -> Plan de reference pour le rework complet. Branche `rework`. -> Voir `PROGRESS.md` pour l'etat d'avancement. +La roadmap active se trouve dans [`docs/ROADMAP.md`](docs/ROADMAP.md). ---- +Ce fichier est conservé comme pointeur de compatibilité pour les anciens liens. +Ne pas maintenir une seconde roadmap ici. -## Stack cible - -| Couche | Techno | -|---|---| -| Shell desktop | **Tauri v2** (Rust) — sidecar pour le sim-bridge | -| Frontend | **React 18 + TypeScript + Vite + Tailwind v4** | -| Sim Bridge | **C# .NET 8** — ASP.NET Minimal API + SignalR + SimConnect SDK | -| Auth + DB | **Supabase** (Postgres + RLS + Auth + Realtime) — single source of truth | -| IPC | **HTTP REST** (CRUD) + **SignalR** (real-time sim data) | - -### Schema d'execution - -``` -Tauri shell (Rust) - └─ React + Vite (UI) ◄── REST + SignalR (localhost:5055) ──► sim-bridge.exe (C# .NET) - ├─ SimConnect thread ──► MSFS 2024 - ├─ ASP.NET Minimal API - ├─ SignalR Hub - └─ Supabase client ──► Supabase (cloud) -``` - ---- - -## Phase 1 — Fondations (TERMINE) - -### 1.1 Nettoyage -- [x] Wipe legacy stack (Electron, Fastify, Prisma, node-simconnect) -- [x] Branche `rework` depuis main - -### 1.2 Sim-bridge C# .NET 8 -- [x] Scaffold projet ASP.NET Minimal API (`sim-bridge/`) -- [x] SimConnect abstraction : `ISimClient`, `SimData`, `FlightDetector` -- [x] `MockSimClient` — vol CDG→JFK en boucle 100s -- [x] `SimConnectWorker` — BackgroundService, SignalR broadcast -- [x] Services metier : `YieldService`, `CashflowService`, `MaintenanceService` -- [x] `LandingProcessor` — pipeline complète landing → Supabase writes -- [x] Cloud models (DTOs Supabase) : Company, Aircraft, Dispatch, Flight, Transaction, Reputation -- [x] `SupabaseClientProvider` — singleton lazy-init avec service_role key -- [x] Session store (userId reçu du front via POST /session) -- [x] Endpoints REST : GET /health, POST /session, DELETE /session -- [x] SignalR hub `/hubs/sim` - -### 1.3 Schema Supabase -- [x] Migration `20260405120000_init.sql` — 10 tables, 7 enums, RLS policies, triggers - -### 1.4 Frontend Tauri + React -- [x] Scaffold Tauri v2 + React 18 + TS + Vite + Tailwind v4 -- [x] Auth Supabase (AuthContext, page Auth email/password) -- [x] Onboarding (creation compagnie) -- [x] CompanyContext (state partage + Supabase Realtime) -- [x] SimContext + useSimStream (client SignalR) -- [x] Layout + Sidebar + SimStatusBadge + LiveFlightBar -- [x] Sidecar spawn dans lib.rs (Tauri) - ---- - -## Phase 2 — Pages UI (TERMINE) - -- [x] **Dashboard** — KPIs (capital, sim status, last landing), flight in progress -- [x] **Flights** — historique complet avec table (route, distance, duration, fuel, revenue, net) -- [x] **Fleet** — cards avions avec health bar, cycles/hours, add form, set active -- [x] **Sortie de flotte** — vente courtier des avions possedes et restitution anticipee payante des credit-bails -- [x] **Dispatch** — liste missions avec badges status, actions (dispatch → flying → completed), new dispatch form -- [x] **Crew** — table avec rank/status, aircraft assignment, hire form avec random names -- [x] **Finances** — summary cards, cashflow chart (recharts), loans, transaction ledger -- [x] **Settings** — health check sim-bridge - ---- - -## Phase 3 — Infra technique (TERMINE) - -- [x] **NativeSimConnectClient** — `#if HAS_SIMCONNECT`, thread Win32 message pump, 10 SimVars, retry auto 5s -- [x] **Sidecar auto-spawn** — `scripts/build-sidecar.ps1`, lib.rs avec child management + kill on close -- [x] **Supabase Realtime** — CompanyContext subscribe aux UPDATE sur companies, capital live -- [x] **useRealtimeTable** — hook generique INSERT/UPDATE/DELETE -- [x] **waitForBridge()** — retry helper pour attendre le sidecar au demarrage - ---- - -## Phase 4 — Features majeures (TERMINE) - -### 4.1 Base aeroports (ICAO) -- [x] Fichier statique `airports.ts` (3232 aeroports, ICAO 4-lettres, large+medium, scheduled_service) - - Source : OurAirports CSV auto-parse - - Champs : `icao, iata, name, city, country, lat, lon, elevation_ft` - - Index `airportByIcao` pour lookup O(1) -- [x] Composant `AirportPicker.tsx` — input autocomplete (recherche ICAO, IATA, nom, ville) - - Max 8 resultats, priorite exact > startsWith > contains - - Keyboard navigation (Arrow, Enter, Escape) - - Affiche nom + ville sous le code selectionne -- [x] Branche dans Dispatch (origin/dest) et Onboarding (hub) - -### 4.2 Base avions (types + contraintes) -- [x] Fichier statique `aircraftTypes.ts` (36 types MSFS courants) - - Airbus (A319→A388), Boeing (B737→B78X), Regional (CRJ, Embraer), Turboprops (ATR, Dash8), GA (C172, TBM9, PC12) - - Champs : `icaoType, name, manufacturer, rangeNm, maxPaxEco, maxPaxBiz, fuelCapacityGal, ceilingFt, cruiseSpeedKts` -- [x] Composant `AircraftTypePicker.tsx` — dropdown searchable avec specs -- [x] Validation Dispatch : warning si distance route > range avion (haversine) -- [x] Auto-fill pax eco/biz depuis le type selectionne -- [x] Integration Fleet : remplacement input icao_type - -### 4.3 Carte live (Flight Map) -- [x] Package `react-leaflet@4` + `leaflet@1` (compatible React 18) -- [x] Composant `FlightMap.tsx` reutilisable (props: origin, dest, waypoints, aircraft) - - Marqueur avion anime avec rotation heading (SVG) - - Polyline route (dashed, couleur brand cyan) - - Marqueurs aeroports avec labels ICAO permanents - - Auto-fit bounds sur origin+dest -- [x] Integration Dashboard (carte 260px, non-interactive, hub + avion live) -- [x] Integration Dispatch (carte 180px dans le formulaire, route quand origin+dest) -- [x] Dark map tiles CartoDB dark_matter + Leaflet CSS overrides - -### 4.4 Integration SimBrief -- [x] Champ `simbrief_username` dans Settings (sauvegarde Supabase) -- [x] Bouton "Generate on SimBrief" dans Dispatch (ouvre URL pre-remplie) -- [x] Bouton "Import OFP" — poll API toutes les 5s (max 60s) -- [x] Lib `simbrief.ts` — fetch + parse OFP (route, fuel, weights, times, navlog) -- [x] Modal OFP glassmorphism avec sections (Route, Fuel, Weights, Times, Aircraft) -- [x] Bouton "Apply to dispatch" dans OFP Modal → pre-remplit le formulaire -- [x] Trace route waypoints navlog sur la carte -- [x] Helper `geo.ts` — haversine distance en nautical miles - ---- - -## Phase 5 — Game Mechanics (EN COURS) - -Ordre d'implementation : 5.3 → 5.2 → 5.4 → 5.1 -(base economique d'abord, puis emprunts, puis reputation, puis evenements) - -### 5.3 Salaires & charges mensuelles (PREMIER) -- [ ] **Timer de session** : a chaque lancement de l'app, calculer le nombre de "mois de jeu" ecoules depuis le dernier calcul - - Stocker `last_billing_at` dans `companies` (nouvelle colonne) - - Au login, si > 30 jours ecoules → declencher un cycle de facturation - - Endpoint sim-bridge `POST /billing/cycle` ou logique frontend-only via Supabase -- [ ] **Deduction salaires crew** : pour chaque crew_member, deduire `salary_mo` du capital - - INSERT transaction (type=salary, amount=-salary_mo, description="Salary — {name}") - - UPDATE companies.capital -= total_salaries -- [ ] **Deduction lease avions** : pour chaque aircraft ownership=leased, deduire `lease_cost_mo` - - INSERT transaction (type=lease, amount=-lease_cost_mo, description="Lease — {name}") - - UPDATE companies.capital -= total_leases -- [ ] **UI Finances** : section "Monthly charges" avec breakdown salaires + leases -- [ ] **Notification** : toast/banner au login montrant le recap des charges deduites - -### 5.2 Systeme de loans -- [ ] **Formulaire emprunt** dans Finances : montant, duree (mois), taux d'interet fixe - - Table `loans` existe deja : amount, interest_rate, monthly_payment, remaining, active - - INSERT loan + UPDATE capital += montant emprunte -- [ ] **Remboursement mensuel** : dans le cycle de facturation (5.3), deduire `monthly_payment` de chaque loan actif - - INSERT transaction (type=loan_payment, amount=-monthly_payment) - - UPDATE loans.remaining -= (monthly_payment - interet) - - Si remaining <= 0 → UPDATE loans.active = false -- [ ] **UI Finances** : liste des emprunts actifs, progress bar remboursement, historique -- [ ] **Validation** : plafond d'emprunt (ex: max 3x le capital actuel), refus si capital < 0 - -### 5.4 Reputation avancee -- [ ] **Score par route** (table `reputations` existe deja) : - - Deja ajuste par qualite d'atterrissage dans LandingProcessor - - Ajouter : bonus si vol regulier (>3 vols sur la meme route), malus si route abandonnee (>30 jours sans vol) -- [ ] **Impact sur la demande pax** : dans YieldService, le `repMult` est deja calcule (0.5 + score/100) - - Ajouter : affichage du multiplicateur dans Dispatch (ex: "Demand: 1.2x" a cote de la route) - - Couleur verte si >1x, rouge si <1x -- [ ] **UI reputation** : nouvelle section dans Dashboard ou page dediee - - Liste des routes avec score, nombre de vols, tendance (↑↓) - - Badge "Premium route" si score > 80 -- [ ] **Routes premium** : routes a haute reputation (>80) generent un bonus +20% de revenue - - Modifier YieldService pour ajouter le premium bonus - -### 5.1 Evenements aleatoires (DERNIER) -- [ ] **GameEvent system** : table `game_events` existe deja (type, scope, multiplier, active, expires_at) - - Types : fuel_spike (+30% fuel cost), fuel_drop (-20%), weather (annule des vols), tourism_boom (+50% pax revenue sur une route), strike (-100% revenue temporaire), mechanical (-health sur un avion) -- [ ] **Generateur d'evenements** : a chaque cycle mensuel, 30% de chance de generer 1-2 evenements - - Duree : 1-7 jours (expires_at) - - Scope : global (toutes routes), route (une route specifique), aircraft (un avion specifique) -- [ ] **Modificateurs dans les services** : - - CashflowService : deja supporte `fuelPriceMultiplier` et `landingFeeMultiplier` - - YieldService : ajouter `demandMultiplier` depuis game_events -- [ ] **UI notifications** : banner en haut du Dashboard avec les evenements actifs - - Icone + couleur selon type (rouge=strike, vert=tourism_boom, orange=fuel_spike) - - Compte a rebours avant expiration -- [ ] **UI evenements** : liste dans Settings ou page dediee avec historique - ---- - -## Phase 6 — Flight Scheduling (MVP TERMINE) - -- [x] Generateur de rotations continues par avion, sans teleport -- [x] Contraintes : nombre de vols, nombre de rotations, heures totales, duree max par vol, range avion -- [x] Retour optionnel au hub et avertissements quand les contraintes sont impossibles -- [x] Position persistante de chaque avion (`current_airport_icao`) -- [x] Tables `schedules`, `schedule_rotations`, `schedule_legs` avec RLS -- [x] Page Schedule : configuration, preview carte/liste, sauvegarde et progression -- [x] Un seul leg disponible a la fois, transforme en dispatch a la demande -- [x] LandingProcessor : complete le leg, deplace l'avion et debloque le suivant -- [x] Garde-fous DB : un planning actif et un vol flying par avion, validation de position -- [x] Horaires reels par leg et temps au sol configurable -- [x] Equipage fixe captain + first officer + PNC selon le type d'avion par schedule passif, avec garde-fous de rang et de conflit -- [x] Vols passifs avec progression, economie/usure, position carte et rattrapage au prochain lancement -- [x] Vitesse des operations passives configurable (1x, 6x, 12x ou 24x) -- [x] Economie passive basee sur la demande passagers, la capacite et les couts propres au type d'avion -- [ ] Vue calendrier/timeline multi-avions, overnight et maintenance planifiee - ---- - -## Phase 7 — Polish & Deploy (A VENIR) - -- [ ] CI/CD (GitHub Actions : build + test) -- [ ] `supabase gen types typescript` — types auto-generes -- [ ] Installeur Windows (NSIS/MSI via Tauri) -- [ ] Virtual Airlines (compagnie partagee, invitations, roles) -- [ ] Stripe freemium → Pro diff --git a/PROGRESS.md b/PROGRESS.md index bafa3c3..daf96f1 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,228 +1,8 @@ -# Thrustline — Etat d'avancement +# État d'avancement -> Mis a jour a chaque session. Lire en premier avant tout travail. -> Voir `PLAN.md` pour le plan detaille. +L'état réel et le prochain ticket recommandé se trouvent dans +[`docs/CURRENT_STATE.md`](docs/CURRENT_STATE.md). ---- +Le statut détaillé du travail se trouve dans [`docs/tickets/`](docs/tickets/). +Ce fichier est conservé comme pointeur de compatibilité. -## Branche : `rework` - -## Phase actuelle : Phase 5 — Game Mechanics + MVP Flight Scheduling livre - ---- - -## Historique des commits - -``` -5cadd69 feat(app): flight network map on Dashboard with curved route arcs -67bf327 feat(app): show flight number and route in LiveFlightBar -f8ee5c1 fix(app): aircraft icon rotates to match flight heading -89f9903 fix(app): aircraft follows flight plan route + trail on map -5597af6 feat(app): pass passenger count to SimBrief dispatch URL -8f72407 feat(sim-bridge): mock aircraft follows flight plan waypoints -16beace feat(app): add flight number + callsign to dispatch, pass to SimBrief -081d200 fix(app): SimBrief opens browser, fix map route color, remove cruise alt -2d91a65 refactor(app): redesign dispatch form — SimBrief-first workflow -0919e07 feat(sim-bridge): dispatch-driven mock + UserSecretsId for Supabase config -634324e feat(app): live flight tracking, unit system, UI fixes -845fa43 feat(app): Phase 4 — airports, aircraft types, flight map, SimBrief integration -02986fd docs: rewrite PLAN.md and PROGRESS.md for rework branch -748b637 fix(sim-bridge): use HAS_SIMCONNECT flag instead of WINDOWS -12fb831 feat: NativeSimConnect + sidecar auto-spawn + Supabase Realtime -``` - ---- - -## Ce qui est fait - -### Phase 1 — Fondations - -| Composant | Status | Details | -|---|---|---| -| Sim-bridge C# .NET 8 | DONE | ASP.NET Minimal API, SignalR, SimConnect abstraction | -| MockSimClient | DONE | Dispatch-driven (idle par defaut, vol a la demande via POST /mock/start-flight) | -| FlightDetector | DONE | Machine a etats takeoff/landing, debounce 5s, haversine | -| LandingProcessor | DONE | Pipeline complete : yield/cashflow/maintenance → Supabase writes | -| Services metier | DONE | YieldService, CashflowService, MaintenanceService | -| Cloud models (DTOs) | DONE | 6 models avec Supabase.Postgrest attributes | -| Backend privilegie | DONE | Edge Function authentifiee; aucune cle service_role dans le frontend ou le sidecar | -| Deploiement securite Supabase | DONE | Migrations 20260721190000-20260721201000 appliquees et fonction complete-flight active sur le projet lie | -| Schema Supabase | DONE | 10 tables, 7 enums, RLS policies, triggers | -| Frontend Tauri + React | DONE | Tauri v2, React 18, TS, Vite, Tailwind v4 | -| Auth + Onboarding | DONE | Supabase Auth, CompanyContext, AirportPicker hub | -| SignalR streaming | DONE | useSimStream hook, LiveFlightBar (flight number + route), SimStatusBadge | - -### Phase 2 — Pages UI - -| Page | Status | Details | -|---|---|---| -| Dashboard | DONE | KPIs, flight network map (arcs courbes), charts, recent flights | -| Flights | DONE | Table historique (route, distance, duration, fuel, revenue, net) | -| Fleet | DONE | Cards avions, health bar, AircraftTypePicker, set active | -| Maintenance flotte | DONE | Devis, confirmation, debit atomique, transaction et remise a 100 %, avec blocage en operation | -| Marche d'occasion | DONE | Annonces partagees, filtres, etat/heures/prix/localisation, achat atomique avec debit et transaction | -| Marche avions + credit-bail | DONE | Achat neuf, achat occasion, lease-to-own 12-48 mois, impayes, rachat anticipe et transfert automatique de propriete | -| Vente + restitution flotte | DONE | Estimation serveur, commission courtier, frais de restitution, blocages operationnels et remplacement de l'avion actif | -| Profils SimBrief dans le marche | DONE | Chaque profil Settings genere une offre neuve et deux occasions privees, achetables ou finançables | -| Dispatch | DONE | SimBrief-first workflow, OFP inline, route preview, callsign | -| Crew | DONE | Table rank/status, aircraft assignment, hire form, random names | -| Finances | DONE | Summary cards, cashflow chart (recharts), loans, transaction ledger | -| Settings | DONE | Health check, SimBrief username, unit system toggle | -| Live Flight | DONE | Carte plein ecran, avion temps reel, trail, instruments, landing recap | - -### Phase 3 — Infra technique - -| Feature | Status | Details | -|---|---|---| -| NativeSimConnectClient | DONE | `#if HAS_SIMCONNECT`, Win32 message pump, 10 SimVars, retry 5s | -| Verification avion MSFS | DONE | Modele/type/immatriculation SimConnect compares au dispatch et a l'OFP dans Live Flight | -| Demarrage de vol securise | DONE | Passage en flying autorise uniquement avec MSFS actif et avion detecte au sol | -| Sidecar auto-spawn | DONE | `build-sidecar.ps1`, lib.rs child management, kill on close | -| Discord Rich Presence | DONE | Phase ACARS et route du vol publiees dynamiquement par Tauri, reconnexion automatique | -| Supabase Realtime | DONE | CompanyContext subscribe, capital updates live | -| useRealtimeTable | DONE | Hook generique INSERT/UPDATE/DELETE | -| waitForBridge | DONE | Retry helper startup | -| Durcissement desktop | DONE | JWT valide, appairage ephemere Tauri/bridge, CORS limite, CSP active et permissions shell reduites | -| Chargement frontend | DONE | Pages metier, cartes, graphiques et base aeroports decoupes en chunks a la demande | -| UI Polish v2 | DONE | Lucide icons, recharts, glassmorphism v2, animations | - -### Phase 4 — Features majeures - -| Feature | Status | Details | -|---|---|---| -| Airport database | DONE | 3232 aeroports ICAO 4-lettres, OurAirports source | -| AirportPicker | DONE | Autocomplete ICAO/IATA/nom/ville, keyboard nav | -| Aircraft types database | DONE | 36 types MSFS (Airbus, Boeing, Regional, Turboprops, GA) | -| Dispatch refonte | DONE | SimBrief-first: route → avion (specs pills) → load (max pax) → flight ID/callsign → SimBrief → OFP inline → submit | -| FlightMap | DONE | Dark tiles, bezier route arcs, aircraft marker (heading rotation), trail, waypoints | -| Dashboard network map | DONE | Arcs courbes historiques, dots aeroports, auto-fit bounds, interactive | -| Live Flight page | DONE | Carte plein ecran, instruments overlay, trail, landing recap | -| SimBrief integration | DONE | Generate (airline/fltnum/callsign/pax), Import OFP, inline resume, ofp_data persiste | -| Unit system | DONE | Imperial/Metric toggle, UnitsContext, integre LiveFlightBar + Dashboard + LiveFlight | -| Mock dispatch-driven | DONE | Idle par defaut, vol a la demande avec waypoints OFP, heading dynamique | -| Import airframes SimBrief | DONE | Decodage local des liens partages, economie automatique, catalogue persistant dans Settings | - -### Phase 6 — Flight Scheduling (MVP) - -| Feature | Status | Details | -|---|---|---| -| Schedule generator | DONE | Vols/rotations/heures max/duree max, range avion, retour hub optionnel | -| No teleport | DONE | Position avion persistante et validation DB au passage en flying | -| Schedule UI | DONE | Preview carte + rotations, sauvegarde, annulation, prochain vol disponible | -| Gestion des schedules | DONE | Affectation avion visible dans Schedule/Fleet et suppression securisee avec confirmation | -| Dispatch integration | DONE | Creation d'un seul dispatch depuis le prochain leg | -| Landing progression | DONE | LandingProcessor complete le leg, deplace l'avion et debloque le suivant | -| Supabase schema | DONE | schedules, schedule_rotations, schedule_legs, index et policies RLS | -| Operations passives | DONE | Horaires, temps au sol, captain/FO et PNC variables selon l'avion, progression automatique, economie/usure et rattrapage hors ligne | -| Acceleration passive | DONE | Echelle 1x/6x/12x/24x, 12x par defaut, sans reduire heures de vol, usure ni revenus | -| Visibilite flotte passive | DONE | Prochain leg/equipage dans Fleet et avion interpole sur la carte Schedule | -| Carte Dashboard passive | DONE | Tous les avions passifs en vol, routes et info-bulles, actualises toutes les 15 secondes | -| Economie passive par passagers | DONE | Demande deterministe, capacite avion, tarifs Eco/Business, consommation par famille, frais aeroportuaires et maintenance variable | - -### Passenger Experience (MVP) - -| Feature | Status | Details | -|---|---|---| -| Telemetrie cabine | DONE | Accelerations, G-force, pitch/bank, rotations et ceintures via SimConnect, snapshots mouvement limites a 10 Hz | -| Simulation temps reel | DONE | Cohortes Economy/Business, confort, stress, nausee, divertissement, turbulences et manoeuvres brusques | -| SignalR + Live Flight | DONE | Etat cabine diffuse a 2 Hz, panneau temps reel et tendances visibles pendant le vol | -| Bilan et persistence | DONE | Atterrissage integre au score final et `flights.pax_satisfaction` alimente par la simulation, avec fallback historique | -| Embarquement passagers | DONE | Progression 30-90s persistante, Business prioritaire, compteurs par cabine, passage automatique a ready et verrouillage du depart | - ---- - -## En cours — Phase 5 - -### 5.1 Evenements aleatoires -- [ ] `GameEvent` system : fuel_spike, weather, tourism_boom, strike, mechanical -- [ ] Modificateurs temporaires sur les routes/avions -- [ ] Notifications in-app - -### 5.2 Systeme de loans -- [ ] Prendre un emprunt pour acheter un avion -- [ ] Remboursements mensuels automatiques -- [ ] UI dans Finances - -### 5.3 Salaires & charges mensuelles -- [ ] Deduction automatique salaires crew -- [ ] Deduction lease cost avions -- [ ] Timer mensuel (ou par session) - -### 5.4 Reputation avancee -- [ ] Score par route influence la demande pax -- [ ] Bonus/malus visibles dans l'UI -- [ ] Deblocage de routes premium - ---- - -## Bugs connus / fixes appliques - -| Bug | Cause | Fix | Commit | -|---|---|---|---| -| Leaflet z-index chevauche UI | Layers internes z-index 400+ | isolation:isolate + z-index:0 | `634324e` | -| OFP times raw unix timestamps | sched_out/sched_in pas formates | parseInt + formatUnixUTC() | `634324e` | -| SimBrief n'ouvre pas le navigateur | window.open() bloque dans Tauri | shell.open() + permission shell:allow-open | `081d200` | -| Polyline invisible sur carte | oklch() pas supporte par Leaflet | Couleur hex #00b4d8 | `081d200` | -| Avion en diagonale sur carte | Lerp lineaire origin→dest sans waypoints | InterpolateRoute avec waypoints + Bearing | `8f72407` | -| Icone avion ne tourne pas | SVG Lucide pointe ~315°, pas 0° | Triangle simple nord=0° + rotate(heading) | `f8ee5c1` | -| Secret privilegie sur le client | Ancien sidecar configure avec service_role | Remplace par JWT utilisateur + Edge Function serveur | Securite distribution | -| Mock vol auto en boucle | CDG→JFK 100s loop au demarrage | Dispatch-driven, idle par defaut | `0919e07` | -| Vol affiche dans les menus MSFS | L'UI conservait le dernier snapshot actif quand `SIM DISABLED=1` | Etat actif propage et detecteur reinitialise | Non commite | - ---- - -## Commandes utiles - -```bash -# Prerequis frontend : Node.js 24.18.0 LTS - -# Frontend (dev) -cd app && npm run dev # Vite dev server (port 1420) -cd app && npm run tauri:dev # Tauri + Vite (avec sidecar) - -# Frontend (validation) -cd app && npm test -cd app && npm run build - -# Sim-bridge (dev) -cd sim-bridge && dotnet run # Lance le service .NET (port 5055) - -# Backend Supabase -supabase functions deploy complete-flight --project-ref - -# Sidecar build (Windows) -.\scripts\build-sidecar.ps1 # Publish + copie dans Tauri binaries - -# Supabase -npx supabase gen types typescript --project-id > app/src/lib/database.types.ts -``` - ---- - -## Architecture fichiers cles - -``` -Thurstline/ -├── app/ # Tauri + React -│ ├── src/ -│ │ ├── components/ # Layout, Sidebar, LiveFlightBar, SimStatusBadge, AirportPicker, FlightMap, OFPModal -│ │ ├── contexts/ # AuthContext, CompanyContext, SimContext, UnitsContext -│ │ ├── data/ # airports.ts (3232), aircraftTypes.ts (36) -│ │ ├── hooks/ # useSimStream, useRealtimeTable -│ │ ├── lib/ # supabase.ts, simBridge.ts, simbrief.ts, geo.ts, units.ts, database.types.ts -│ │ └── pages/ # Dashboard, Flights, Fleet, Dispatch, Crew, Finances, Settings, LiveFlight, Auth, Onboarding -│ └── src-tauri/ -│ ├── src/lib.rs # Sidecar spawn + kill -│ ├── capabilities/default.json # Permissions (shell:allow-open, execute, spawn) -│ └── tauri.conf.json # Config Tauri, externalBin -├── sim-bridge/ # C# .NET 8 -│ ├── SimConnect/ # ISimClient, MockSimClient (dispatch-driven), NativeSimConnectClient, FlightDetector, SimData -│ ├── Cloud/Models/ # DTOs Supabase (CompanyRow, AircraftRow, etc.) -│ ├── Services/ # YieldService, CashflowService, MaintenanceService, LandingProcessor -│ ├── Session/ # SessionStore -│ └── Program.cs # Entry point, DI, endpoints, POST /mock/start-flight -├── supabase/migrations/ # Schema SQL -├── scripts/build-sidecar.ps1 # Build + deploy sidecar -├── PLAN.md # Plan detaille -└── PROGRESS.md # Cet etat d'avancement -``` diff --git a/README.md b/README.md index be0fddc..d536038 100644 --- a/README.md +++ b/README.md @@ -145,9 +145,14 @@ npm run tauri:build ## Documentation du projet -- [`PLAN.md`](PLAN.md) : feuille de route et comportement cible -- [`PROGRESS.md`](PROGRESS.md) : etat d'avancement et fonctionnalites livrees -- [`codex.md`](codex.md) : architecture detaillee et conventions de contribution +- [`docs/README.md`](docs/README.md) : point d'entree de la refonte +- [`docs/PRODUCT.md`](docs/PRODUCT.md) : vision et perimetre produit +- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) : architecture cible +- [`docs/CURRENT_STATE.md`](docs/CURRENT_STATE.md) : etat reel du depot +- [`docs/ROADMAP.md`](docs/ROADMAP.md) : phases et gates de la refonte +- [`docs/WORKFLOW.md`](docs/WORKFLOW.md) : cycle de travail par tickets +- [`docs/tickets/`](docs/tickets/) : backlog et rapports de completion +- [`AGENTS.md`](AGENTS.md) : regles obligatoires pour les agents - [`supabase/README.md`](supabase/README.md) : notes relatives a Supabase ## Securite diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..dbf4b6d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,26 @@ +# Politique de sécurité + +Thrustline est actuellement en développement et ne possède pas encore de version +publique stable officiellement supportée. + +## Signaler une vulnérabilité + +Ne créez pas d'issue GitHub publique contenant les détails d'une vulnérabilité. + +Utilisez le signalement privé de vulnérabilité GitHub du dépôt s'il est activé. +Sinon, contactez le mainteneur par un canal privé publié sur son profil, sans +inclure de secret ni de donnée personnelle dans le premier message. + +Indiquez si possible : + +- version ou commit affecté ; +- composant concerné ; +- étapes de reproduction ; +- impact attendu ; +- mitigation suggérée. + +N'accédez pas aux données d'autres utilisateurs, ne perturbez pas le service et ne +publiez pas les détails avant coordination d'un correctif. + +Les règles internes de développement sont dans `docs/SECURITY.md`. + diff --git a/codex.md b/codex.md index 62dd67f..4281696 100644 --- a/codex.md +++ b/codex.md @@ -1,126 +1,14 @@ -# Thrustline project guide +# Guide Codex — compatibilité -## Project overview +Les instructions actives sont désormais centralisées dans `AGENTS.md`. -Thrustline is a Windows-first virtual airline management desktop application for Microsoft Flight Simulator. The active implementation is split across: +Avant toute modification : -- `app/`: Tauri v2 desktop shell with a React 18, TypeScript, Vite, and Tailwind CSS v4 frontend. -- `sim-bridge/`: ASP.NET Core/.NET 8 sidecar that connects to MSFS through SimConnect, exposes local REST endpoints, and streams simulator data through SignalR. -- `supabase/`: Postgres schema migrations. Supabase provides authentication, database storage, row-level security, and realtime updates. -- `scripts/`: repository-level PowerShell build helpers. -- `legacy/`: superseded Electron and WPF implementations. Treat this directory as reference-only unless a task explicitly targets it. +1. lire `AGENTS.md` ; +2. lire `docs/CURRENT_STATE.md` ; +3. lire le ticket demandé dans `docs/tickets/` ; +4. suivre `docs/WORKFLOW.md`. -The normal data flow is: +Ce fichier est conservé pour les outils ou anciennes conversations qui le +référencent encore. Il ne doit pas devenir une seconde source de règles. -`MSFS -> sim-bridge -> REST/SignalR -> React UI`, with the React app and sidecar both using Supabase for their appropriate responsibilities. - -## Start every task here - -1. Read `PROGRESS.md` for the current implementation state and known issues. -2. Read the relevant section of `PLAN.md` for intended behavior and remaining work. -3. Check `git status --short` and preserve unrelated user changes. -4. Inspect the relevant implementation and latest Supabase migrations before editing; do not rely on the plan alone because code may be newer than the documentation. - -The current roadmap focus is Phase 5 game mechanics, but the user's request always takes precedence. - -## Setup and development - -Prerequisites are Node.js 24.18.0 LTS, npm, .NET 8, Rust, the Tauri v2 platform prerequisites, and a Supabase project. Native SimConnect functionality requires Windows and an MSFS/SimConnect installation. - -Frontend environment: - -```powershell -Set-Location app -Copy-Item .env.example .env -npm install -``` - -Populate `app/.env` with `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY`. Never commit `.env` files or service-role credentials. - -Useful commands: - -```powershell -# Browser-only frontend development -Set-Location app -npm run dev - -# Full Tauri desktop development -Set-Location app -npm run tauri:dev - -# Run the sidecar directly (localhost:5055) -Set-Location sim-bridge -dotnet run - -# Build and copy the Windows sidecar into Tauri's externalBin directory -.\scripts\build-sidecar.ps1 - -# Production checks/builds -Set-Location app -npm test -npm run build - -Set-Location sim-bridge -dotnet build -``` - -Deploy privileged operations as Supabase Edge Functions. The desktop and sidecar are public clients and must never receive the service-role key. See `supabase/SECURITY_DEPLOYMENT.md`. - -## Architecture and conventions - -### Frontend (`app/src`) - -- `App.tsx` owns the auth/company routing gates. -- `pages/` contains route-level screens; shared UI belongs in `components/`. -- `contexts/` owns app-wide auth, company, simulator, and units state. -- `hooks/` contains reusable realtime subscriptions and simulator streaming behavior. -- `lib/` contains Supabase access and domain/integration helpers. -- `data/airports.ts` and `data/aircraftTypes.ts` are large static datasets; avoid broad formatting or mechanical rewrites. -- Prefer the configured `@/` alias for imports from `app/src`. -- TypeScript is strict. Keep `noUnusedLocals`, `noUnusedParameters`, and the other compiler checks passing. -- Follow the existing functional-component, hook, and Tailwind utility patterns. Reuse the design tokens in `app/src/index.css` instead of introducing isolated styling systems. - -### Sidecar (`sim-bridge`) - -- `Program.cs` configures dependency injection, localhost REST endpoints, CORS, SignalR, and service startup. -- `SimConnect/` owns simulator clients, polling, flight detection, and the SignalR hub. -- `Services/` owns business rules and landing-processing behavior. -- `Session/` tracks the validated JWT and active flight context in memory. -- Privileged persistence is performed by Supabase Edge Functions, never by a service-role client in the sidecar. -- Keep the bridge bound to localhost unless a task explicitly changes the security model. -- Preserve cross-platform compilation. Native SimConnect behavior is Windows-specific and should remain isolated behind the existing abstraction. - -### Supabase (`supabase/migrations`) - -- Treat migrations as append-only history. Add a new timestamped migration rather than rewriting an applied migration. -- Include appropriate RLS policies, constraints, indexes, triggers, and grants when adding data structures. -- Keep `app/src/lib/database.types.ts` and affected C# models synchronized with schema changes. -- The frontend and sidecar may use only public configuration and user JWTs. The service-role key belongs exclusively to hosted Edge Functions and must never be shipped, logged, or committed. - -### Tauri (`app/src-tauri`) - -- `tauri.conf.json` declares the sidecar as an external binary. -- `src/lib.rs` manages sidecar startup and shutdown. -- `capabilities/default.json` controls permissions. Add only the narrow permissions a feature needs. -- Sidecar binaries and Rust build output are generated artifacts and should not be committed. - -## Change guidelines - -- Keep changes scoped to the active stack; do not modify `legacy/` unless explicitly requested. -- Preserve the separation of responsibilities: UI and RLS-protected CRUD in React, simulator/native integration and privileged landing processing in the sidecar. -- When changing a shared payload or database entity, trace every consumer across TypeScript, C#, SQL, REST, and SignalR. -- Avoid embedding ports or URLs in new call sites. Reuse the existing bridge and Supabase configuration helpers. -- Do not commit secrets, generated build directories, logs, published executables, or dependency folders. -- Update `PROGRESS.md` when a task materially changes roadmap status, architecture, commands, or known bugs. Update `PLAN.md` only when the intended roadmap itself changes. - -## Validation - -Run the narrowest checks that cover the change, then expand for cross-layer work: - -- Frontend changes: `npm run build` from `app/`. -- Sidecar changes: `dotnet build` from `sim-bridge/`. -- Rust/Tauri changes: `npm run tauri:build` from `app/` when practical; at minimum run the frontend build and `cargo check` from `app/src-tauri/`. -- Schema changes: review migration ordering and validate against a disposable/local Supabase instance when available. -- Cross-layer changes: build every affected layer and manually verify the relevant REST/SignalR flow. - -There is currently no automated test script in `app/package.json` and no dedicated .NET test project. Do not claim tests passed unless a test suite exists and was run. Report which build or manual checks were performed and any checks that could not run because MSFS, SimConnect, Supabase credentials, or platform tooling was unavailable. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..41bab5c --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,138 @@ +# Architecture cible + +Statut : cible de refonte ; toute divergence durable nécessite un ADR. + +## Architecture logique + +```text +MSFS + │ SimConnect (données non fiables) + ▼ +Bridge .NET 8 + │ événements de vol versionnés + │ canal local authentifié + ▼ +Tauri v2 / Rust + │ capacités natives minimales + ▼ +React / TypeScript + │ lectures RLS + commandes HTTPS + ▼ +Supabase + ├─ Auth + ├─ PostgreSQL + RLS + ├─ RPC/Edge Functions transactionnelles + ├─ Realtime + └─ jobs serveur contrôlés +``` + +## Frontières de confiance + +- Le frontend, Tauri, le bridge, MSFS et tous les fichiers importés sont publics + et modifiables par l'utilisateur. +- Supabase valide identité, appartenance, permissions et transitions. +- Le serveur recalcule argent, prix, récompenses, usure et progression. +- La télémétrie est un signal borné et analysé, pas une preuve absolue. + +## Responsabilités + +### React + +- Présentation, formulaires, cache de vues et états UX. +- Aucun calcul client utilisé comme autorité économique. +- Pages minces ; logique dans modules de fonctionnalité testables. +- Une couche `queries` pour les lectures et `commands` pour les mutations. + +### Tauri/Rust + +- Cycle de vie de l'application et du bridge. +- Capacités natives en allowlist. +- Validation native des URL externes. +- Update signée, diagnostics et stockage local approprié. + +### Bridge .NET + +- Connexion/reconnexion SimConnect. +- Normalisation, validation et agrégation de la télémétrie. +- Machine à états de vol déterministe et rejouable. +- Rapport de vol versionné. +- Aucun secret privilégié ni écriture économique directe. + +### Supabase + +- Identité et autorisation. +- Commandes sensibles transactionnelles et idempotentes. +- Grand livre immuable et projections. +- RLS défensive sur chaque table exposée. +- Audit des changements sensibles. +- Traitements passifs côté serveur, indépendants d'un client ouvert. + +## Organisation cible + +```text +app/src/ + app/ # composition, routes, providers + features/ + dispatch/ + api/ + components/ + hooks/ + model/ + tests/ + shared/ # UI, contrats, utilitaires sans métier + +sim-bridge/ + Api/ + Application/ + Domain/ + Infrastructure/ + SimConnect/ + Contracts/ + +supabase/ + functions/ + migrations/ + tests/ + +docs/ + decisions/ + tickets/ + templates/ +``` + +La migration vers cette organisation est progressive et pilotée par tickets. +Aucun « big bang » de déplacement sans tests de caractérisation. + +## Données + +- UUID pour les identités distribuées. +- Horodatages UTC ; temps simulé explicitement distinct du temps réel. +- Grand livre financier append-only. +- Version ou jeton de concurrence sur ressources sensibles. +- `operation_id` unique pour chaque commande rejouable. +- Suppression logique pour données auditables ; rétention documentée. +- Types Supabase générés et dérive détectée en CI. + +## Contrats + +- Payloads REST, SignalR et RPC versionnés. +- Validation aux deux extrémités. +- Changements compatibles ou migration coordonnée. +- Événements de domaine sans types SimConnect natifs. + +## Résilience + +- Timeout et annulation sur toute I/O. +- Retry uniquement pour opérations idempotentes, avec backoff et jitter. +- File locale/outbox pour les commandes critiques interrompues. +- États visibles : local, pending, synchronized, rejected. +- Aucun `last write wins` pour argent, propriété ou affectations. + +## Décisions encore ouvertes + +- Solo connecté ou VA collaborative. +- HTTP localhost renforcé ou named pipe Windows pour le bridge. +- Cache SQLite local et données autorisées hors ligne. +- Stratégie d'anti-triche proportionnée. +- Fournisseur de crash reporting et consentement. + diff --git a/docs/CURRENT_STATE.md b/docs/CURRENT_STATE.md new file mode 100644 index 0000000..4cf6e9d --- /dev/null +++ b/docs/CURRENT_STATE.md @@ -0,0 +1,168 @@ +# État actuel du dépôt + +Dernière revue documentaire : 24 juillet 2026 (ticket T0001). +Statut : baseline locale vérifiée ; validations externes encore requises. + +## Produit + +La version existante est une alpha active de gestion de compagnie aérienne +virtuelle. Le routeur et la navigation exposent les parcours suivants : + +- authentification et création initiale d'une compagnie ; +- tableau de bord, compagnie, flotte et marchés d'avions ; +- routes, dispatch/SimBrief, vols et suivi de vol en direct ; +- horaires et opérations passives ; +- équipage, finances, paramètres, EFB et succès. + +Le code contient aussi des services de maintenance, expérience passager, ACARS, +météo, événements de jeu et calculs d'atterrissage. T0001 prouve leur présence +dans le dépôt, pas leur fonctionnement de bout en bout. Il n'existe pas encore de +version publique stable. + +## Stack active et versions observées + +Baseline exécutée sous Windows le 24 juillet 2026 : + +- Node.js `24.14.1` et npm `11.11.0` ; +- SDK .NET `10.0.201`, projet bridge ciblant `net8.0` ; +- `rustc 1.94.1` et `cargo 1.94.1` ; +- Supabase CLI non installée/non trouvée ; +- Tauri v2 / Rust, React 18 / TypeScript / Vite / Tailwind ; +- ASP.NET Core et SimConnect.NET pour le bridge ; +- REST et SignalR sur loopback entre UI et bridge ; +- Supabase Auth/PostgreSQL/RLS/Realtime/Edge Functions. + +Le moteur Node déclaré par `app/package.json` est `>=24.18.0 <25`. La machine de +baseline est donc en dessous de la version minimale, même si les tests et le +build frontend réussissent. Les workflows CI utilisent Node `24.18.0`, .NET 8.x +et Rust stable. + +## Inventaire reproductible + +- Lockfiles : `app/package-lock.json` et `app/src-tauri/Cargo.lock`. +- Scripts npm : `dev`, `build`, `test`, `test:watch`, `test:coverage`, `preview`, + `tauri`, `tauri:dev`, `tauri:build`, `sidecar:build`. +- Scripts dépôt : `scripts/build-sidecar.ps1` et + `scripts/security-check.ps1`. +- Workflows : `.github/workflows/ci.yml` et + `.github/workflows/security.yml`. +- Migrations Supabase append-only constatées : 25. +- Dépendances directes : 11 npm runtime, 12 npm développement, 2 NuGet, + 6 Cargo runtime et 1 Cargo build. +- Variables/configurations relevées par nom seulement : + `VITE_SUPABASE_URL`, `VITE_SUPABASE_ANON_KEY`, `VITE_SIM_BRIDGE_URL`, + `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY` et + `THRUSTLINE_BRIDGE_TOKEN`. + +## Procédure vérifiée depuis un clone propre + +Installer Windows, Node `24.18.x`, npm, le SDK .NET 8, Rust stable et les +prérequis Tauri v2, puis exécuter depuis la racine : + +```powershell +Set-Location app +npm ci +npm test +npm run build + +Set-Location ..\sim-bridge +dotnet restore +dotnet build --configuration Release +dotnet test --configuration Release + +Set-Location ..\app\src-tauri +cargo check --locked + +Set-Location ..\.. +powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\security-check.ps1 +``` + +Configurer uniquement après restauration les variables nécessaires dans un +fichier local non versionné. L'exécution de l'application et les validations +cloud nécessitent une instance Supabase configurée. Le suivi réel nécessite +MSFS/SimConnect. Le packaging signé nécessite un certificat approprié. + +## Validation exécutée le 24 juillet 2026 + +- `npm ci` : réussi depuis le lockfile ; avertissement `EBADENGINE` à cause de + Node `24.14.1` ; audit npm signalant 2 vulnérabilités modérées. +- `npm test` : 4 fichiers, 11 tests réussis. +- `npm run build` : TypeScript/Vite réussi. +- `dotnet restore` : réussi. +- `dotnet build --configuration Release` : réussi, 0 avertissement, 0 erreur. +- `dotnet test --configuration Release` : code 0, mais aucun projet de tests ni + test exécuté. +- `cargo check --locked` : réussi ; avertissement d'environnement sur la + canonicalisation de `C:\Users\andyd`. +- `scripts/security-check.ps1` : invariants réussis lorsque PowerShell est lancé + avec `-ExecutionPolicy Bypass`. + +Les premiers essais de `npm ci`, `dotnet restore` et `dotnet test` ont échoué +par refus d'accès du bac à sable aux caches/configurations utilisateur, puis ont +réussi avec cet accès autorisé. Le premier lancement direct du script de sécurité +a été bloqué par la politique PowerShell locale, puis a réussi avec le bypass +explicite. Ces échecs sont classés comme environnement, pas comme défauts du code. + +## Contrôles non exécutables dans cette baseline + +- Connexion réelle à MSFS/SimConnect, replay de trace et parcours de vol : MSFS + absent et aucun replay automatisé fourni. +- Démarrage/reset Supabase local, application des migrations et tests RLS entre + deux utilisateurs : Supabase CLI absente et aucun environnement de test fourni. +- Déploiement de l'Edge Function et validation cloud : projet/identifiants + Supabase absents. +- Build installable signé, installation, mise à jour et rollback : aucun + certificat de signature ni pipeline de release complet fourni. +- Validation manuelle complète de l'interface : services externes requis absents. + +## Sécurité déjà présente + +- Bridge lié à localhost. +- Jeton aléatoire d'instance entre Tauri et bridge. +- CSP Tauri et capacités limitées. +- Clôture de vol privilégiée déplacée vers une Edge Function/RPC. +- Migrations de durcissement RLS/grants. +- CI avec audits de dépendances, scan de secrets et invariants. + +## Dette et risques structurants + +- Aucun projet de tests .NET dédié constaté. +- Aucun test RLS automatisé livré constaté. +- Le build Tauri complet dépend du sidecar généré dans `externalBin`. +- L'environnement local Node ne satisfait pas le moteur déclaré. +- Les README divergent (`Node 24.18 LTS` contre `Node 20+`) et utilisent + `npm install` au lieu de la restauration déterministe `npm ci`. +- Deux vulnérabilités npm modérées sont signalées ; aucune mise à jour n'a été + faite dans T0001. +- Pages React volumineuses et mélange UI/orchestration/données. +- Mutations métier directes depuis le client et séquences multi-écritures non + atomiques. +- Pas de pipeline complet de release signée/updater. +- Versions répétées dans plusieurs manifestes. +- Modèle solo ou VA collaborative non tranché. + +## Travail local à préserver + +La modification utilisateur de `app/src-tauri/Cargo.toml` est restée intacte +pendant T0001. Son empreinte SHA-256 avant et après validation est +`94BF4E46145BC363B70BD3EEE5BBA578EF198718EBDADB7264C260FEAFAE2AFE`. +Les autres modifications utilisateur préexistantes n'ont pas été intégrées au +ticket. + +## Prochain ticket recommandé + +`T0002 — Choisir le modèle produit solo ou collaboratif`. Cette décision précède +le schéma cible, les rôles, les politiques RLS et la stratégie de refonte. La +matrice Windows/MSFS sera traitée ensuite dans T0004. + +## Mise à jour de ce fichier + +Après chaque ticket terminé, modifier uniquement : + +- capacités réellement disponibles ; +- structure ou dépendances actives ; +- validation réellement exécutée ; +- dette ajoutée/résolue ; +- prochain ticket recommandé. + +Ne pas y copier l'historique Git ni les projets futurs. diff --git a/docs/KNOWN_ISSUES.md b/docs/KNOWN_ISSUES.md new file mode 100644 index 0000000..fdbfd81 --- /dev/null +++ b/docs/KNOWN_ISSUES.md @@ -0,0 +1,32 @@ +# Problèmes connus et follow-ups + +Ce registre contient uniquement les découvertes réelles hors périmètre d'un +ticket. La roadmap contient le travail planifié. + +## Format + +| ID | Sévérité | Zone | Résumé | Preuve | Ticket cible | Statut | +| --- | --- | --- | --- | --- | --- | --- | + +Sévérité : `Critical`, `High`, `Medium`, `Low`. +Statut : `Open`, `Accepted`, `Scheduled`, `Resolved`, `Invalid`. + +## Entrées initiales + +| ID | Sévérité | Zone | Résumé | Preuve | Ticket cible | Statut | +| --- | --- | --- | --- | --- | --- | --- | +| KI-001 | High | Data | Certaines mutations métier sont encore effectuées directement par le client. | Audit initial | Phase 2 | Open | +| KI-002 | High | Quality | Absence de suite automatisée RLS A/B/anonyme. | Audit initial | Phase 1–2 | Open | +| KI-003 | High | Release | Pas de pipeline complet d'artefacts/updater signés. | Audit initial | Phase 6 | Open | +| KI-004 | Medium | Bridge | Pas de projet de tests .NET/replay SimConnect constaté. | Audit initial | Phase 3 | Open | +| KI-005 | Medium | Frontend | Plusieurs pages mélangent UI, règles et accès aux données. | Audit initial | Phase 4 | Open | +| KI-006 | Medium | Docs | Documentation historique partiellement désynchronisée. | Audit initial | T0001 | Open | +| KI-007 | Medium | Product | Mode solo ou VA collaborative non tranché. | Audit initial | T0002 | Open | + +## Règles + +- Ajouter une preuve reproductible. +- Lier à un ticket lorsqu'il devient planifié. +- Ne pas résoudre discrètement un problème hors scope. +- Retirer une entrée uniquement si son historique reste traçable dans un ticket. + diff --git a/docs/PRODUCT.md b/docs/PRODUCT.md new file mode 100644 index 0000000..9f9f7e3 --- /dev/null +++ b/docs/PRODUCT.md @@ -0,0 +1,85 @@ +# Vision produit — Thrustline Rebuild + +Statut : Draft à valider avant la phase 1. + +## Vision + +Thrustline transforme les vols MSFS en gestion cohérente d'une compagnie +aérienne virtuelle : planifier, exploiter, suivre, analyser et développer une +compagnie sans perdre les données ni pouvoir falsifier facilement son économie. + +## Principes produit + +- Windows-first et MSFS-first. +- Fonctionnel même lorsque MSFS est fermé pour la partie gestion. +- Dégradation claire en cas de panne Supabase, SimBrief, météo ou SimConnect. +- Aucune perte silencieuse d'un vol ou d'une transaction. +- Les calculs importants sont explicables à l'utilisateur. +- Les mises à jour sont signées, récupérables et non destructrices. +- Vie privée par défaut ; télémétrie facultative et transparente. + +## Utilisateur principal + +Un passionné de simulation qui gère sa propre compagnie et effectue lui-même des +vols dans MSFS. + +## Décision produit requise + +Avant le schéma final, choisir explicitement : + +- **Solo connecté** : une compagnie appartient à un utilisateur ; +- **VA collaborative** : plusieurs membres, rôles, invitations et pilotes. + +La phase de fondation part du mode solo tant qu'une ADR n'adopte pas le mode +collaboratif. Ne pas ajouter partiellement du multi-utilisateur. + +## Parcours essentiels + +1. Installer, lancer et créer/se connecter à un compte. +2. Créer une compagnie sans état partiel. +3. Acheter ou louer un avion. +4. Créer un dispatch et préparer le vol avec SimBrief. +5. Connecter MSFS et suivre les phases du vol. +6. Reprendre après une déconnexion ou un crash. +7. Finaliser le vol une seule fois. +8. Voir les impacts financiers, réputation et maintenance. +9. Planifier des opérations passives sans incohérence temporelle. +10. Mettre à jour ou désinstaller sans perdre les données. + +## MVP de la refonte + +- Authentification et compagnie. +- Flotte, maintenance et propriété. +- Routes, dispatch et SimBrief. +- SimConnect, phases de vol, ACARS résumé et rapport. +- Grand livre financier autoritaire. +- Réputation et progression minimales. +- Sauvegarde cloud, reprise et diagnostics. +- Installateur et mises à jour signés. + +## Hors MVP + +- Réseau social, marketplace communautaire et mods. +- Application mobile. +- Tableau de bord web public. +- Multi-VA complexe. +- Simulation économique exhaustive. +- Anti-triche présenté comme inviolable. + +## Contraintes de distribution + +- Windows 10/11 à confirmer par matrice de tests. +- MSFS 2020/2024 et éditions réellement supportées à documenter. +- Aucun privilège administrateur permanent. +- Données utilisateur séparées des fichiers d'installation. +- Politique de confidentialité, support, sécurité et licence avant bêta publique. + +## Mesures de réussite + +- Sessions sans crash ≥ objectif défini avant bêta. +- Zéro double clôture de vol. +- Zéro variation financière sans écriture de grand livre. +- Reprise après coupure testée sur chaque parcours essentiel. +- Temps de démarrage et consommation mémoire budgétés. +- Mise à jour N-1 → N et rollback validés sur VM propre. + diff --git a/docs/QUALITY.md b/docs/QUALITY.md new file mode 100644 index 0000000..77be4b4 --- /dev/null +++ b/docs/QUALITY.md @@ -0,0 +1,96 @@ +# Stratégie qualité et validation + +## Principe + +« Le build passe » ne signifie pas « la fonctionnalité fonctionne ». Chaque +ticket associe tests automatisés, vérification manuelle courte et preuve de +résultat. + +## Pyramide de tests + +### Unitaires + +- Calculs d'économie, carburant, maintenance, satisfaction et réputation. +- Machine à états de vol avec horloge et SimConnect factices. +- Validation, conversion d'unités et génération d'horaires. +- Composants React purs et hooks déterministes. + +### Intégration + +- PostgreSQL/RPC/RLS dans Supabase local. +- Deux utilisateurs, anonyme et service serveur. +- REST/SignalR entre frontend et bridge. +- Sérialisation des contrats TypeScript/C#/SQL. +- Reconnexion, timeout et rejeu idempotent. + +### End-to-end + +- Installation et premier lancement. +- Auth → compagnie → avion → dispatch. +- Trace de vol rejouée → rapport → clôture unique. +- Crash/coupure puis reprise. +- Upgrade N-1 → N, rollback et désinstallation. + +### Manuel MSFS + +- MSFS fermé, lancement tardif et redémarrage. +- Vol normal, touch-and-go, go-around, pause, slew et accélération temporelle. +- Perte réseau pendant et après le vol. +- Plusieurs appareils/add-ons représentatifs. + +## Matrice de validation par zone + +| Zone | Minimum | +| --- | --- | +| React/TypeScript | tests concernés + `npm run build` | +| .NET/SimConnect | unit tests + `dotnet build` | +| Rust/Tauri | `cargo check --locked` + test de capacité | +| Supabase | migration propre + tests RLS A/B/anonyme | +| Contrat transverse | tests de contrat + builds des consommateurs | +| Sécurité | scénario d'abus et contrôle rejeté | +| Release | VM propre, signature, upgrade et rollback | + +## Budgets initiaux à fixer en phase 0 + +- temps de démarrage sur machine cible ; +- mémoire au repos et pendant un vol long ; +- fréquence maximale de rendu de télémétrie ; +- taille d'installateur et de mise à jour ; +- latence des commandes critiques ; +- sessions sans crash ; +- temps maximum de récupération après déconnexion. + +## Vérification manuelle d'un ticket + +Elle doit tenir en 5–10 minutes quand le ticket est correctement découpé : + +1. préparer un état connu ; +2. effectuer l'action principale ; +3. observer le résultat attendu ; +4. tester au moins une erreur ou limite ; +5. vérifier logs/console sans secret ; +6. relancer pour confirmer la persistance si pertinente. + +## Preuves + +Le Completion Report conserve : + +- commandes exactes et codes de sortie ; +- nombre de tests réussis/échoués ; +- contrôles non exécutés et raison ; +- étapes manuelles et résultat ; +- capture ou extrait uniquement si utile et sans donnée sensible. + +## Release gate + +Une release publique exige : + +- tests verts sur un commit propre ; +- zéro secret détecté ; +- audits sans vulnérabilité bloquante ; +- migrations et restauration validées ; +- artefacts signés et vérifiés ; +- SBOM/checksums/provenance ; +- parcours critiques sur VM propre ; +- notes de version, limitations et procédure de rollback. + diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..00bbd4b --- /dev/null +++ b/docs/README.md @@ -0,0 +1,64 @@ +# Centre de pilotage de la refonte + +Ce dossier est la mémoire partagée entre Andy, les agents de planification et +Codex. Il est inspiré d'un workflow « planifier → ticket → implémenter → vérifier +→ actualiser », avec moins de doublons documentaires. + +## Lecture rapide + +| Besoin | Document | +| --- | --- | +| Comprendre le produit | `PRODUCT.md` | +| Comprendre la cible technique | `ARCHITECTURE.md` | +| Connaître l'état réel | `CURRENT_STATE.md` | +| Choisir le prochain travail | `ROADMAP.md` puis `tickets/` | +| Exécuter un ticket | `WORKFLOW.md` | +| Vérifier une modification | `QUALITY.md` | +| Appliquer les règles de sécurité | `SECURITY.md` | +| Voir les problèmes différés | `KNOWN_ISSUES.md` | +| Prendre une décision structurante | `decisions/README.md` | +| Créer un ticket | `templates/TICKET.md` | + +## Sources de vérité + +Il n'existe que quatre documents d'état à maintenir : + +1. `PRODUCT.md` : ce que Thrustline doit être ; +2. `ARCHITECTURE.md` : comment le système est structuré ; +3. `CURRENT_STATE.md` : ce qui existe aujourd'hui ; +4. les tickets : ce qui est prévu, en cours ou terminé. + +`SECURITY.md`, `QUALITY.md` et `WORKFLOW.md` sont des règles relativement stables. +Les ADR conservent l'historique des décisions sans réécrire le passé. + +## Cycle + +```text +Vision / contraintes + ↓ +Roadmap par résultats + ↓ +Ticket petit et vérifiable + ↓ +Revue du ticket avant code + ↓ +Branche isolée + implémentation + ↓ +Tests + vérification manuelle + ↓ +Revue sécurité / architecture + ↓ +Completion Report + ↓ +CURRENT_STATE + ticket suivant +``` + +## Discipline documentaire + +- Ne jamais copier la même information dans plusieurs fichiers. +- Une décision structurante devient un ADR. +- Une découverte hors périmètre devient une entrée dans `KNOWN_ISSUES.md`. +- `CURRENT_STATE.md` décrit le présent, jamais les intentions. +- La roadmap décrit des résultats, pas un historique de commits. +- Les détails exécutables appartiennent au ticket. + diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..e97e510 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,110 @@ +# Roadmap de la refonte + +La roadmap est ordonnée par réduction du risque. Elle décrit des résultats ; les +détails d'exécution appartiennent aux tickets. + +## Phase 0 — Baseline et décisions + +Objectif : rendre l'existant mesurable et décider ce que l'on reconstruit. + +- Inventaire reproductible, tests/builds et matrice de dépendances. +- Décision solo connecté vs VA collaborative. +- Matrice Windows/MSFS supportée. +- Budgets stabilité/performance et politique de données. +- Choix : réécriture incrémentale ou remplacement par strangler pattern. +- Environnements dev/staging/prod documentés. + +Gate : baseline verte ou écarts connus, ADR majeures acceptées, périmètre MVP gelé. + +## Phase 1 — Socle reproductible + +Objectif : pouvoir reconstruire et tester le produit à tout moment. + +- Versions/outils supportés et bootstrap automatisé. +- Source de version unique. +- CI consolidée et actions épinglées. +- Lint/format/types/tests cohérents. +- Supabase local jetable et données de test. +- Contrats versionnés et génération des types. + +Gate : clone propre → setup → tests/build sans étape secrète non documentée. + +## Phase 2 — Noyau métier autoritaire + +Objectif : empêcher corruption, doubles opérations et calculs client autoritaires. + +- Modèle de domaine et grand livre immuable. +- Commandes transactionnelles/idempotentes. +- RLS A/B/anonyme. +- Concurrence optimiste et audit. +- Migration/reconciliation des données existantes. + +Gate : aucune mutation sensible directe depuis un composant client. + +## Phase 3 — Bridge et moteur de vol stables + +Objectif : rendre la détection de vol déterministe et récupérable. + +- Domaine indépendant de SimConnect. +- Replays de traces et projet de tests .NET. +- Reconnexion, pause, slew, go-around, touch-and-go et crash. +- Canal local durci et cycle de vie robuste. +- Rapport de vol versionné et outbox de reprise. + +Gate : parcours critiques reproductibles sans lancer MSFS. + +## Phase 4 — Application cliente maintenable + +Objectif : reconstruire l'UX sur des fondations testables. + +- Architecture par fonctionnalités. +- Couche queries/commands. +- Auth et onboarding résilients. +- Flotte, routes, dispatch, vol live, finances. +- États offline/pending/rejected explicites. +- Accessibilité et design system. + +Gate : golden path E2E stable et aucun écran critique monolithique. + +## Phase 5 — Opérations passives et progression + +Objectif : réintroduire la profondeur de jeu côté serveur. + +- Horaires/rotations atomiques. +- Jobs serveur temporels et déterministes. +- Maintenance, équipage, prêts, réputation et événements. +- Tests de simulation longue et cohérence économique. + +Gate : simulation accélérée sans création/destruction inexpliquée de valeur. + +## Phase 6 — Distribution sûre + +Objectif : produire une bêta installable et récupérable. + +- Authenticode, installateur, SBOM, checksums et provenance. +- Updater signé, canaux stable/bêta et rollback. +- Logs redigés, diagnostics consentis et crash reporting. +- Politique sécurité, confidentialité, licence et support. +- Tests VM Windows/MSFS. + +Gate : installation, upgrade N-1, rollback et désinstallation validés. + +## Phase 7 — Bêta fermée et stabilisation + +Objectif : mesurer en conditions réelles sans ajouter de fonctionnalités. + +- Cohorte limitée et procédure d'incident. +- SLO, triage et retour utilisateur. +- Tests longue durée et correction des régressions. +- Sauvegarde/restauration. + +Gate : deux releases consécutives respectent les objectifs de stabilité. + +## Phase 8 — Après stabilité + +- Collaboration multi-rôle si décidée. +- Tableau de bord web. +- Import/export avancé. +- Administration et audit étendu. +- Modding avec permissions/signatures dédiées. + diff --git a/docs/SECURITY.md b/docs/SECURITY.md new file mode 100644 index 0000000..6546d24 --- /dev/null +++ b/docs/SECURITY.md @@ -0,0 +1,100 @@ +# Règles de sécurité + +Ces règles sont des critères de livraison, pas des améliorations facultatives. + +## Modèle de menace minimal + +Supposer qu'un attaquant peut : + +- modifier le frontend et appeler Supabase directement ; +- lire les fichiers et la mémoire de son propre poste ; +- envoyer une télémétrie MSFS fabriquée ; +- rejouer ou interrompre des requêtes ; +- fournir fichiers, URLs et identifiants malformés ; +- analyser tous les binaires distribués. + +## Règles obligatoires + +### Secrets + +- Jamais de `service_role`, mot de passe, clé privée ou certificat dans le dépôt, + le frontend, le bridge ou les artefacts distribués. +- JWT utilisateur en mémoire seulement si possible, purgé au logout/expiration. +- Aucun secret, header Authorization ou donnée personnelle dans les logs. +- Rotation immédiate après exposition supposée. + +### Autorisation et économie + +- Identité déduite du JWT côté serveur. +- Vérifier rôle, ownership et transition pour chaque commande. +- Ne jamais faire confiance aux prix, gains, rangs, scores, durées ou company IDs + envoyés comme autorité par le client. +- Argent, propriété, dette, réputation et récompenses : transaction serveur. +- Commandes idempotentes avec `operation_id`. +- Grand livre financier immuable ; correction par compensation. + +### Entrées + +- Schémas stricts, limites de taille et plages numériques. +- Rejeter NaN, infini, propriétés inattendues et formats ambigus. +- SQL paramétré uniquement. +- Aucun contenu non fiable vers shell ou exécution dynamique. +- Chemins normalisés et confinés ; imports contrôlés par contenu réel. + +### Desktop et réseau + +- Bridge loopback uniquement et authentifié par instance. +- Port/conduit non accessible aux autres utilisateurs locaux lorsque possible. +- CORS et capacités Tauri en allowlist. +- URL externe validée côté Rust : protocole et domaine autorisés. +- HTTPS et validation TLS obligatoires. +- Timeouts, limites de réponse et rate limiting. +- Aucun besoin de lancer l'application comme administrateur. + +### Supabase + +- RLS sur toute table exposée. +- `PUBLIC` révoqué par défaut. +- Fonctions `security definer` avec `search_path` fixe et contrôles internes. +- Tests automatisés anonyme, utilisateur A et utilisateur B. +- Migrations append-only et testées sur base jetable. +- Clé privilégiée uniquement dans une fonction serveur contrôlée. + +### Vie privée + +- Collecte minimale et finalité écrite. +- Discord Rich Presence et diagnostics clairement désactivables. +- Consentement avant envoi de logs ou télémétrie facultative. +- Rétention, export et suppression des données documentés. + +### Supply chain et release + +- Lockfiles, audits npm/NuGet/Rust, scan de secrets et licences. +- Actions CI épinglées à des SHA immuables. +- Secrets CI interdits aux PR de forks. +- EXE, installateur et manifeste de mise à jour signés. +- Checksum, SBOM et provenance publiés. +- Vulnérabilité critique/haute bloque la release sauf exception écrite et limitée. + +## Revue sécurité d'un ticket + +Tout ticket touchant auth, DB, fichiers, réseau, IPC, shell, update, télémétrie ou +économie doit documenter : + +- actifs et données concernés ; +- frontière traversée ; +- abus plausibles ; +- validation et autorisation ; +- atomicité/idempotence ; +- journalisation et vie privée ; +- tests négatifs et inter-utilisateurs. + +## Réponse à incident + +1. Contenir et préserver les preuves. +2. Révoquer les secrets concernés. +3. Corriger la cause et ajouter un test de régression. +4. Préparer une release signée. +5. Informer les utilisateurs affectés si nécessaire. +6. Consigner l'incident et l'action préventive. + diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md new file mode 100644 index 0000000..b5c7f06 --- /dev/null +++ b/docs/WORKFLOW.md @@ -0,0 +1,121 @@ +# Workflow de refonte + +## Rôles + +- **Andy — Product Owner** : tranche la vision, le périmètre et les compromis. +- **Agent planificateur** : analyse le dépôt, propose ADR, roadmap et tickets. +- **Codex implémenteur** : exécute un ticket borné et fournit les preuves. +- **Reviewer** : cherche régressions, failles, dérive architecturale et tests + manquants avant validation. + +Un même outil peut tenir plusieurs rôles, mais pas dans la même étape sans +effectuer une revue adversariale explicite. + +## États d'un ticket + +`Draft → Ready → In progress → Review → Verify → Done` + +États alternatifs : `Blocked`, `Rejected`, `Superseded`. + +## 1. Préparer la phase + +1. Définir le résultat utilisateur. +2. Écrire/valider les ADR structurantes. +3. Identifier dépendances et risques. +4. Découper en vertical slices. +5. Créer seulement les 3–8 prochains tickets détaillés ; garder le reste au + niveau roadmap pour éviter un plan périmé de 50 tickets. + +## 2. Rendre un ticket Ready + +Un ticket Ready contient : + +- objectif unique ; +- dépendances satisfaites ; +- zones autorisées et interdites ; +- exigences et non-objectifs ; +- critères d'acceptation observables ; +- tests attendus ; +- vérification manuelle de 5–10 minutes ; +- revue sécurité si nécessaire. + +Le reviewer challenge le ticket avant tout code : trop large, ambigu, mauvaise +frontière ou absence de preuve = retour en Draft. + +## 3. Implémenter + +1. Créer une branche `type/TXXXX-slug`. +2. Lire `AGENTS.md`, `CURRENT_STATE.md`, le ticket et les docs liées. +3. Vérifier l'état Git et préserver les changements existants. +4. Inspecter le code réel. +5. Implémenter seulement le ticket. +6. Exécuter d'abord les tests ciblés, puis les gates applicables. +7. Ne pas corriger les découvertes hors scope ; les consigner. + +Types de branche : `foundation`, `feature`, `fix`, `security`, `refactor`, `docs`. + +## 4. Revoir + +La revue vérifie dans cet ordre : + +1. sécurité et perte de données ; +2. conformité aux critères ; +3. régressions et compatibilité ; +4. architecture et dette créée ; +5. tests et observabilité ; +6. lisibilité et performance. + +Une revue ne doit pas demander une réécriture esthétique sans bénéfice mesurable. + +## 5. Vérifier + +Effectuer la checklist manuelle du ticket. Si elle échoue, le ticket revient en +`In progress`. Si elle est impossible localement, indiquer précisément qui doit +la faire et sur quel environnement ; le ticket reste `Verify`. + +## 6. Clore + +1. Remplir le Completion Report dans le ticket. +2. Actualiser `CURRENT_STATE.md` si l'état réel a changé. +3. Ajouter les problèmes différés dans `KNOWN_ISSUES.md`. +4. Mettre à jour une ADR seulement par une nouvelle ADR qui la remplace. +5. Fusionner après checks et revue. +6. Choisir le prochain ticket Ready. + +## Limites de taille + +Un bon ticket : + +- vise un résultat ; +- modifie idéalement une frontière principale ; +- produit un diff révisable ; +- se vérifie manuellement en 5–10 minutes ; +- peut être abandonné sans invalider plusieurs jours de travail. + +Si le ticket combine migration, nouveau protocole, gros écran et pipeline release, +le diviser. + +## Commande de démarrage recommandée + +```text +Implémente uniquement le ticket TXXXX. + +Lis AGENTS.md, docs/CURRENT_STATE.md et le ticket complet. +Respecte Allowed areas et Do not touch. +Avant de coder, signale toute contradiction bloquante. +Après le changement, exécute les validations du ticket et remplis son +Completion Report avec preuves, risques et follow-ups. +``` + +## Rétrospective + +À la fin de chaque phase : + +- quelles règles ont évité une erreur ? +- quels tickets étaient trop grands ou ambigus ? +- quels contrôles manquaient ? +- quels documents ont dérivé ? +- quelle automatisation répétée mérite un script ou une skill ? + +Modifier le workflow uniquement sur la base d'un problème répété. + diff --git a/docs/decisions/README.md b/docs/decisions/README.md new file mode 100644 index 0000000..df81104 --- /dev/null +++ b/docs/decisions/README.md @@ -0,0 +1,22 @@ +# Architecture Decision Records + +Les ADR conservent les décisions difficiles et leur contexte. Ils évitent que les +agents réouvrent sans cesse une question ou suivent une règle devenue obsolète. + +## Convention + +- `ADR-0001-solo-or-collaborative.md` +- Numéro séquentiel, titre stable. +- Une ADR acceptée n'est pas réécrite pour changer l'histoire. +- Une nouvelle ADR peut en remplacer une ancienne. +- Les détails d'implémentation ordinaires restent dans les tickets. + +## ADR prioritaires + +1. Modèle solo connecté ou VA collaborative. +2. Stratégie de refonte incrémentale. +3. Canal local Tauri ↔ bridge. +4. Stockage/cache hors ligne. +5. Autorité et modèle anti-triche. +6. Stratégie de distribution et mise à jour. + diff --git a/docs/templates/ADR.md b/docs/templates/ADR.md new file mode 100644 index 0000000..f847050 --- /dev/null +++ b/docs/templates/ADR.md @@ -0,0 +1,42 @@ +# ADR-XXXX — Titre de la décision + +Status: Proposed / Accepted / Rejected / Superseded +Date: YYYY-MM-DD +Deciders: +Supersedes: +Superseded by: + +## Context + +Problème, contraintes et forces en présence. + +## Decision drivers + +- Critères qui déterminent le choix. + +## Options considered + +### Option A + +Avantages, coûts et risques. + +### Option B + +Avantages, coûts et risques. + +## Decision + +Choix précis et raisons. + +## Consequences + +### Positive + +### Negative + +### Risks and mitigations + +## Validation + +Comment vérifier que la décision produit le résultat attendu. + diff --git a/docs/templates/PHASE_REVIEW.md b/docs/templates/PHASE_REVIEW.md new file mode 100644 index 0000000..dcc2bf4 --- /dev/null +++ b/docs/templates/PHASE_REVIEW.md @@ -0,0 +1,24 @@ +# Revue de phase — Phase X + +Date: +Participants: +Result: Pass / Conditional / Fail + +## Outcomes delivered + +## Gate evidence + +## Stability and security + +## Deferred work + +## Metrics + +## What worked + +## What caused friction + +## Workflow changes justified + +## Decision for next phase + diff --git a/docs/templates/TICKET.md b/docs/templates/TICKET.md new file mode 100644 index 0000000..2a21cb3 --- /dev/null +++ b/docs/templates/TICKET.md @@ -0,0 +1,92 @@ +# TXXXX — Titre orienté résultat + +Status: Draft +Owner: Unassigned +Branch: `type/txxxx-slug` +Phase: X +Risk: Low / Medium / High +Security-sensitive: Yes / No + +## Goal + +Un seul résultat utilisateur ou technique observable. + +## Context + +Pourquoi ce ticket existe, état actuel et liens utiles. + +## Dependencies + +- Tickets/ADR/prérequis nécessaires. + +## Allowed areas + +- Fichiers ou dossiers modifiables. + +## Do not touch + +- Zones explicitement exclues. + +## Requirements + +- Comportements obligatoires. +- Contraintes techniques. + +## Non-goals + +- Fonctionnalités voisines volontairement exclues. + +## Acceptance criteria + +- [ ] Critère observable et testable. +- [ ] Erreur/limite pertinente couverte. +- [ ] Documentation synchronisée si nécessaire. + +## Security review + +À remplir si `Security-sensitive: Yes` : + +- actifs/données : +- frontière : +- abus : +- validation/autorisation : +- atomicité/idempotence : +- logs/vie privée : + +## Automated validation + +```powershell +# Commandes exactes attendues +``` + +## Manual verification + +1. Préparer… +2. Exécuter… +3. Confirmer… +4. Tester l'erreur… + +Temps cible : 5–10 minutes. + +## Rollback + +Comment abandonner/revenir en arrière sans perte de données. + +## Completion Report + +À remplir après implémentation. + +### Summary + +### Files changed + +### Commands and results + +### Manual verification result + +### Risks and limitations + +### Follow-ups + +### Documentation updated + diff --git a/docs/tickets/README.md b/docs/tickets/README.md new file mode 100644 index 0000000..9e39daf --- /dev/null +++ b/docs/tickets/README.md @@ -0,0 +1,28 @@ +# Tickets de refonte + +Créer un fichier par ticket à partir de `docs/templates/TICKET.md`. + +## Convention + +- Nom : `T0001-baseline-reproductible.md` +- Un ticket = un résultat et une branche. +- Les tickets détaillés ne sont créés que quelques étapes à l'avance. +- Le statut et le Completion Report restent dans le fichier du ticket. +- Un ticket terminé est conservé pour la traçabilité. + +## Backlog initial + +| ID | Titre | Phase | Dépend de | Statut | +| --- | --- | --- | --- | --- | +| T0001 | Baseline reproductible et inventaire | 0 | — | Done | +| T0002 | Choisir le modèle produit solo ou collaboratif | 0 | T0001 | Ready | +| T0003 | ADR stratégie de refonte | 0 | T0001–T0002 | Draft | +| T0004 | Matrice de support Windows/MSFS | 0 | T0001 | Draft | +| T0005 | Budgets stabilité et performance | 0 | T0001 | Draft | +| T0006 | Consolider CI et versions d'outils | 1 | T0003 | Backlog | +| T0007 | Supabase local et tests RLS | 1 | T0003 | Backlog | +| T0008 | Source de version unique | 1 | T0003 | Backlog | + +T0002 est le prochain ticket exécutable. Les tickets suivants doivent être +affinés après sa décision pour éviter de figer une architecture fondée sur une +hypothèse produit. diff --git a/docs/tickets/T0001-baseline-reproductible.md b/docs/tickets/T0001-baseline-reproductible.md new file mode 100644 index 0000000..97424df --- /dev/null +++ b/docs/tickets/T0001-baseline-reproductible.md @@ -0,0 +1,205 @@ +# T0001 — Baseline reproductible et inventaire + +Status: Done +Owner: Unassigned +Branch: `foundation/t0001-baseline-reproductible` +Phase: 0 +Risk: Low +Security-sensitive: No + +## Goal + +Produire une baseline vérifiée et reproductible de la version actuelle avant toute +refonte, sans changer son comportement. + +## Context + +Les documents historiques et le code ont divergé. La refonte ne doit pas partir +d'hypothèses sur les builds, tests, dépendances, fonctionnalités ou secrets requis. + +## Dependencies + +- Aucune. + +## Allowed areas + +- Documentation sous `docs/`. +- Scripts de diagnostic non destructifs sous `scripts/` si indispensable. +- Fichiers de configuration uniquement pour corriger une erreur de baseline + explicitement séparée et approuvée. + +## Do not touch + +- Comportement produit. +- Schéma/migrations Supabase. +- `legacy/`. +- Modification utilisateur existante dans `app/src-tauri/Cargo.toml`. +- Mise à niveau de dépendances. + +## Requirements + +- Relever versions Node/npm, .NET, Rust et Supabase CLI. +- Installer/restaurer uniquement depuis les lockfiles. +- Exécuter tests et builds disponibles. +- Inventorier scripts, workflows, migrations, dépendances directes et variables + d'environnement par leur nom seulement. +- Relever les parcours fonctionnels réellement présents. +- Relever les contrôles impossibles sans MSFS/Supabase/certificat. +- Actualiser `docs/CURRENT_STATE.md` avec preuves datées. + +## Non-goals + +- Corriger les échecs. +- Concevoir l'architecture finale. +- Mettre à jour les dépendances. +- Nettoyer ou déplacer le code. + +## Acceptance criteria + +- [x] Une machine neuve peut suivre les étapes documentées. +- [x] Chaque commande exécutée et son résultat sont consignés. +- [x] Les échecs sont classés code, environnement ou dépendance externe. +- [x] Aucun secret ni valeur de secret n'est affiché. +- [x] L'état Git utilisateur est préservé. +- [x] Le prochain ticket recommandé repose sur les preuves collectées. + +## Automated validation + +```powershell +Set-Location app +npm ci +npm test +npm run build + +Set-Location ..\sim-bridge +dotnet restore +dotnet build --configuration Release +dotnet test --configuration Release + +Set-Location ..\app\src-tauri +cargo check --locked + +Set-Location ..\.. +.\scripts\security-check.ps1 +``` + +## Manual verification + +1. Confirmer que seuls les noms des variables/secrets sont documentés. +2. Comparer les commandes README avec les commandes réellement réussies. +3. Vérifier que `git status` conserve la modification Cargo préexistante. +4. Relire `CURRENT_STATE.md` et retirer toute affirmation non prouvée. + +## Rollback + +Revenir uniquement aux changements documentaires/scripts du ticket. Ne toucher à +aucun fichier utilisateur préexistant. + +## Completion Report + +### Summary + +Baseline exécutée sous Windows le 24 juillet 2026 sans changement de comportement +ni mise à niveau. Les restaurations lockées, tests/builds disponibles et +invariants ont été exécutés. L'inventaire des outils, dépendances directes, +scripts, workflows, migrations, variables par nom et parcours visibles est +consigné dans `docs/CURRENT_STATE.md`. + +### Files changed + +- `docs/CURRENT_STATE.md` +- `docs/tickets/T0001-baseline-reproductible.md` + +Aucun script, code, manifeste, lockfile, migration ou fichier sous `legacy/` n'a +été modifié pour T0001. + +### Commands and results + +| Commande | Résultat | Classement | +| --- | --- | --- | +| `node --version` | `v24.14.1` | Réussi ; environnement inférieur au moteur `>=24.18.0 <25` | +| `npm --version` | Script `npm.ps1` bloqué par la politique PowerShell | Environnement | +| `npm.cmd --version` | `11.11.0` | Réussi | +| `dotnet --version` | `10.0.201` | Réussi ; projet ciblant .NET 8 | +| `rustc --version` | `1.94.1` | Réussi avec avertissement de canonicalisation du profil | +| `cargo --version` | `1.94.1` | Réussi avec avertissement de canonicalisation du profil | +| `supabase --version` | Commande introuvable | Dépendance externe/outillage absent | +| `npm.cmd ci` (initial) | `EPERM` sur le cache npm utilisateur | Environnement/bac à sable | +| `npm.cmd ci` (accès autorisé) | Réussi, 283 paquets ; avertissement `EBADENGINE`, 2 vulnérabilités modérées | Réussi avec risques connus | +| `npm.cmd test` | 4 fichiers, 11 tests réussis | Réussi | +| `npm.cmd run build` | TypeScript et Vite réussis | Réussi | +| `dotnet restore` (initial) | Accès refusé à `NuGet.Config` utilisateur | Environnement/bac à sable | +| `dotnet restore` (accès autorisé) | Réussi, projets à jour | Réussi | +| `dotnet build --configuration Release` | Réussi, 0 avertissement, 0 erreur | Réussi | +| `dotnet test --configuration Release` (initial) | Accès refusé à `NuGet.Config` utilisateur | Environnement/bac à sable | +| `dotnet test --configuration Release` (accès autorisé) | Code 0, aucun projet/test découvert | Réussi sans couverture de tests | +| `cargo check --locked` | Réussi ; avertissement de canonicalisation de `C:\Users\andyd` | Réussi avec limite environnement | +| `.\scripts\security-check.ps1` | Bloqué par la politique d'exécution PowerShell | Environnement | +| `powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\security-check.ps1` | `Security invariants passed.` | Réussi | + +Les commandes de lecture `Get-Content`, `Get-ChildItem`, `Select-Xml`, `rg`, +`git status`, `git diff`, `Get-FileHash` et la lecture JSON PowerShell ont servi +à l'inventaire et aux vérifications manuelles. Elles ont réussi, sauf une tentative +de lecture globale de `package-lock.json` avec `ConvertFrom-Json` (erreur +PowerShell sur un nom de propriété) et les avertissements non bloquants de Git sur +l'accès au fichier d'exclusion global utilisateur. La restauration npm prouve +néanmoins que le lockfile est exploitable. + +Résultat de l'inventaire en lecture seule : + +- 25 migrations SQL ; +- workflows `.github/workflows/ci.yml` et `.github/workflows/security.yml` ; +- scripts `build-sidecar.ps1` et `security-check.ps1` ; +- 11 dépendances npm runtime, 12 npm développement, 2 NuGet, 6 Cargo + runtime et 1 Cargo build ; +- variables/configurations, noms seuls : + `VITE_SUPABASE_URL`, `VITE_SUPABASE_ANON_KEY`, `VITE_SIM_BRIDGE_URL`, + `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, + `THRUSTLINE_BRIDGE_TOKEN`. + +### Manual verification result + +- Seuls des noms de variables/secrets sont présents dans la documentation ; aucune + valeur n'a été copiée. +- Les README ont été comparés : la racine demande Node `24.18 LTS`, + `app/README.md` demande Node `20+`, et les deux indiquent `npm install` alors + que `npm ci` est la commande reproductible vérifiée. Ils n'ont pas été modifiés. +- Le statut Git conserve `app/src-tauri/Cargo.toml` comme modification + préexistante. Son empreinte SHA-256 est identique avant et après : + `94BF4E46145BC363B70BD3EEE5BBA578EF198718EBDADB7264C260FEAFAE2AFE`. +- `docs/CURRENT_STATE.md` a été relu et distingue présence dans le code, + validation automatisée et contrôles externes non exécutés. + +La validation manuelle fonctionnelle de l'interface, d'un vol réel et du cloud +est déléguée à un environnement équipé de MSFS, Supabase et des identifiants de +test appropriés. + +### Risks and limitations + +- Node `24.14.1` ne satisfait pas le moteur déclaré ; la CI emploie `24.18.0`. +- L'audit exécuté par `npm ci` signale 2 vulnérabilités modérées. Elles ne sont + pas corrigées, conformément au non-goal d'absence de mise à jour. +- Aucun test .NET dédié et aucun test RLS automatisé ne sont disponibles. +- MSFS/SimConnect n'a pas été lancé et aucun replay de trace n'existe. +- Supabase CLI, projet de test et certificat de signature sont absents. +- Le build Tauri complet/installable n'a pas été exécuté ; `cargo check --locked` + valide seulement le shell Rust et le build complet dépend du sidecar externe. +- Les restrictions du bac à sable ont nécessité un accès autorisé aux caches npm + et NuGet ; la politique PowerShell a nécessité un bypass explicite. + +### Follow-ups + +- Créer le prochain ticket de phase 0 pour fixer la matrice Windows/MSFS + supportée et un protocole de validation SimConnect reproductible. +- Conserver pour un ticket ultérieur l'alignement des prérequis README, + `package.json` et CI. +- Traiter dans un ticket dédié les vulnérabilités npm après analyse, sans mise à + niveau opportuniste dans T0001. +- Prévoir des tests .NET, des replays SimConnect et des tests RLS A/B/anonyme + dans les phases prévues par la roadmap. + +### Documentation updated + +`docs/CURRENT_STATE.md` contient désormais la baseline datée, la procédure depuis +une machine neuve, l'inventaire, les résultats réels, les contrôles externes +impossibles, les écarts de documentation et le prochain ticket recommandé. diff --git a/docs/tickets/T0002-modele-produit-solo-ou-collaboratif.md b/docs/tickets/T0002-modele-produit-solo-ou-collaboratif.md new file mode 100644 index 0000000..ff98fb5 --- /dev/null +++ b/docs/tickets/T0002-modele-produit-solo-ou-collaboratif.md @@ -0,0 +1,274 @@ +# T0002 — Choisir le modèle produit solo ou collaboratif + +Status: Ready +Owner: Andy +Branch: `docs/t0002-modele-produit` +Phase: 0 +Risk: High +Security-sensitive: Yes + +## Goal + +Décider si la refonte de Thrustline cible : + +1. un produit **solo connecté**, où un utilisateur possède et gère sa compagnie ; +2. une **VA collaborative**, où plusieurs utilisateurs partagent une compagnie + avec des rôles et responsabilités ; +3. un **socle solo préparé pour une extension collaborative ultérieure**, sans + livrer de collaboration dans le MVP. + +La décision doit être consignée dans une ADR acceptée et donner une direction +non ambiguë aux tickets d'architecture et de sélection de stack suivants. + +## Context + +L'application actuelle est principalement conçue autour d'un utilisateur et de +sa compagnie, mais l'expression « gestion de compagnie virtuelle » peut aussi +désigner une VA avec propriétaire, administrateurs, dispatchers et pilotes. + +Ce choix modifie fortement : + +- le périmètre du MVP ; +- le modèle de données et la propriété des ressources ; +- l'authentification et les autorisations ; +- les politiques RLS Supabase ; +- le niveau d'audit et de concurrence ; +- l'UX d'onboarding et d'administration ; +- les coûts de développement, de support et d'hébergement. + +La baseline T0001 est terminée. Aucun schéma cible ni nouveau socle ne doit être +figé avant cette décision. + +## Inputs required from Andy + +Le ticket doit obtenir des réponses explicites aux questions suivantes : + +1. Une compagnie doit-elle pouvoir avoir plusieurs humains membres dès le MVP ? +2. Un pilote peut-il appartenir à plusieurs compagnies ? +3. Les rôles propriétaire, administrateur, dispatcher et pilote sont-ils utiles + dès la première version publique ? +4. Un pilote doit-il pouvoir effectuer un vol préparé par un autre membre ? +5. Les finances, la flotte et les horaires doivent-ils être partagés en temps réel ? +6. Faut-il inviter, exclure, suspendre et transférer la propriété d'une compagnie ? +7. Le produit doit-il permettre de jouer entièrement seul sans gérer de membres ? +8. Une future collaboration est-elle un objectif certain, probable ou simplement + possible ? +9. Quel surcoût et quel délai sont acceptables avant la première bêta ? +10. En cas de conflit, la stabilité du mode solo ou la collaboration doit-elle + être prioritaire ? + +Si une réponse essentielle manque, l'ADR reste `Proposed` et le ticket passe en +`Blocked` plutôt que d'inventer une préférence. + +## Dependencies + +- T0001 terminé. +- `docs/PRODUCT.md` +- `docs/ARCHITECTURE.md` +- `docs/SECURITY.md` +- `docs/CURRENT_STATE.md` + +## Allowed areas + +- `docs/PRODUCT.md` +- `docs/ARCHITECTURE.md` +- `docs/CURRENT_STATE.md` +- `docs/ROADMAP.md` +- `docs/KNOWN_ISSUES.md` +- `docs/decisions/` +- `docs/tickets/README.md` +- ce ticket + +## Do not touch + +- `app/` +- `sim-bridge/` +- `supabase/` +- `legacy/` +- manifests, lockfiles et dépendances +- workflows CI +- secrets ou configuration locale +- modification utilisateur existante dans `app/src-tauri/Cargo.toml` + +## Requirements + +### 1. Décrire les trois options + +Pour chaque option, documenter : + +- utilisateur et parcours principal ; +- périmètre MVP ; +- fonctionnalités obligatoires ; +- modèle de propriété des compagnies et ressources ; +- rôles et permissions ; +- impact sur le schéma et la RLS ; +- impact UX ; +- besoins d'audit, notifications et concurrence ; +- complexité de test et d'exploitation ; +- risques de sécurité et de perte de données ; +- coût relatif et effet sur le délai de bêta ; +- facilité ou difficulté de migration vers une autre option. + +### 2. Produire une matrice de décision + +Noter chaque option de 1 à 5 avec une justification pour : + +- adéquation à la vision d'Andy ; +- rapidité jusqu'à une bêta stable ; +- simplicité et fiabilité ; +- sécurité et maîtrise des permissions ; +- expérience solo ; +- potentiel communautaire ; +- coût d'hébergement et de support ; +- capacité d'évolution. + +Les poids des critères doivent être validés par Andy avant le score final. +La matrice aide à décider ; elle ne remplace pas la décision humaine. + +### 3. Définir précisément le modèle retenu + +L'ADR doit fixer au minimum : + +- cardinalité utilisateur ↔ compagnie ; +- ownership d'une compagnie ; +- rôles disponibles dans le MVP ; +- permissions de chaque rôle ; +- appartenance éventuelle à plusieurs compagnies ; +- invitations et transfert de propriété ; +- visibilité des vols, finances et flotte ; +- comportement lorsque le propriétaire quitte le service ; +- éléments explicitement reportés après le MVP ; +- chemin de migration si la collaboration est différée. + +### 4. Propager la décision + +Après acceptation : + +- créer `docs/decisions/ADR-0001-modele-produit.md` ; +- mettre `docs/PRODUCT.md` en cohérence ; +- ajuster les frontières pertinentes dans `docs/ARCHITECTURE.md` ; +- adapter les phases concernées dans `docs/ROADMAP.md` ; +- résoudre ou mettre à jour `KI-007` dans `docs/KNOWN_ISSUES.md` ; +- actualiser le prochain ticket dans `docs/CURRENT_STATE.md`. + +## Non-goals + +- Implémenter comptes, compagnies, invitations ou rôles. +- Modifier le schéma Supabase ou les politiques RLS. +- Choisir les versions de la stack. +- Choisir la stratégie technique complète de refonte. +- Concevoir tous les écrans. +- Établir une tarification commerciale. +- Ajouter partiellement du multi-utilisateur « pour plus tard ». + +## Acceptance criteria + +- [ ] Les dix questions produit ont reçu une réponse explicite ou sont marquées + comme bloquantes. +- [ ] Les trois options sont comparées selon les mêmes critères. +- [ ] Les poids de la matrice sont approuvés par Andy. +- [ ] L'option retenue est formulée en une phrase sans ambiguïté. +- [ ] Les cardinalités, rôles, permissions et reports après MVP sont définis. +- [ ] Les principaux abus et risques de chaque option sont décrits. +- [ ] `ADR-0001` est `Accepted` et indique qui a pris la décision. +- [ ] `PRODUCT.md`, `ARCHITECTURE.md` et `ROADMAP.md` ne se contredisent plus. +- [ ] Aucun fichier applicatif, migration ou dépendance n'est modifié. +- [ ] Le prochain ticket recommandé est identifié. + +## Security review + +### Assets and data + +- comptes utilisateurs ; +- propriété de la compagnie ; +- flotte, finances, horaires et rapports de vol ; +- rôles, invitations et journal d'audit ; +- données potentiellement visibles entre membres. + +### Trust boundaries + +- desktop public vers Supabase ; +- membre d'une compagnie vers les ressources partagées ; +- administrateur/dispatcher vers les pilotes ; +- utilisateur appartenant éventuellement à plusieurs compagnies. + +### Abuse cases to compare + +- un membre lit ou modifie une autre compagnie ; +- élévation de rôle côté client ; +- invitation ou transfert de propriété forgé ; +- ancien membre conservant un accès ; +- deux responsables modifiant simultanément une ressource ; +- propriétaire supprimé laissant une compagnie orpheline ; +- fraude sur les vols, finances ou récompenses partagées ; +- exposition excessive des données de vol ou d'identité. + +### Required controls in the selected model + +- identité et permissions vérifiées côté serveur ; +- RLS fondée sur une appartenance serveur, jamais un rôle client ; +- moindre privilège ; +- révocation immédiate des accès ; +- opérations sensibles transactionnelles et auditées ; +- règles explicites de concurrence et transfert de propriété ; +- tests utilisateur A/utilisateur B/ancien membre. + +## Automated validation + +Ticket documentaire : aucun build applicatif requis. + +```powershell +# Vérifier que l'ADR et les documents attendus existent +Test-Path docs/decisions/ADR-0001-modele-produit.md + +# Vérifier qu'aucun fichier applicatif n'a été modifié par ce ticket +git diff --name-only + +# Vérifier les références à la décision produit +rg -n "solo|collaboratif|collaboration|multi-utilisateur|rôle" ` + docs/PRODUCT.md docs/ARCHITECTURE.md docs/ROADMAP.md ` + docs/decisions/ADR-0001-modele-produit.md +``` + +La revue humaine de cohérence reste obligatoire. + +## Manual verification + +1. Lire uniquement la section `Decision` de l'ADR et reformuler le modèle retenu. +2. Vérifier que cette reformulation correspond à l'intention d'Andy. +3. Contrôler un exemple concret : + - qui crée la compagnie ; + - qui peut voir les finances ; + - qui prépare et effectue un vol ; + - qui peut acheter ou vendre un avion. +4. Vérifier que le MVP n'inclut aucun rôle ou parcours marqué comme différé. +5. Vérifier que l'architecture cible peut appliquer les permissions sans faire + confiance au client. + +Temps cible : 10 minutes. + +## Rollback + +Tant qu'aucun code ou schéma ne dépend de l'ADR, la remplacer par une nouvelle ADR +qui la marque `Superseded`. Ne pas réécrire silencieusement une décision acceptée. + +## Completion Report + +À remplir après décision. + +### Summary + +### Decision selected + +### Files changed + +### Commands and results + +### Manual verification result + +### Risks and limitations + +### Follow-ups + +### Documentation updated +