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