# TODO.md - Plan de travail en cours > Document de reprise : si la session est interrompue, reprendre ici. > Dernière mise à jour : 2026-09-14. ## Comment lancer / tester ```bash # Tout tester d'un coup (backend + couverture + frontend) : "test le projet" ./test.sh # Serveur API (dev) - obligatoire pour les tests cd api && php -c php-upload.ini -S localhost:8000 router.php & # Front (dev) cd partitions && npm run dev # http://localhost:5173 # Tests backend cd api && rm -f /tmp/rate_* 2>/dev/null && php tests.php # Tests frontend cd partitions && npm run check && npm run test:e2e # Couverture (Xdebug requis) ~96.9% ``` ## État actuel ### Fait (session) - **Docs** : `AGENTS.md` réécrit (stack réelle), `README.md` + `api/README.md` corrigés, `NAMING.md` recréé (convention des noms), dépendances documentées, `PLAN.md` / `SECURITY_AUDIT.md` / `wordpress_list/` supprimés (commit `e79c865`). - **Sécurité C1-C5** : plus de service statique `.env` (`router.php`), containment `deleteScoreFile`, `.env` dé-suivis + secret roté, JWT base64url + `exp` obligatoire + `alg` validé + erreurs génériques, XSS `ressource` bloqué. - **Bugs** : `+`/encodage des chemins (167 PDF), viewer PDF (course canvas + double chargement + fuite blob), en-tête `Authorization` insensible à la casse, 404/403 download. - **Backend** : `ressource` persisté/préservé, watermark multi-pages + échec remonté, validation des segments de chemin, sanitisation INI, rate-limiter `flock`, CORS sans wildcard, token download via header uniquement, `ini_set` retiré, `score.ini` protégé, code mort supprimé (Auth methods). - **Tests** : `tests.php` porte de 53 à **181 tests** (fonctionnels + unitaires directs). Tests isolés (créent/suppriment leurs propres partitions) ; le test watermark utilisait un PDF invalide et écrasait `scores[0]` → corrigé. - **Harness couverture** : `api/coverage-prepend.php` + `api/coverage-report.php` (exclus du deploy), documentés dans `AGENTS.md`. ### Couverture backend : 96.9% - `api/router.php` : **100%** - `api/lib/Auth.php` : **100%** - `api/lib/ScoreScanner.php` : **99.5%** (restent 2 lignes) - `api/index.php` : **92.4%** (restent 22 lignes) Code inutile retiré (justifié en revue) : fallback `getallheaders()` (lit la même source que `$_SERVER['HTTP_AUTHORIZATION']`) et boucle d'auto-id morte (comparait un id non paddé à des dossiers paddés). Lignes non couvertes = **branches défensives d'échec I/O**, non atteignables via l'API sans injection de panne OS : | Fichier | Lignes | Nature | |---|---|---| | `api/index.php` | 56, 59, 60 | rate-limiter : `fopen`/`flock` échoue (fail-open) | | `api/index.php` | 104 | fallback `SCORES_PATH` si variable absente | | `api/index.php` | 222-224 | `GET /scores` renvoie 500 si dossier Scores absent | | `api/index.php` | 388-408 | erreurs d'upload PHP (`UPLOAD_ERR_*`, post_max_size) | | `api/lib/ScoreScanner.php` | 443, 444 | rollback `createScore` si écriture `score.ini` échoue | **Option** pour monter plus haut : serveur de test secondaire (port 8001) avec `SCORES_PATH=/nonexistent` et `upload_max_filesize=1K` pour couvrir 222-224 et 388-395. Le reste (I/O/OS, 56/59/60, 104, 443/444) resterait non couvert. ## À faire (reste) ### Finitions - [ ] Décider du sort de `legacy/Scores/001/` (résidu de test « Test Duplicate », sans PDF) → demander avant suppression. - [ ] `npm audit` : 18 → **8 vulnérabilités** après `npm audit fix`. Le reste (svelte/rollup/picomatch) exige `npm audit fix --force` (breaking) → à décider. - [ ] Committer (uniquement sur demande). ## Fait (frontend, F11-F16) - **F11** code mort supprimé : `auth.getToken()`, `api.downloadFileWithAuth`, tout le code d'upload inutilisé d'`admin/+page.svelte`. - **F12** maps d'instruments factorisées dans `partitions/src/lib/instruments.ts` (+ helpers `getInstrumentName/Icon/DefaultKey`), réutilisées partout. `test-icons` supprimé. `lucide-svelte` retiré (inutilisé). - **F13** migration `$app/stores` → `$app/state`, suppression des abonnements manuels, état réactif dans `scores/[id]` et chargement piloté par `$effect` (navigation client correcte). `` → `{@render children()}`. - **F14** worker PDF pointé sur `.mjs` (fichier suivi), `nginx.conf` MIME `.mjs`, `deploy.sh` simplifié, `favicon.png` ajouté. - **F15** route `test-icons/` supprimée ; `VITE_API_URL` réellement utilisé (fallback dev/prod), `define` bogus retiré de `vite.config.ts`. - **F16** `svelte-check` ajouté (`npm run check`) → **0 erreur / 0 warning** ; a11y corrigée (labels `for`/`id`, ``/spans cliquables → `