# Coaster World DATA

Base centrale de données de l'écosystème Coaster World.

## État du projet

Version de développement : **0.19.0 — Ingestion du contenu des parcs**

Le cahier des charges de référence se trouve dans :

`docs/COASTER_WORLD_DATA_CAHIER_DES_CHARGES_v0.1.md`

Les schémas et phases sont documentés dans :

- `docs/PHASE_1A_SCHEMA.md`
- `docs/PHASE_1B_PROVIDERS_SOURCES.md`
- `docs/PHASE_1C_RELIABILITY_PROVENANCE.md`
- `docs/PHASE_1D_FLEXIBLE_FIELDS_TRANSLATIONS_ALIASES.md`
- `docs/PHASE_2A_ADMIN_MINIMAL.md`
- `docs/PHASE_2B_PROVIDERS_ADMIN.md`
- `docs/PHASE_3A_CONNECTOR_ENGINE.md`
- `docs/PHASE_3B_THEMEPARKS_WIKI_PREVIEW.md`
- `docs/PHASE_4A_PUBLIC_API.md`
- `docs/PHASE_4B_LIVE_ENGINE.md`
- `docs/PHASE_4C_LIVE_SCHEDULER.md`
- `docs/PHASE_4D_SYSTEM_HEALTH.md`
- `docs/PHASE_5A_CONTROLLED_INGESTION.md`
- `docs/PHASE_5B_MULTI_ENTITY_INGESTION.md`
- `docs/PHASE_5C_REVIEW_QUEUE.md`
- `docs/PHASE_5D_THEMEPARKS_WIKI_PILOT_IMPORT.md`
- `docs/PHASE_5E_CORE_PROVIDERS.md`
- `docs/PHASE_5F_MULTI_SOURCE_ENRICHMENT.md`
- `docs/PHASE_5G_PARK_CONTENT_INGESTION.md`
- `docs/API_V1.md`

## Installation locale Laragon

Pré-requis : PHP 8.3+ et Composer.

```bash
composer install
copy .env.example .env
php artisan key:generate
php artisan migrate
```

La configuration d'exemple cible :

- URL : `http://coaster-world-data.test`
- base MySQL : `coaster_world_data`
- utilisateur local Laragon : `root`

Adaptez uniquement le `.env` local si nécessaire. Le fichier `.env` ne doit jamais être versionné ou distribué.

## Phases réalisées

La Phase 1A fournit le socle canonique pour :

- parcs ;
- zones ;
- attractions ;
- coasters ;
- POI ;
- organisations (constructeurs, propriétaires, exploitants, etc.).

La Phase 1B ajoute :

- fournisseurs de données ;
- capacités des fournisseurs ;
- fournisseurs limités à certains parcs ;
- registre des sources ;
- identifiants externes.

La Phase 1C ajoute :

- observations collectées champ par champ ;
- provenance fournisseur/source ;
- score de confiance ;
- détection et résolution des conflits ;
- sélection explicite d’une valeur canonique ;
- historique des changements canoniques.

La Phase 1D ajoute :

- registre de champs extensibles ;
- portée des champs par type d’entité ;
- traductions FR/EN/DE/ES/IT ;
- provenance et conflits séparés par langue ;
- alias et anciens noms ;
- accès aux valeurs extensibles sans modifier les tables principales.

La Phase 2A ajoute :

- premier compte administrateur créé depuis le web ;
- authentification et protection des routes d'administration ;
- tableau de bord et recherche universelle ;
- gestion manuelle des parcs, zones, attractions, coasters et POI ;
- saisie des traductions et alias depuis l'interface ;
- thème clair/sombre et interface responsive.

La Phase 2B ajoute :

- administration web des fournisseurs ;
- portée globale ou limitée à certains parcs ;
- capacités standards et personnalisées ;
- priorités et fréquence cible ;
- registre des sources concrètes d'un fournisseur.

La Phase 3A ajoute :

- registre commun de connecteurs ;
- connecteurs `manual` et `generic_http` ;
- sélection du moteur technique depuis l'administration ;
- test de connectivité sans import ;
- journal des exécutions, statuts, durées et erreurs ;
- protections réseau de base et timeouts configurables.

La Phase 3B ajoute :

- lecture réelle de `/v1/destinations` chez ThemeParks.wiki ;
- aperçu des destinations et parcs sans import ;
- journalisation des aperçus ;
- filtre local des résultats ;
- validation stricte de la source ThemeParks.wiki.

La Phase 4A ajoute :

- API publique versionnée `/api/v1` en lecture seule ;
- santé, recherche, parcs, attractions, coasters et POI ;
- pagination et filtres ;
- localisation FR/EN/DE/ES/IT ;
- exposition des champs canoniques et de leur niveau de qualité ;
- rate limiting et cache HTTP ;
- CORS public en lecture seule pour faciliter la connexion du site et des clients compatibles.

La Phase 4B ajoute :

- moteur central Live pour les états et temps d’attente ;
- historique append-only des observations ;
- dernier état connu par attraction ;
- arbitrage par fraîcheur, priorité fournisseur et source officielle ;
- conservation de la dernière donnée connue en mode dégradé ;
- fraîcheur `fresh`, `stale`, `expired` ou `unavailable` ;
- API Live par attraction, parc et collection globale ;
- tableau de supervision Live dans l’administration.


La Phase 4C ajoute :

- orchestration planifiée des synchronisations Live ;
- commande `cw:live:dispatch` exécutée chaque minute par le scheduler ;
- jobs asynchrones sur une queue `live` dédiée ;
- protection contre les doublons et traitements concurrents ;
- retries avec backoff et journalisation des erreurs ;
- supervision des fournisseurs Live dans l’administration ;
- déclenchement manuel d’une synchronisation depuis le web.

Aucun agent IA n’est encore activé. Les connecteurs `manual` et `generic_http` ne parsant pas encore les données Live, aucun flux externe n’est ingéré automatiquement tant qu’un connecteur Live spécialisé n’est pas branché. L’ajout de nouvelles sources reste volontairement en pause pendant la poursuite du socle global.

## v0.12.0 — Santé système

L'administration possède désormais une page **Système** (`/admin/system`) pour surveiller base, scheduler, worker, queue, connecteurs et Live.

Sous Laragon, les scripts `START_DATA.bat`, `STOP_DATA.bat` et `STATUS_DATA.bat` simplifient le démarrage quotidien des processus nécessaires au fonctionnement H24 local.

## v0.13.0 — Ingestion contrôlée

La base dispose maintenant d’une file d’**ingestion contrôlée** (`/admin/ingestion`). Les données d’un fournisseur peuvent être préparées sous forme de candidats sans modifier les fiches Coaster World.

Le premier flux exploitable est le catalogue de parcs ThemeParks.wiki : DATA propose les rapprochements possibles puis l’administrateur choisit explicitement **Associer**, **Créer** ou **Ignorer**. Les valeurs brutes, les identifiants externes et la décision restent traçables.

## v0.14.0 — Ingestion multi-entités et observations

L’ingestion contrôlée ne se limite plus aux parcs. Le moteur générique accepte désormais les **parcs, attractions, coasters et POI**, conserve le contexte du parc parent et évite les rapprochements homonymes entre parcs différents.

Chaque champ proposé par une source est stocké comme une valeur candidate. Après une décision humaine **Associer** ou **Créer**, ces valeurs deviennent des **observations sourcées** dans le moteur de fiabilité. Elles ne deviennent jamais automatiquement des valeurs canoniques. Les coasters conservent leur fiche technique séparée tout en rattachant les identifiants externes à l’attraction sous-jacente, ce qui prépare également les futurs flux Live.


## v0.15.0 — File « À vérifier » et validation canonique

La fiabilité des données devient directement administrable : chaque nouvelle valeur sans donnée canonique, valeur divergente ou conflit ouvre une entrée dans la file **À vérifier**. L’administrateur peut accepter une observation, la rejeter ou confirmer la valeur Coaster World existante. Chaque décision est historisée et la valeur canonique reste la seule valeur publiée par l’API.


## v0.16.1 — Correctif sélection import pilote

- Force le rafraîchissement des ressources d’administration après une mise à jour grâce à un cache-busting basé sur la date des fichiers CSS/JS.
- Le bouton « Préparer la sélection » reste utilisable sans JavaScript ; les contrôles de sélection et de limite restent appliqués côté serveur.
- Corrige le cas où une case était cochée mais le compteur restait à 0/10 avec un ancien `admin.js` conservé par le navigateur.

## v0.16.0 — Premier import réel ThemeParks.wiki

Le catalogue ThemeParks.wiki peut maintenant servir à préparer un vrai lot d’ingestion, mais uniquement pour les parcs explicitement sélectionnés dans l’aperçu. La limite pilote est de 10 parcs par lot par défaut (`CW_DATA_TPW_MAX_PARKS_PER_BATCH`). Le catalogue complet reste en lecture seule ; chaque parc sélectionné devient un candidat à **Associer / Créer / Ignorer** avant toute écriture encyclopédique.
## v0.17.0 — Noyau multi-sources

La page **Sources & fournisseurs** peut installer depuis le web un noyau complémentaire composé de **Wikidata, Wikipedia, OpenStreetMap / Overpass et Queue-Times**. Chaque fournisseur possède ses capacités, ses sources et un connecteur de test spécialisé. L'installation est idempotente et n'écrase pas les personnalisations existantes. Aucun import encyclopédique ou Live n'est lancé par cette version.

## v0.18.0 — Enrichissement multi-sources des parcs

Une fiche parc déjà reliée à un fournisseur peut maintenant lancer une collecte encyclopédique depuis l'administration. Le premier pipeline interroge **ThemeParks.wiki, Wikidata, Wikipedia et OpenStreetMap / Overpass** dans cet ordre afin de consolider l'identité du parc avant les sources suivantes.

Les résultats sont enregistrés exclusivement comme **observations sourcées** avec confiance et provenance. Les identifiants externes reconnus sont reliés à la fiche, les cas ambigus sont ignorés et aucun champ canonique n'est modifié automatiquement. Les nouvelles valeurs ou divergences rejoignent la file **À vérifier** avant publication par l'API. Queue-Times reste volontairement réservé au moteur Live.



## v0.18.1 — Fiabilisation Wikidata / Overpass
- Wikipedia récupère le `wikibase_item` via MediaWiki `pageprops` afin de transmettre un QID fiable à Wikidata.
- Wikidata utilise prioritairement ce QID au lieu d'une recherche globale par libellé.
- Overpass limite les recherches autour des coordonnées déjà connues du parc.
- Le rapport d'enrichissement affiche le détail technique d'une erreur fournisseur pour l'administration.


## v0.19.0 — Ingestion du contenu des parcs

Une fiche parc liée à ThemeParks.wiki peut maintenant préparer son contenu depuis l’endpoint `/v1/entity/{id}/children`. Les attractions, spectacles et restaurants reconnus sont transformés en candidats d’ingestion rattachés au bon parc, sans création encyclopédique automatique.

Les types `ATTRACTION` et `SHOW` deviennent des candidats Attraction, tandis que `RESTAURANT` devient un candidat POI. ThemeParks.wiki ne distinguant pas les coasters dans son type d’entité, DATA ne devine pas cette classification : une attraction pourra recevoir son extension technique Coaster plus tard après croisement avec Wikidata, OpenStreetMap ou d’autres sources spécialisées.

Les imports sont rejouables sans dupliquer les identifiants déjà associés ni les candidats encore en attente.

## v0.20.0 — Classification et automatisation contrôlée du contenu

Les lots `park_content` peuvent désormais être analysés avec OpenStreetMap / Overpass avant traitement. Les attractions confirmées comme `attraction=roller_coaster` sont reclassées en **Coaster** avec un score et leurs preuves conservées.

DATA marque également les candidats suffisamment sûrs pour une création groupée : parc parent résolu, identifiant externe unique, coordonnées présentes, aucun rapprochement existant et aucun doublon de nom dans le lot. Les cas ambigus restent manuels. Les preuves OSM, Wikidata et Wikipedia détectées sont matérialisées après création/association sous forme d'identifiants externes et d'observations, sans publication canonique automatique.


## v0.20.1 — Classification coaster Wikidata et rattrapage

La classification des coasters ne dépend plus uniquement du balisage OpenStreetMap. L’analyse d’un lot `park_content` croise désormais **OpenStreetMap / Overpass et Wikidata**. Wikidata recherche les éléments proches du parc dont le type est `roller coaster` (`Q204832`) ou une sous-classe, puis rapproche nom et coordonnées du candidat.

Le correctif sait aussi **rattraper les attractions déjà créées** par la v0.20.0 : si une attraction comme Mystic est ensuite confirmée comme coaster avec une confiance suffisante, DATA ajoute l’extension technique `coasters` sur l’attraction existante au lieu de créer un doublon. Les identifiants et observations Wikidata sont conservés et passent toujours par la file **À vérifier** avant toute valeur canonique.

## v0.20.2 — Correctif compteur Coasters confirmés

Le résumé des lots `park_content` compte désormais tous les candidats actuellement confirmés comme **Coaster**, et non uniquement les classifications produites par la dernière exécution de l'analyse. Le total reste exact lorsque les candidats sont répartis sur plusieurs pages. Aucune donnée encyclopédique ni classification existante n'est modifiée par ce correctif.
