Files
ohmj2/PLAN.md
2026-02-18 10:08:48 +01:00

14 KiB

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)

  • Classe pour scanner les partitions
  • Lecture des fichiers score.ini (supporte sections [info], [pieces])
  • Scan récursif instruments → parties → fichiers PDF
  • Mapping codes instruments vers noms
  • Retourne piece pour chaque instrument
  • Parse les noms de fichiers : part, key, clef, variant
  • Retourne ressource si présent dans score.ini
  • Supporte les partitions multi-morceaux (ex: score 390)

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)
  • Tests unitaires Auth.php (PHP non installé)

1.3 users.json

  • Fichier JSON avec structure users
  • Passwords hashés avec bcrypt (password: password)
  • Script pour ajouter/modifier users

1.4 index.php (Router API)

  • CORS headers
  • POST /login
  • GET /scores (protégé JWT)
  • GET /scores/:id (protégé JWT)
  • GET /pieces/:scoreId (protégé JWT)
  • GET /download/:path (protégé JWT, stream PDF)
  • POST /admin/scores (protégé JWT, créer partition)
  • PUT /admin/scores/:id (protégé JWT, modifier partition)
  • DELETE /admin/scores/:id (protégé JWT, supprimer partition)
  • POST /admin/scores/:id/upload (protégé JWT, upload PDF)
  • Gestion erreurs JSON
  • Tests toutes les routes (PHP non installé)

1.5 Tests API

  • Tests unitaires Auth.php (PHP non installé)
  • Tests intégration toutes les routes (PHP non installé)
  • Tests authentification JWT (PHP non installé)

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

[info]
name = La part d'Euterpe
compositor = Michaël CUVILLON

[pieces]
count = 1

Pour 390:

[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)

Phase future : Liens externes

Objectif

Ajouter des liens externes dans les partitions (YouTube, site éditeur, etc.)

Implementation

  1. Modification score.ini (FAIT)

    [info]
    name = Le morceau
    compositor = Compositeur
    ressource = https://youtube.com/watch?v=xxx
    # ou
    ressource = https://www.musicdiffusion.com/...
    
  2. API (FAIT)

    • GET /scores → retourner ressource si présent
    • GET /scores/:id → retourner ressource aussi
  3. Frontend

    • Page liste partitions : afficher icône lien externe si présent
    • Page détail partition : afficher les liens sous le titre

Ordre de priorité

  • Implémenté, en attente frontend

TODO: Icônes instruments

  • Installer lucide-svelte (fait)
  • Personnaliser chaque instrument avec la bonne icône

Code IconeDesired

  • pic flute traversiere
  • flu flute traversiere
  • cla clarinette
  • clb clarinette basse
  • sax OK
  • sat OK
  • sab OK
  • coa cor anglais
  • cba OK
  • cor cor
  • trp OK
  • trb OK
  • tub OK
  • htb hautbois
  • bas basson
  • per OK
  • crn OK
  • eup OK
  • har OK
  • pia OK

TODO: Déploiement

Solution idéale: Docker

Services à conteneriser:

  1. PHP-FPM - API backend
  2. Nginx - Servir static + proxy PHP
  3. Node.js - Frontend SvelteKit (ou build static)

docker-compose.yml:

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./frontend/build:/usr/share/nginx/html
      - ./api:/var/www/html
      - ./legacy/Scores:/var/www/html/Scores
    depends_on:
      - php

  php:
    image: php:8.2-fpm
    volumes:
      - ./api:/var/www/html

  node:
    build: ./partitions
    command: npm run dev

Solution alternative: Serveur classique

Si hébergement mutualisé:

  • Build SvelteKit → dossier build/
  • PHP-FPM pour API
  • Dossiers:
    • / → frontend static
    • /api → PHP
    • /legacy/Scores → fichiers PDF

Tâches pour déploiement

  • Créer Dockerfile
  • Créer docker-compose.yml
  • Tester en local
  • Configurer CI/CD (GitHub Actions)
  • Déployer sur serveur prod