# Plan de développement - Application de partitions OHMJ ## Structure finale du projet ``` /home/jbnadal/sources/jb/ohmj/ohmj2/ ├── legacy/ # Backup ancien code │ ├── api/ # Ancien PHP legacy (MySQL) │ ├── frontend/ # Ancien Vue.js 2 │ ├── fpdf/ │ ├── Imgs/ │ ├── Scripts/ │ ├── Textes/ │ └── index.php ├── api/ # NOUVEAU backend PHP moderne │ ├── index.php # Router / entry point API │ ├── config/ │ │ └── users.json # Users avec passwords hashés │ └── lib/ │ ├── Auth.php # JWT authentication │ └── ScoreScanner.php # Lecture fichiers ini + scan partitions ├── partitions/ # NOUVEAU frontend SvelteKit │ ├── src/ │ │ ├── routes/ │ │ │ ├── +page.svelte # Login page │ │ │ ├── scores/+page.svelte # Liste des morceaux │ │ │ ├── scores/[id]/+page.svelte # Détail partition │ │ │ └── +layout.svelte # Layout avec auth guard │ │ ├── lib/ │ │ │ ├── api.ts # Client API │ │ │ └── stores/auth.ts # Store JWT │ │ └── app.html │ ├── package.json │ └── svelte.config.js └── Scores/ # Répertoire partitions (hors git) └── {id}/ ├── score.ini ├── cla/ │ └── 1/ │ └── *.pdf └── ... ``` ## Phase 1 : Backend PHP (api/) ### 1.1 ScoreScanner.php ✓ (FAIT) - [x] Classe pour scanner les partitions - [x] Lecture des fichiers score.ini - [x] Scan récursif instruments → parties → fichiers PDF - [x] Mapping codes instruments vers noms ### 1.2 Auth.php - [ ] Classe JWT pour authentification - [ ] Génération token JWT - [ ] Vérification token JWT - [ ] Lecture users.json - [ ] Vérification password hashé (bcrypt) ### 1.3 users.json - [ ] Fichier JSON avec structure users - [ ] Passwords hashés avec bcrypt - [ ] Script pour ajouter/modifier users ### 1.4 index.php (Router API) - [ ] CORS headers - [ ] Routing : POST /login - [ ] Routing : GET /scores (protégé JWT) - [ ] Routing : GET /scores/:id (protégé JWT) - [ ] Routing : GET /download/:path (protégé JWT, stream PDF) - [ ] Gestion erreurs JSON ## Phase 2 : Frontend SvelteKit (partitions/) ### 2.1 Initialisation projet - [ ] npm create svelte@latest partitions - [ ] TypeScript + ESLint + Prettier - [ ] npm install (axios, etc.) ### 2.2 Configuration - [ ] svelte.config.js (adapter static) - [ ] API base URL config ### 2.3 Stores - [ ] lib/stores/auth.ts - [ ] Store JWT token - [ ] Store user info - [ ] Persistance localStorage ### 2.4 Client API - [ ] lib/api.ts - [ ] Instance axios avec baseURL - [ ] Intercepteur pour ajouter header Authorization - [ ] Méthodes : login(), getScores(), getScore(id), downloadFile(path) ### 2.5 Routes #### Login (/) - [ ] Formulaire : username, password - [ ] Appel API login - [ ] Stockage JWT - [ ] Redirection vers /scores - [ ] Gestion erreurs #### Liste des morceaux (/scores) - [ ] Auth guard (redirect si pas connecté) - [ ] Table/DataGrid avec : - [ ] Numéro (ID) - [ ] Nom du morceau - [ ] Compositeur - [ ] Tri possible - [ ] Click → navigation /scores/:id - [ ] Loading state #### Détail partition (/scores/[id]) - [ ] Auth guard - [ ] Header : - [ ] Numéro - [ ] Nom du morceau - [ ] Compositeur - [ ] Bouton retour - [ ] Liste des instruments (grid ou accordion) : - [ ] Nom de l'instrument - [ ] Pour chaque partie : - [ ] Numéro de partie - [ ] Liste des fichiers PDF - [ ] Bouton téléchargement par fichier - [ ] Loading state #### Layout - [ ] Auth guard global - [ ] Header avec : - [ ] Titre app - [ ] User connecté - [ ] Bouton logout - [ ] Footer (optionnel) ### 2.6 Styles - [ ] CSS moderne (Tailwind ou CSS vanilla) - [ ] Responsive (mobile-friendly) - [ ] Thème harmonie (couleurs) ## Phase 3 : Déploiement ### 3.1 Build frontend - [ ] npm run build - [ ] Output dans dist/ ### 3.2 Configuration serveur - [ ] /partitions → contenu dist/ - [ ] /api → PHP - [ ] /legacy/Scores → accès aux PDFs - [ ] .htaccess ou config nginx pour routing ### 3.3 Sécurité - [ ] HTTPS obligatoire - [ ] JWT secret fort - [ ] Protection download (vérif JWT) - [ ] Headers sécurité ## Notes techniques ### Backend PHP - Pas de base de données - JWT pour auth stateless - Lecture fichiers uniquement - Stream PDF pour download ### Frontend SvelteKit - Svelte 5 (runes) - TypeScript strict - Pas de store complexe (juste auth) - Client API simple ### Contraintes - Chemin partitions : ../legacy/Scores/ (sera déplacé après DL) - Fichiers ini présents partout - PDFs uniquement - Auth obligatoire pour tout accès ## Phase Préliminaire : Normalisation des données ### 0.1 Structure des partitions (à valider) - [ ] Analyser tous les instruments pour voir si le répertoire "1" est nécessaire - [ ] Identifier les cas où il n'y a qu'une seule partie (supprimer le niveau "1" ?) - [ ] Valider la structure finale avant codage ### 0.2 Harmonisation des noms de fichiers ✓ **Convention finale :** - Format : `{instrument}[_{instrument2}][_{variante}][_{tonalité}]_{partie}[_clef].pdf` - Exemples : - `clarinette_sib_1.pdf` (clarinette en Si♭, partie 1) - `clarinette_alto_mib_1.pdf` (clarinette alto en Mi♭, partie 1) - `basse_et_contrebasse_sib_1.pdf` (partition pour 2 instruments) - `cor_mib_1_et_2.pdf` (cor en Mi♭, parties 1 et 2 combinées) - `euphonium_sib_2_clefa.pdf` (euphonium en Si♭, partie 2, clé de fa) - Tout en minuscule, français, ASCII sans accents - Tonalités : sib (Bb), mib (Eb), fa (F), do (C), etc. - **Garder les sous-répertoires numérotés (1/, 2/, etc.)** pour distinguer les versions - **Script :** `scripts/convert_final_v2.js` - **Usage :** `node scripts/convert_final_v2.js /chemin/vers/Scores confirm` ### 0.3 À propos des répertoires numérotés (1/, 2/, etc.) **Découverte importante :** - Le répertoire `1/` = version principale du morceau - Le répertoire `2/` (ou plus) = alternative du même morceau - Cela permet d'avoir plusieurs versions d'un même morceau dans le même ID - Exemple : Score 210, dossier `cla/1/` et `cla/2/` contiennent des versions différentes - **Action:** Le script de conversion doit utiliser le numéro du répertoire comme numéro de partie UNIQUEMENT pour les fichiers "version_X" ### 0.4 À propos du répertoire "sup" - Le répertoire `sup/` signifie "supérieur" ou "combiné" - C'est une partition où deux instruments jouent sur la même partition - Ex: baryton + tuba sur une même partition - **Note API:** Ces partitions combinées doivent être gérées différemment dans l'interface (afficher les deux instruments) ### 0.5 Conventions de nommage - Instruments **Orthographe standardisée (français) :** - Clarinette → clarinette - Saxophone → saxophone (ou sax_baryton, sax_tenor, sax_alto, sax_soprano pour les variantes) - Cor → cor - Trompette → trompette - Trombone → trombone - Tuba → tuba (ou tuba_tenor pour tenor tuba) - Basse → basse - Contrebasse → contrebasse (UN SEUL MOT) - Baryton → baryton - Euphonium → euphonium - Flute → flute (ou petite_flute, grande_flute) - Hautbois → hautbois - Basson → basson - Contre-basson → contre_basson - Bugle → bugle (inclut flugelhorn) - Percussion → percussion (timbales, grosse_caisse, cymbale, caisse_claire, triangle, etc.) **Instrumentsperaussion reconnus :** - timpani, glockenspiel, bongos, maracas, tambourine, vibraphone, xylophone - woodblock, claves, batterie **Tonalités :** - sib (Bb), mib (Eb), fa (F), do (ut), sol, re, mi, si, reb - NOTE: "do" devient "ut" dans les noms de fichiers **Cas spéciaux gérés :** - "default_cor" = instrument de substitution (ex: baryton_default_cor_2) - Parties combinées avec & = format "instrument1_et_instrument2_info1_info2_partie" ### 0.6 Structure du nom de fichier final **Format :** `{instrument}[_{variante}][_{tonalité}][_{default}][_{instrument_subst}]_{partie}[_clef].pdf` **Exemples :** - `clarinette_sib_1.pdf` - `sax_baryton_mib_1.pdf` - `cor_fa_1_et_2.pdf` - `baryton_sib_default_cor_2.pdf` - `sax_tenor_sib_1.pdf` - `baryton_mib_2_clesol.pdf` - `baryton_et_tuba_tenor_sib_clefa.pdf` (parties combinées sup) **Note:** Pour les parties combinées (sup), chaque instrument garde ses propres infos (tonalité, partie, clef) ## Phase 3 : Déploiement ### 3.1 Build frontend - [ ] npm run build - [ ] Output dans dist/ ### 3.2 Configuration serveur - [ ] /partitions → contenu dist/ - [ ] /api → PHP - [ ] /legacy/Scores → accès aux PDFs - [ ] .htaccess ou config nginx pour routing ### 3.3 Sécurité - [ ] HTTPS obligatoire - [ ] JWT secret fort - [ ] Protection download (vérif JWT) - [ ] Headers sécurité ## Phase 4 : Admin (post-déploiement) ### 4.1 Page d'administration - [ ] Route `/admin` protégée (super-user) - [ ] Interface CRUD pour les partitions - [ ] Formulaire : ID, nom du morceau, compositeur - [ ] Création automatique du répertoire et du score.ini - [ ] Upload drag & drop des fichiers PDF - [ ] Organisation automatique des fichiers dans la bonne structure - [ ] Validation du format (convention de nommage) ## Prochaines étapes 1. ✓ Backup legacy (FAIT) 2. ✓ Renommage IDs avec zéros (FAIT) 3. ✓ Correction noms fichiers (& et espaces) (FAIT) 4. → Définir structure finale des partitions 5. → Harmoniser tous les noms de fichiers 6. → Créer Auth.php 7. → Créer users.json 8. → Créer index.php (router) 9. → Tester backend 10. → Créer frontend SvelteKit 11. → Développer routes 12. → Tester intégration 13. → Déployer 14. → Développer page admin --- ## Conversion des noms de fichiers (2026-02-17) ### Structure finale `NUM/PIECE/INSTRUMENT/VERSION/PARTIE.pdf` - **NUM**: numéro du score (ex: 102, 390) - **PIECE**: numéro de pièce (1 = premier morceau) - **INSTRUMENT**: trigramme de l'instrument (ex: cla, sax, trp) - **VERSION**: numéro de version (1 = première version) - **PARTIE**: numéro de partie (ex: 1, 2, 3...) ### Exemples #### Score normal (1 seul morceau) - `102/1/cla/1/1/clarinette-sib-1.pdf` #### Score 390 (5 morceaux différents) - `390/1/sax/1/1/sax_alto-1.pdf` (pièce 1) - `390/2/sax/1/1/sax_alto-1.pdf` (pièce 2) ### Format score.ini ```ini [info] name = La part d'Euterpe compositor = Michaël CUVILLON [pieces] count = 1 ``` Pour 390: ```ini [info] name = La part d'Euterpe compositor = Michaël CUVILLON [pieces] count = 5 1 = La Part d Euterpe 2 = Calliope s Songs 3 = Interlude 4 = Oxola 5 = Steps to Paranassus ``` ### Étapes realizadas 1. ✅ score.ini: ajouté section [info] et [pieces] pour tous les scores 2. ✅ Répertoires 2 chiffres renommés (72→072, 73→073, 98→098) 3. ✅ Structure NUM/1/INSTRUMENT/VERSION appliquée pour tous les scores (sauf 390) 4. ✅ Structure NUM/PIECE/INSTRUMENT/VERSION appliquée pour 390 (PIECE=1-5) 5. ✅ Script convert_final_v2.js mis à jour pour supporter la nouvelle structure 6. ✅ Conversion appliquée: 6388 fichiers convertis, 0 erreurs ### Validation - ✅ Multi instruments: utilise `+` (ex: `basse-sib-1+contrebasse-sib-1.pdf`) - ✅ Parties combinées: utilise `_` (ex: `cor-mib-1_2.pdf`) - ✅ Variantes: `solo` (ex: `clarinette-sib-solo-1.pdf`) - ✅ Clefs: `clesol`, `clefa` (ex: `basse-sib-clesol-1.pdf`) - ✅ Mots composés: `sax_alto`, `clarinette_basse` - ✅ Pas de `-et-` (0 occurrences) - ✅ Pas de `--` (0 occurrences)