# Coaster World DATA — v1.2.0

Cette version livre le **lot 2 : import des fiches Excel**, après l’accueil simplifié du lot 1. Depuis **Importer Excel**, charger une fiche, examiner son aperçu puis confirmer son intégration. Les réimports retrouvent les fiches existantes, les sources restent consultables et les valeurs existantes différentes sont conservées pour vérification.

Version du 4 octobre 2026, construite sur l’archive complète v1.1.0. Application Laravel 13 / PHP 8.3+, séparée du site principal et de l’application mobile. L’ajout par nom avec recherche web IA et la découverte par pays restent les jalons suivants.

## Installation sous Laragon

1. Activer PHP 8.3 ou plus et MySQL/MariaDB. Extensions : PDO MySQL, mbstring, XML/DOM, ctype, fileinfo, curl, OpenSSL et zip.
2. Extraire l’archive complète dans `C:/laragon/www/coaster-world-data`. Configurer la racine web du domaine sur le sous-dossier `public/`.
3. Créer une base MySQL vide `coaster_world_data`. Copier `.env.example` vers `.env`, puis renseigner `DB_*` et `APP_URL`.
4. Depuis le terminal Laragon, lancer `INSTALL_DATA.bat`. L’archive contient le code et les dépendances, sans secrets ni base personnelle. Le dossier `vendor/` est fourni ; Composer est nécessaire seulement pour réinstaller les dépendances.
5. Ouvrir `http://coaster-world-data.test/setup` depuis le même ordinateur et créer le premier administrateur. Aucun compte administrateur ni mot de passe par défaut n’est fourni.
6. Lancer `START_DATA.bat`. Il démarre le scheduler, un worker Live et un worker de collecte. Vérifier les trois indicateurs dans **Système**.
7. Créer une clé dans **Accès API et utilisateurs** pour le serveur qui consommera l’API.

Commandes équivalentes, après création et configuration de `.env` :

```bash
php artisan config:clear
php artisan cw:data:install --generate-key
php artisan optimize:clear
php artisan schedule:work
```

Dans deux autres terminaux :

```bash
php artisan queue:work --queue=live --sleep=1 --tries=3 --timeout=60
php artisan queue:work --queue=default --sleep=2 --tries=2 --timeout=360
```

`STOP_DATA.bat` arrête les processus lancés par le script. `STATUS_DATA.bat` affiche leur état. En production, superviser les deux workers et exécuter `php artisan schedule:run` chaque minute. Aucun build npm n’est nécessaire pour l’administration : ses fichiers CSS et JavaScript sont servis directement.

## Mise à jour depuis v1.1.0

Conserver son `.env`, son `APP_KEY`, sa base et son dossier `storage/`. Arrêter les workers avec `STOP_DATA.bat`, puis superposer les fichiers de l’archive `_update.zip`. Actualiser la ligne `CW_DATA_VERSION=1.2.0` dans `.env` et conserver les paramètres MySQL et API actuels.

Pour ce lot sans modification de schéma, suivre `INSTALL_UPDATE_v1.2.0.md` : arrêter les tâches, copier le ZIP de mise à jour, actualiser la version dans `.env`, lancer `php artisan optimize:clear`, puis redémarrer avec `START_DATA.bat`. Le guide décrit aussi le premier import et les exceptions.

Depuis v0.20.2, appliquer d’abord le socle et les correctifs v1.0.0 selon `INSTALL_UPDATE_v1.0.0.md`, puis le lot 1 selon `INSTALL_UPDATE_v1.1.0.md`. Le ZIP de mise à jour v1.2.0 est destiné à v1.1.0.

L’archive complète convient à une installation dans un nouveau dossier. Pour une installation existante, employer la mise à jour. Ne pas employer `migrate:fresh` ou régénérer une clé existante.

## Import Excel

- Ouvrir **Accueil → Importer Excel**, ou utiliser le lien d’une fiche parc.
- Charger un fichier `.xlsx` conforme aux modèles Coaster World DATA : fiche parc avec tableaux, ou fiche détaillée Champ / Valeur. Limites : 8 Mo et 250 fiches par lot.
- Sélectionner un parc existant si nécessaire. Sinon le parc déclaré est associé ou créé ; une fiche isolée peut préparer un parc parent minimal.
- Examiner les fiches, les sources et les exceptions, puis cocher la confirmation et lancer **Importer le lot**. L’aperçu prépare uniquement l’ingestion.
- Un fichier identique pour le même choix de parc rouvre son lot. Un fichier modifié prépare un nouveau lot et retrouve les fiches par identifiants connus ou noms exacts ; les rapprochements ambigus restent à résoudre.
- Les colonnes supplémentaires utilisent des champs `excel.*`. Les formules ne sont pas calculées ; fournir des valeurs fixes. Les tableaux Calendrier, Historique, Fréquentation, Services & tarifs, Identifiants externes et Sources sont conservés pour vérification. Le calendrier importé ne modifie pas les horaires Live.

Les identifiants vérifiés sont ajoutés aux fournisseurs existants actifs quand ils ne sont pas déjà associés ailleurs. Les fournisseurs absents ou désactivés et les incohérences sont signalés. Les URL de source sont conservées sans recherche web pendant l’import. Les corrections humaines et toutes les valeurs finales existantes différentes restent protégées.

## Parcours de collecte

- **Collecte et exploitation** : rechercher un parc, une attraction, un coaster ou un POI par nom. Une attraction, un coaster ou un POI doit avoir un parc de rattachement.
- Examiner les candidats dans **Ingestion**, puis associer une fiche existante ou créer une fiche explicitement.
- Dans une fiche, ouvrir **Sources et données** : contrôler les identifiants, lancer l’enrichissement, consulter les observations et l’historique, ajouter des organisations ou des médias avec leurs droits.
- Valider les propositions dans **À vérifier**. Les collectes statiques et l’IA ne modifient pas silencieusement les valeurs canoniques.
- Programmer les collectes statiques avec un intervalle d’au moins 24 heures. Les propositions restent soumises à la revue.

Les collectes et analyses longues utilisent la file `default`. Leur page affiche l’état et se rafraîchit automatiquement. Un échec peut être relancé. Les fiches de coaster peuvent recevoir des informations Wikidata à partir d’un identifiant vérifié ; les quantités sans unité reconnue sont ignorées.

## Fournisseurs et Live

L’installation enregistre les fournisseurs manquants : ThemeParks.wiki, Queue-Times, Wikidata, Wikipedia et OpenStreetMap/Overpass. Les fournisseurs, capacités, sources, périmètres et priorités restent configurables.

ThemeParks.wiki et Queue-Times disposent de connecteurs Live effectifs. Chaque parc est traité dans un job indépendant. Les correspondances reposent sur les identifiants externes du fournisseur ; une ressemblance de nom ne suffit pas. Les données inconnues ne créent pas automatiquement de nouvelles attractions.

Une source HTTP JSON personnalisée peut déclarer `live_endpoint_template` et `live_mapping` dans ses métadonnées. Exemple :

```json
{
  "live_endpoint_template": "https://api.example.com/parks/{park_id}/live",
  "live_mapping": {
    "items": "rides", "id": "id", "status": "status", "wait": "wait_minutes",
    "timestamp": "updated_at", "status_map": {"OPEN": "open", "CLOSED": "closed"}
  }
}
```

Le fournisseur doit être actif, sa capacité `wait_times` activée et les fiches reliées à ses identifiants `default`. Les désactivations par parc ou par source sont respectées. Les appels HTTP ont des délais limités, les redirections automatiques sont désactivées et les adresses privées sont bloquées par défaut.

L’API lit les tables locales et n’appelle aucun fournisseur. Une attente expirée devient `null`, avec `freshness=expired` et un état courant inconnu. Une fermeture connue du parc masque l’attente ; un horaire manquant reste inconnu. ThemeParks.wiki utilise une date de dernier changement : le moteur conserve cette date et évalue sa fraîcheur à partir de la dernière collecte réussie. Les horaires gardent le fuseau local et couvrent les ouvertures qui passent minuit.

Les réponses Live indiquent l’attribution. Afficher **Powered by Queue-Times.com** avec un lien vers Queue-Times lorsque ses données sont utilisées, ainsi que l’attribution ThemeParks.wiki applicable. Vérifier les conditions des sources avant une diffusion externe de leurs données.

## API

Base : `/api/v1`. Avec `.env.example`, les données nécessitent `Authorization: Bearer <clé>` ou `X-API-Key`. La clé est stockée sous forme de hash, peut être révoquée et doit rester côté serveur. `/api/v1/health` reste accessible pour la supervision. L’API retourne des réponses JSON, avec pagination, limites de débit et en-têtes de cache.

```bash
curl -H "Authorization: Bearer VOTRE_CLE" "http://coaster-world-data.test/api/v1/parks?locale=fr"
```

Principales routes :

| Route GET | Contenu |
| --- | --- |
| `/parks`, `/parks/{id}` | Catalogue et fiche parc |
| `/parks/{id}/attractions`, `/parks/{id}/coasters`, `/parks/{id}/pois` | Contenu d’un parc |
| `/attractions/{id}`, `/coasters/{id}`, `/pois/{id}` | Fiches et données canoniques |
| `/search?q=...` | Recherche transversale |
| `/parks/{id}/live`, `/attractions/{id}/live` | État Live local |
| `/attractions/{id}/live/history` | Mesures historiques paginées |
| `/parks/{id}/schedule` | Horaires, fuseau et état du parc |
| `/entities/{type}/{id}/media` | Médias dont les droits et la diffusion sont confirmés |
| `/entities/{type}/{id}/organizations` | Constructeurs, propriétaires, exploitants et périodes |

Les fiches exposent la confiance, la vérification, les dates et la source des valeurs canoniques. Langues : `fr`, `en`, `de`, `es`, `it`, via `locale` ou `Accept-Language`. Le fichier `docs/openapi.json` décrit les routes GET disponibles.

## IA facultative

Renseigner `OPENAI_API_KEY` et un modèle compatible avec Responses et la recherche web dans `CW_DATA_AI_MODEL`, puis activer `CW_DATA_AI_ENABLED=true`. L’IA est désactivée par défaut. Depuis la v1.3, **Ajouter un parc** ouvre une recherche par nom avec pays facultatif, collecte de 50 éléments maximum et recherches détaillées par groupes de 0 à 25 fiches. Le worker `default` est nécessaire. La recherche web est obligatoire ; seules les URL retournées par cet outil sont retenues. Une identité exacte et fortement étayée permet la création ou l’association du parc. Les valeurs valides, suffisamment confiantes et reliées au domaine officiel peuvent compléter les champs vides, avec historique et sans vérification humaine revendiquée. Les valeurs existantes et traductions sont conservées. Les incertitudes restent dans les lots et la revue ; **Reprendre ce lot** conserve la recherche initiale et lance le prochain groupe de détails. Le fournisseur `ai-research`, ses capacités, son périmètre et ses sources restent contrôlables.

L’ancienne action IA d’une fiche reste une collecte d’observations plafonnée à 70 avec validation humaine. Aucun appel payant réel n’a été effectué pour la validation de cette livraison ; le nouveau client est testé avec des réponses HTTP simulées. Voir `INSTALL_UPDATE_v1.3.0.md` pour les commandes Laragon.

## Sauvegarde et contrôle de restauration

Une sauvegarde quotidienne est programmée à 03:00 UTC, avec rétention de 20 archives. La base est sauvegardée par `mysqldump` ou `mariadb-dump` ; son exécutable est détecté dans une installation Laragon standard. Les chemins peuvent être précisés dans `CW_DATA_MYSQLDUMP_BINARY` et `CW_DATA_MYSQL_BINARY`.

```bash
php artisan cw:data:backup
php artisan cw:data:backup --verify=cwdata-YYYYMMDD-HHMMSS-xxxxxx.zip
php artisan cw:data:restore-check cwdata-YYYYMMDD-HHMMSS-xxxxxx.zip --database=coaster_world_data_restore_test
```

La restauration de contrôle exige un **nouveau nom de base** et n’écrit pas dans la base courante. Elle contrôle les empreintes et les nombres de lignes des tables métier. Le compte utilisé doit pouvoir créer la base de contrôle. Les tables de jobs, cache et sessions sont exclues de cette comparaison car elles évoluent continuellement.

Les sauvegardes contiennent la base, un manifeste et, lorsque `.env` existe, sa copie chiffrée. Conserver `APP_KEY` séparément pour relire cette copie. `storage/app/private/data-backups` doit être copié régulièrement vers un autre disque ou une destination de sauvegarde. Les médias externes sont sauvegardés comme références, pas comme fichiers téléchargés.

## Vérifications et références

```bash
php artisan test
php artisan route:list --path=api
php artisan cw:system:status
```

Voir `docs/VALIDATION_v1.1.0.md`, `CHANGELOG_v1.1.0.md` et `INSTALL_UPDATE_v1.1.0.md`. Les notes des versions antérieures sont conservées dans `docs/README_REFERENCE_v0.20.2.md` et dans les documents historiques.

Les paramètres réels de la base Laragon et les éventuelles clés de services restent à renseigner sur l’ordinateur cible. Les tests des fournisseurs utilisent des réponses contrôlées ; leurs disponibilités et leurs conditions peuvent évoluer. La base encyclopédique réelle se remplit ensuite avec les importations et validations de l’administration.
