# Déploiement de recette - LOT 1 Workspace SAS

## 1. Pré-requis

- PHP 8.1 minimum avec PDO MySQL, OpenSSL, Fileinfo et Zlib.
- MySQL 5.7+ ou MariaDB 10.4+.
- HTTPS obligatoire.
- Sous-domaine de recette distinct de la production.
- Base et utilisateur SQL dédiés, sans accès aux bases Licence ou Tracking.
- Accès SSH ou possibilité d'exécuter des tâches PHP CLI depuis l'espace OVH.

## 2. Sauvegardes préalables

Avant le déploiement, conserver hors du répertoire web :

- un dump récent de `synolui94` ;
- un dump récent de `synoluidpstrack` ;
- une copie du code OVH actuellement déployé ;
- une copie représentative de la base SQLite PLACE.

Le LOT 1 n'écrit dans aucune de ces sources, mais ces sauvegardes constituent le point de référence du projet global.

## 3. Création de la base de recette

Depuis le manager OVH :

1. créer une base, par exemple `synoluisharing_staging` ;
2. créer un utilisateur SQL dédié ;
3. attribuer uniquement les droits nécessaires sur cette base ;
4. ne pas réutiliser l'utilisateur des bases Licence ou Tracking.

La base de production restera `synoluisharing` et ne doit pas être utilisée pour la première recette.

## 4. Installation des fichiers

Décompresser le dossier `traildpsworkspace` sous une racine distincte, par exemple :

`/home/synolui/programme/traildpsworkspace-staging`

Le document root du sous-domaine doit viser exclusivement :

`/home/synolui/programme/traildpsworkspace-staging/public`

Les dossiers `config`, `SRC`, `sql`, `scripts`, `storage`, `tests` et `docs` ne doivent pas être exposés directement par le serveur web.

## 5. Configuration

Copier :

`config/config.example.php` vers `config/config.php`

Puis renseigner au minimum :

- URL HTTPS du sous-domaine de recette ;
- hôte, port, nom, utilisateur et mot de passe de la base ;
- `token_signing_key` de 32 octets minimum ;
- `cache_signing_key` ;
- `internal_hmac_key` ;
- origines autorisées ;
- chemins de stockage si l'arborescence diffère.

Génération recommandée d'une clé :

```bash
php -r "echo bin2hex(random_bytes(32)), PHP_EOL;"
```

Ne jamais copier une clé de recette en production.

## 6. Droits des répertoires

Le compte PHP doit pouvoir écrire dans :

- `storage/private/TRAILDPS-partage` ;
- `storage/quarantine` ;
- `storage/logs` ;
- `storage/backups`.

Les fichiers privés ne doivent jamais être servis directement par Apache. Les téléchargements passent par l'API authentifiée.

## 7. Migration SQL

Depuis la racine du projet :

```bash
php scripts/migrate.php
php scripts/verify_installation.php
```

La migration est versionnée et contrôlée par checksum. Ne pas modifier un fichier SQL déjà appliqué ; créer une nouvelle migration pour toute correction ultérieure.

## 8. Création du premier ADMIN_ORGA de recette

Exemple :

```bash
export WORKSPACE_ADMIN_PASSWORD='MotDePasseTemporaire!2026'
php scripts/create_workspace_admin.php \
  --email='admin-recette@example.fr' \
  --name='Administrateur recette' \
  --organization-name='Organisation recette TRAIL DPS' \
  --edition='PRO'
unset WORKSPACE_ADMIN_PASSWORD
```

Conserver les UUID affichés. Le mot de passe doit être changé après la première validation.

Le bootstrap local crée une projection temporaire d'organisation et de souscription pour la recette du LOT 1. Le LOT 3 remplacera cette alimentation manuelle par le serveur Licence.

## 9. Tâches planifiées

Fréquences recommandées :

```text
*/5 * * * * php scripts/cleanup_locks.php
0 * * * * php scripts/cleanup_tokens.php
10 * * * * php scripts/usage_recompute.php
20 2 * * * php scripts/photo_purge.php
40 2 * * 0 php scripts/photo_integrity.php 10000
15 3 * * * php scripts/backup.php
```

Sur une offre limitant la fréquence des tâches, `cleanup_locks.php` peut être exécuté chaque heure : les verrous expirés sont déjà ignorés par l'API.

## 10. Vérifications HTTP

La route suivante doit répondre en HTTPS :

`GET /api/v1/health`

Réponse attendue : `ok=true`, service `traildps-workspace`, version identique au fichier `VERSION`.

Poursuivre ensuite avec les scénarios de `TESTS_RECETTE_LOT_1.md`.

## 11. Conditions avant LOT 2

Ne pas intégrer l'authentification workspace dans PLACE tant que les preuves suivantes ne sont pas réunies :

- migration réussie sur une base vide puis rejouée sans erreur ;
- isolation entre deux organisations ;
- conflit de révision HTTP 409 ;
- upload, remplacement, corbeille et restauration d'une photo ;
- contrôle d'intégrité des fichiers ;
- sauvegarde coordonnée et restauration sur recette ;
- absence de donnée LIVE dans les snapshots ;
- validation du journal d'audit et de l'idempotence.

## Maintenance 1.0.6-lot1 — prérequis avant LOT 2 PLACE

Après extraction du ZIP incrémentiel :

1. conserver le `config/config.php` déjà présent sur le serveur ;
2. vérifier manuellement que `storage.min_free_ratio` vaut au minimum `0.20` et que `storage.min_free_bytes` est positif ; sur un hébergement mutualisé, ne pas activer `use_filesystem_total_for_ratio` et ne définir `capacity_reference_bytes` que si la capacité réellement allouée au compte est connue ;
3. ne pas remplacer la configuration réelle par `config/config.example.php` ;
4. exécuter `php tests/run.php` et attendre `11/11 tests réussis` ;
5. exécuter `php scripts/verify_installation.php` ;
6. exécuter `php scripts/scan_orphan_files.php --json` ;
7. si des orphelins sont confirmés, les déplacer avec `php scripts/scan_orphan_files.php --quarantine --json` avant toute suppression définitive.

Le script de scan retourne le code `2` lorsqu'une anomalie est détectée, même si le rapport JSON a été correctement produit. Ce code permet la supervision par tâche planifiée.


## Mise à niveau 1.0.12-lot1 — LOTS L2.7.5 et L2.7.6

Après extraction de l’archive incrémentielle :

```bash
cd /home/synolui/programme/traildpsworkspace-staging
php scripts/migrate.php
php tests/run.php
php scripts/verify_installation.php
```

La migration `002_conflict_resolution_attribution.sql` ajoute uniquement le champ facultatif `workspace_users.business_phone`. Elle ne modifie ni les snapshots, ni les révisions existantes, ni les données Licence/Tracking. Le résultat des tests attendu pour cette version est indiqué dans le procès-verbal du ZIP incrémentiel.

## Mise à niveau 1.0.13-lot1 — LOT L2.8 Photos POI

Après extraction de l'archive incrémentielle :

```bash
cd /home/synolui/programme/traildpsworkspace-staging
cat VERSION
php scripts/migrate.php
php tests/run.php
php scripts/verify_installation.php
```

Aucune migration MySQL n'est ajoutée par L2.8. Le stockage privé existant, `shared_files` et `poi_photo_versions` sont conservés. Le résultat attendu est `1.0.13-lot1`, aucune migration à appliquer et `25/25 tests réussis`.

Ne jamais remplacer `config/config.php`, `storage/private`, `storage/quarantine`, les journaux ou les sauvegardes lors de l'extraction du ZIP incrémentiel.



## Hotfix 1.0.14-lot1 — capacité de stockage sur hébergement mutualisé

Le contrôle de réserve ne déduit plus implicitement 20 % de `disk_total_space()`. Sur un hébergement mutualisé, cette valeur correspond souvent au volume physique global de l’hôte et non au quota du compte. Sans paramètre supplémentaire, seule la réserve absolue `storage.min_free_bytes` est appliquée.

Paramètres facultatifs :

```php
'capacity_reference_bytes' => 100 * 1024 * 1024 * 1024,
'use_filesystem_total_for_ratio' => false,
```

- `capacity_reference_bytes` permet d’appliquer `min_free_ratio` à une capacité allouée connue ;
- `use_filesystem_total_for_ratio` ne doit être activé que sur un volume dédié dont `disk_total_space()` représente réellement la capacité exploitable par TRAIL DPS ;
- aucune modification de `config/config.php` n’est requise pour l’environnement staging mutualisé actuel.
