# Phase 1D — Champs extensibles, traductions et alias

Version : 0.4.0

## Objectif

Permettre à Coaster World DATA d'ajouter de nouvelles informations sans modifier le schéma principal à chaque nouveau besoin, tout en préparant les contenus multilingues et les noms alternatifs.

Cette phase complète le socle de la Phase 1 :

- les colonnes structurées restent utilisées pour les données essentielles et très consultées ;
- les nouvelles propriétés encyclopédiques peuvent être déclarées dans un registre de champs ;
- leurs valeurs utilisent le système de provenance et de fiabilité de la Phase 1C ;
- les textes peuvent exister séparément par langue ;
- les anciens noms, noms locaux et variantes de recherche peuvent être conservés comme alias.

## Langues de base

Le projet déclare dès maintenant les langues suivantes :

- français (`fr`) ;
- anglais (`en`) ;
- allemand (`de`) ;
- espagnol (`es`) ;
- italien (`it`).

La structure accepte d'autres codes de langue plus tard sans migration supplémentaire.

## `data_fields`

Registre des champs encyclopédiques extensibles.

Exemple :

`construction_cost_eur`

peut être déclaré comme :

- type `decimal` ;
- groupe `construction` ;
- unité `EUR` ;
- applicable aux attractions et coasters ;
- filtrable ou non ;
- traduisible ou non.

Ajouter ce champ ne nécessite aucune nouvelle colonne dans `attractions` ou `coasters`.

Les valeurs réelles restent stockées dans `data_observations` et `canonical_values`, ce qui conserve la provenance, la confiance, les conflits et l'historique.

## `data_field_scopes`

Détermine les types d'entités auxquels un champ peut s'appliquer.

Types prévus :

- `park` ;
- `park_zone` ;
- `attraction` ;
- `coaster` ;
- `poi` ;
- `organization`.

Le `DataFieldRegistryService` empêche l'utilisation d'un champ enregistré sur un type d'entité non autorisé.

## `translations`

Stocke les valeurs textuelles publiées par langue.

Une traduction est identifiée par :

`entité + champ + langue`

Exemple pour un parc :

- `description / fr` ;
- `description / en` ;
- `description / de` ;
- `description / es` ;
- `description / it`.

Les valeurs localisées peuvent aussi suivre tout le cycle de fiabilité de la Phase 1C. Lorsqu'une valeur localisée devient canonique, la table `translations` est synchronisée automatiquement.

Une traduction peut indiquer si elle provient d'une traduction machine et si elle a été vérifiée manuellement.

## Extension du moteur de fiabilité

Les tables suivantes disposent maintenant d'un contexte de langue :

- `data_observations` ;
- `canonical_values` ;
- `data_conflicts` ;
- `canonical_value_history`.

Ainsi, deux fournisseurs qui donnent des descriptions françaises différentes créent un conflit français sans perturber la description anglaise.

Les anciennes données de la Phase 1C restent non localisées avec une locale interne vide.

## `aliases`

Conserve les noms alternatifs sans modifier le nom canonique de l'entité.

Exemples d'utilisation :

- ancien nom ;
- nom local ;
- nom court ;
- variante typographique ;
- nom provenant d'un fournisseur.

Chaque alias peut conserver :

- sa langue ;
- son type ;
- son fournisseur et sa source ;
- un score de confiance ;
- son état vérifié ou non ;
- une période de validité ;
- sa valeur normalisée pour faciliter les recherches futures.

## `DataFieldRegistryService`

Le service permet d'enregistrer ou faire évoluer un champ sans toucher aux migrations des entités.

Il contrôle notamment :

- la clé du champ ;
- son type de valeur ;
- les entités autorisées ;
- son caractère traduisible ;
- les valeurs multiples ;
- ses libellés multilingues.

Les types disponibles actuellement sont :

`string`, `text`, `integer`, `decimal`, `boolean`, `date`, `datetime`, `url`, `json`.

## Règle de compatibilité

Les champs structurés existants (`opened_year`, `height_m`, etc.) continuent à être synchronisés dans leurs colonnes lorsqu'ils deviennent canoniques.

Un champ extensible qui n'existe pas comme colonne est simplement conservé dans `canonical_values` et reste accessible via `canonicalData()`.

Le projet garde donc les performances des champs essentiels tout en restant extensible.

## Hors périmètre

Cette phase ne contient pas encore :

- l'interface web permettant de créer les champs ;
- l'import automatique des providers ;
- la traduction automatique par IA ;
- la recherche globale utilisant les alias ;
- l'API publique ;
- les temps d'attente Live.
