# TRAIL DPS — LOT 3 — Administration des organisations et licences

## Objet

Cet incrément complète l'administration Licence afin de permettre :

- la modification exhaustive des informations d'une organisation et de sa souscription commerciale ;
- la suppression définitive d'une licence technique ;
- la suppression définitive d'une organisation, de ses souscriptions et de ses licences techniques liées.

Version serveur déclarée : `lot-3.1-admin-organization-license-management`.

## Périmètre fonctionnel

### Modification d'une organisation

Depuis **Administration Licence > Organisations > Modifier / supprimer**, l'administrateur peut modifier :

- raison sociale ;
- nom affiché ;
- adresse électronique de facturation ;
- statut de l'organisation ;
- édition commerciale ;
- statut de la souscription, y compris `PENDING` ;
- dates de début et de fin de période ;
- quotas courses, SMS et stockage ;
- prix du SMS hors forfait ;
- nombre de licences incluses et plafond de licences ;
- nombre d'utilisateurs et d'événements collaboratifs ;
- collaboration, partage photo, historique photo et mode d'observation des quotas.

Les UUID organisation et souscription restent volontairement non modifiables pour préserver les relations avec Workspace, PLACE et les audits.

Les paramètres commerciaux alignés sont répercutés sur les licences techniques actives liées : édition, quotas, droits, échéance et durée commerciale. Les adresses électroniques propres à chaque licence ne sont pas écrasées par l'adresse de facturation de l'organisation.

Après enregistrement, la projection Organisation/Souscription est synchronisée vers Workspace. Une indisponibilité Workspace n'annule pas la modification locale ; l'interface signale alors que la synchronisation reste en attente.

### Suppression définitive d'une licence

Depuis la fiche de la licence, une zone rouge permet la suppression définitive après recopie exacte de la clé.

La suppression retire :

- la ligne `licenses` ;
- les audits et statistiques propres à la licence ;
- les historiques et changements de rattachement liés à la licence ;
- les remises à zéro SMS propres à la licence.

Les lignes de facturation déjà produites sont conservées, mais leur colonne `license_id` est mise à `NULL`. Les autres identifiants historiques, notamment `technical_license_uuid`, restent disponibles dans les lignes qui les contiennent.

### Suppression définitive d'une organisation

La suppression exige la recopie exacte du nom affiché de l'organisation.

Avant la suppression locale, le serveur tente de projeter vers Workspace :

- l'organisation avec le statut `DELETED` ;
- ses souscriptions avec le statut `CANCELLED`.

Les événements, révisions et fichiers Workspace ne sont pas supprimés par cette opération. Ils restent conservés dans Workspace sous une organisation devenue inactive.

Après validation Workspace, la base Licence supprime dans un ordre compatible avec les clés étrangères :

- toutes les licences techniques liées ;
- les changements et historiques de rattachement ;
- les snapshots de consommation ;
- les audits et opérations d'idempotence de souscription ;
- les périodes ;
- les souscriptions ;
- l'organisation.

Une option de forçage local existe si Workspace est temporairement inaccessible. Elle ne doit être utilisée qu'après une sauvegarde complète et en connaissance du risque de laisser une projection Workspace obsolète.

## Sécurité et contrôles

- authentification administrateur existante obligatoire ;
- jeton CSRF obligatoire ;
- confirmation textuelle exacte pour chaque suppression ;
- transactions MySQL pour les suppressions ;
- journal serveur `WARNING` pour les suppressions définitives ;
- absence de modification de schéma SQL ;
- absence de secret et de fichier de configuration dans le ZIP.

## Déploiement

### 1. Sauvegarde obligatoire

Exporter intégralement la base `synolui94` depuis phpMyAdmin avant le déploiement, ou utiliser le script de sauvegarde Licence/Tracking déjà validé sur le serveur avec son chemin réel. Vérifier que le fichier SQL produit est non vide et conserver son empreinte SHA-256.

### 2. Copier l'incrément

Copier le contenu du dossier `ovh/` du ZIP à la racine :

```text
/home/synolui/ovh
```

Respecter l'arborescence. Aucun fichier non présent dans le ZIP ne doit être supprimé.

### 3. Vérification syntaxique

```bash
cd /home/synolui/ovh

php -l SRC/OrganizationRepository.php
php -l SRC/SubscriptionRepository.php
php -l SRC/SubscriptionService.php
php -l SRC/LicenseRepository.php
php -l SRC/LicenseService.php
php -l public/admin/organizations.php
php -l public/admin/organization.php
php -l public/admin/license.php
php -l tests/lot3_contracts.php
```

Chaque commande doit retourner `No syntax errors detected`.

### 4. Tests contractuels

```bash
cd /home/synolui/ovh

php tests/lot3_contracts.php
```

Résultat attendu :

```text
41/41 tests LOT 3 reussis.
```

### 5. Readiness serveur

```bash
cd /home/synolui/ovh

php scripts/lot3_check_readiness.php
```

Résultat attendu :

```json
"ok": true
```

Aucune migration SQL n'est nécessaire pour cet incrément.

## Recette manuelle recommandée

### Modification

1. Ouvrir `Administration Licence > Organisations`.
2. Cliquer sur **Modifier / supprimer**.
3. Modifier un champ non critique, par exemple le nom affiché.
4. Enregistrer.
5. Vérifier le message de synchronisation Workspace.
6. Revenir sur la fiche et vérifier la persistance.
7. Contrôler qu'une licence liée conserve sa clé et son adresse électronique propre.

### Suppression d'une licence de recette

1. Créer une licence de recette sans usage opérationnel.
2. Ouvrir sa fiche.
3. Recopier exactement la clé dans la zone de suppression.
4. Confirmer.
5. Vérifier que la licence n'apparaît plus dans la liste.
6. Vérifier que `lot3_check_readiness.php` reste positif.

### Suppression d'une organisation de recette

1. Créer une organisation de recette avec une souscription et une licence.
2. Vérifier sa projection dans Workspace.
3. Ouvrir sa fiche d'administration.
4. Recopier exactement son nom affiché.
5. Confirmer la suppression sans activer le forçage local.
6. Vérifier sa disparition de l'administration Licence.
7. Vérifier que Workspace la considère inactive.
8. Relancer les tests et le readiness.

## Retour arrière

Le retour arrière applicatif consiste à remettre les versions précédentes des fichiers listés dans `MANIFEST_PATHS.txt`.

Les suppressions de données réalisées depuis l'interface ne sont pas annulées par un retour arrière du code. Leur restauration nécessite le dump MySQL créé avant l'opération.
