# OHMJ API Documentation

API REST pour la gestion des partitions de l'Harmonie de Montpellier-Jacou.

## Base URL

```
http://localhost:8000
```

## Authentification

L'API utilise JWT (JSON Web Token) pour l'authentification.

### Login

```http
POST /login
Content-Type: application/json
```

**Corps de la requête :**
```json
{
  "username": "admin",
  "password": "password"
}
```

**Réponse :**
```json
{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "username": "admin",
    "role": "admin"
  }
}
```

**Rôles disponibles :**
- `admin` - Accès complet
- `user` - Accès lecture seule

### Utilisation du token

Inclure le token dans l'en-tête `Authorization` :
```http
Authorization: Bearer <token>
```

---

## Endpoints

### GET /scores

Liste toutes les partitions.

```http
GET /scores
```

**Réponse :**
```json
{
  "success": true,
  "scores": [
    {
      "id": "102",
      "name": "A Legend from Yao",
      "compositor": "Yeh Shu-Han"
    },
    {
      "id": "390",
      "name": "La part d Euterpe",
      "compositor": "Michael CUVILLON"
    }
  ]
}
```

---

### GET /scores/:id

Détails d'une partition. Pour les partitions multi-morceaux (ex: 390), retourne tous les instruments de toutes les pièces.

```http
GET /scores/102
GET /scores/390
```

**Réponse (score simple) :**
```json
{
  "success": true,
  "score": {
    "id": "102",
    "name": "A Legend from Yao",
    "compositor": "Yeh Shu-Han",
    "instruments": [
      {
        "id": "cla",
        "title": "Clarinette",
        "piece": "1",
        "parts": [
          {
            "id": "1",
            "files": [
              {
                "name": "clarinette-sib-1",
                "filename": "clarinette-sib-1.pdf",
                "path": "102/1/cla/1/clarinette-sib-1.pdf",
                "part": "1",
                "key": "sib",
                "clef": null,
                "variant": null
              }
            ]
          }
        ]
      }
    ]
  }
}
```

**Réponse (partition multi-morceaux comme 390) :**
```json
{
  "success": true,
  "score": {
    "id": "390",
    "name": "La part d Euterpe",
    "compositor": "Michael CUVILLON",
    "instruments": [
      {
        "id": "cla",
        "title": "Clarinette",
        "piece": "1",
        "parts": [...]
      },
      {
        "id": "sax",
        "title": "Sax Alto",
        "piece": "2",
        "parts": [...]
      }
    ]
  }
}
```

---

### GET /scores/:id/instruments

Liste les instruments d'une partition. Pour les partitions multi-morceaux (ex: 390), peut filtrer par pièce.

```http
GET /scores/102/instruments
GET /scores/390/instruments?piece=1
```

**Paramètre optionnel :**
- `piece` - Numéro de la pièce (pour partitions multi-morceaux)

**Réponse :**
```json
{
  "success": true,
  "instruments": [
    {
      "id": "cla",
      "title": "Clarinette",
      "piece": "1",
      "parts": [
        {
          "id": "1",
          "files": [
            {
              "name": "clarinette-sib-1",
              "filename": "clarinette-sib-1.pdf",
              "path": "102/1/cla/1/clarinette-sib-1.pdf",
              "part": "1",
              "key": "sib",
              "clef": null,
              "variant": null
            }
          ]
        }
      ]
    }
  ]
}
```

**Champs des fichiers :**
- `name` - Nom du fichier sans extension
- `filename` - Nom du fichier avec extension
- `path` - Chemin relatif pour download
- `part` - Numéro de partie (ex: "1", "2_3")
- `key` - Tonalité (ex: "sib", "mib", "fa")
- `clef` - Clé (ex: "clesol", "clefa")
- `variant` - Variante (ex: "solo", "default")

---

### GET /pieces/:scoreId

Liste les pièces d'une partition.

```http
GET /pieces/102
```

**Réponse :**
```json
{
  "success": true,
  "pieces": [
    {
      "id": 1,
      "name": "Pièce 1"
    }
  ]
}
```

---

### GET /download/:path

Télécharge un fichier PDF.

```http
GET /download/102/1/cla/1/clarinette-sib-1.pdf
```

**Réponse :** Fichier PDF (Content-Type: application/pdf)

**Structure des chemins :**
```
NUM/PIECE/INSTRUMENT/VERSION/PARTIE.pdf
```

**Instruments disponibles :**
| Code | Instrument |
|------|------------|
| dir  | Direction |
| pic  | Piccolo |
| flu  | Flûte |
| cla  | Clarinette |
| clb  | Clarinette basse |
| sax  | Saxophone alto |
| sab  | Saxophone baryton |
| sat  | Saxophone ténor |
| cba  | Contrebasse |
| cor  | Cor |
| trp  | Trompette |
| trb  | Trombone |
| tub  | Tuba |
| htb  | Hautbois |
| bas  | Basson |
| per  | Percussion |
| crn  | Cornet |
| eup  | Euphonium |

---

## Routes Admin

### POST /admin/scores

Créer une nouvelle partition.

```http
POST /admin/scores
Authorization: Bearer <token_admin>
Content-Type: application/json
```

**Corps de la requête :**
```json
{
  "id": "200",
  "name": "Nouvelle partition",
  "compositor": "Compositeur"
}
```

---

### PUT /admin/scores/:id

Mettre à jour une partition.

```http
PUT /admin/scores/102
Authorization: Bearer <token_admin>
Content-Type: application/json
```

**Corps de la requête :**
```json
{
  "name": "Nouveau nom",
  "compositor": "Nouveau compositeur"
}
```

---

### DELETE /admin/scores/:id

Supprimer une partition.

```http
DELETE /admin/scores/102
Authorization: Bearer <token_admin>
```

---

### GET /admin/scores/:id/files

Récupérer l'arborescence des fichiers d'une partition.

```http
GET /admin/scores/001/files
Authorization: Bearer <token_admin>
```

**Réponse :**
```json
{
  "success": true,
  "files": [
    {
      "name": "1",
      "path": "1",
      "type": "folder",
      "children": [
        {
          "name": "cla",
          "path": "1/cla",
          "type": "folder",
          "children": [
            {
              "name": "1",
              "path": "1/cla/1",
              "type": "folder",
              "children": [
                {
                  "name": "clarinette_sib_1.pdf",
                  "path": "1/cla/1/clarinette_sib_1.pdf",
                  "type": "file"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

---

### DELETE /admin/scores/:id/files

Supprimer un fichier spécifique.

```http
DELETE /admin/scores/001/files?path=1/cla/1/clarinette_sib_1.pdf
Authorization: Bearer <token_admin>
```

**Paramètres :**
- `path` - Chemin relatif du fichier (requis)

---

### POST /admin/scores/:id/upload

Uploader un fichier PDF pour une partition.

```http
POST /admin/scores/001/upload
Authorization: Bearer <token_admin>
Content-Type: multipart/form-data
```

**Corps de la requête :**
```
file: <fichier_pdf>
piece: 1
instrument: cla
version: 1
key: sib (optionnel)
clef: clesol (optionnel)
variant: solo (optionnel)
part: 1 (optionnel, défaut: 1)
```

---

## Codes d'erreur

| Code | Description |
|------|-------------|
| 200  | Succès |
| 401  | Non authentifié |
| 403  | Accès interdit (rôle insufficient) |
| 404  | Ressource non trouvée |
| 500  | Erreur serveur |

---

## Lancer les tests

```bash
cd api
php tests.php
```

Les tests vérifient :
- **Auth** : Login, mauvais mots de passe, token manquant/invalide
- **Scores** : CRUD, gestion d'erreurs pour ressources inexistantes
- **Create Score with Pieces** : Création avec plusieurs parties, vérification score.ini
- **Files** : Get files tree, suppression de fichiers

---

## Lancer le serveur

```bash
cd api
php -S localhost:8000 router.php
```

---

## Structure des fichiers

```
legacy/Scores/
├── 102/
│   ├── 1/
│   │   ├── cla/
│   │   │   ├── 1/
│   │   │   │   ├── clarinette-sib-1.pdf
│   │   │   │   ├── clarinette-sib-2.pdf
│   │   │   │   └── clarinette-mib-1.pdf
│   │   │   └── 2/
│   │   │       └── clarinette-sib-1.pdf
│   │   ├── flu/
│   │   └── sax/
│   └── 2/
└── score.ini
```
