# TRAIL DPS Workspace SAS — extension 1.0.8-lot1 pour L2.5

## Objet

PLACE L2.5 peut rejouer une écriture après une coupure uniquement lorsque le serveur applique réellement la même clé d’idempotence. La route :

```text
POST /api/v1/migration/course-inventory
```

est donc intégrée au garde-fou `IdempotencyService` existant.

## Corrections

- `Idempotency-Key` UUID obligatoire pour l’inventaire ;
- même clé et même corps : réponse mémorisée, sans seconde écriture ;
- même clé et corps différent : HTTP 409 `IDEMPOTENCY_CONFLICT` ;
- opération encore en cours : HTTP 409 `IDEMPOTENCY_IN_PROGRESS` ;
- en cas de déduplication naturelle par hash, relecture puis retour de l’`inventory_uuid` réellement conservé ;
- mise à jour de `received_at`, `course_count` et `payload_json` lors du rejeu naturel ;
- aucune migration MySQL.

## Compatibilité

Le schéma `course_migration_inventories` contient déjà :

```text
UNIQUE(subscription_uuid, client_instance_uuid, payload_sha256)
```

La version 1.0.8-lot1 exploite cette contrainte sans la modifier. Les routes d’authentification, événements, snapshots, photos et utilisateurs restent inchangées.

## Déploiement

1. extraire le ZIP dans le dossier parent de `traildpsworkspace-staging` ;
2. conserver `config/config.php`, `storage/private`, `storage/backups` et `storage/logs` ;
3. exécuter le lint PHP ;
4. exécuter `php tests/run.php` ;
5. vérifier que `/api/v1/health` annonce `1.0.8-lot1` ;
6. déployer ensuite PLACE L2.5.

## Critères

```text
VERSION = 1.0.8-lot1
TESTS = 13/13
MIGRATION MYSQL = aucune
INVENTAIRE IDEMPOTENT = oui
UUID RETOURNÉ = UUID réellement stocké
```
