docs: add design spec for persisting awards in database
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
93
docs/superpowers/specs/2026-04-01-awards-bdd-design.md
Normal file
93
docs/superpowers/specs/2026-04-01-awards-bdd-design.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# Awards en BDD — Design Spec
|
||||||
|
|
||||||
|
## Contexte
|
||||||
|
|
||||||
|
Actuellement, les récompenses des acteurs sont récupérées à la volée depuis Wikidata (SPARQL) lors de la génération d'une partie. Elles ne sont pas persistées en base de données, ce qui rend le système fragile (dépendance réseau à chaque partie) et empêche tout filtrage par type de récompense.
|
||||||
|
|
||||||
|
## Objectifs
|
||||||
|
|
||||||
|
1. Stocker les awards en BDD dès l'import des films
|
||||||
|
2. Introduire une notion de type de récompense (Oscar, Golden Globe, BAFTA...)
|
||||||
|
3. Adapter la génération des indices pour piocher en BDD au lieu d'appeler Wikidata
|
||||||
|
4. Préparer le terrain pour un futur filtrage par type (choix du joueur avant la partie) — hors scope de cette itération
|
||||||
|
|
||||||
|
## Modèle de données
|
||||||
|
|
||||||
|
### Nouvelle entité : `AwardType`
|
||||||
|
|
||||||
|
| Champ | Type | Description |
|
||||||
|
|-----------|------------|--------------------------------------------------------------------|
|
||||||
|
| `id` | int (PK) | Auto-increment |
|
||||||
|
| `name` | string | Nom affiché, ex: "Oscar", "Golden Globe", "BAFTA", "César" |
|
||||||
|
| `pattern` | string | Préfixe/mot-clé pour le matching sur les noms Wikidata, ex: "Academy Award" |
|
||||||
|
|
||||||
|
### Nouvelle entité : `Award`
|
||||||
|
|
||||||
|
| Champ | Type | Description |
|
||||||
|
|-------------|-------------------|--------------------------------------------------------------|
|
||||||
|
| `id` | int (PK) | Auto-increment |
|
||||||
|
| `awardType` | ManyToOne → AwardType | Type de la récompense |
|
||||||
|
| `actor` | ManyToOne → Actor | Acteur récompensé |
|
||||||
|
| `name` | string | Nom complet Wikidata, ex: "Academy Award for Best Actor" |
|
||||||
|
| `year` | int (nullable) | Année de la récompense |
|
||||||
|
|
||||||
|
### Modification entité `Actor`
|
||||||
|
|
||||||
|
| Champ | Type | Description |
|
||||||
|
|------------------|------|--------------------------------------------------|
|
||||||
|
| `awardsImported` | bool | `false` par défaut. Passe à `true` après import. |
|
||||||
|
|
||||||
|
### Relations
|
||||||
|
|
||||||
|
- `Actor` OneToMany → `Award`
|
||||||
|
- `AwardType` OneToMany → `Award`
|
||||||
|
|
||||||
|
## Flux d'import des awards
|
||||||
|
|
||||||
|
L'import se greffe sur le batch existant (`ImportFilmsBatchMessageHandler`), après `ActorSyncer::syncActorsForMovie()`.
|
||||||
|
|
||||||
|
### Étapes pour chaque acteur du film importé
|
||||||
|
|
||||||
|
1. Vérifier `actor.awardsImported`
|
||||||
|
2. Si `true` → skip
|
||||||
|
3. Si `false` → appeler `WikidataGateway::getAwards(actor)`
|
||||||
|
4. Pour chaque award retourné :
|
||||||
|
- Parcourir les `AwardType` existants et matcher le nom de l'award contre leur `pattern`
|
||||||
|
- Si un `AwardType` matche → l'utiliser
|
||||||
|
- Si aucun ne matche → créer un nouvel `AwardType` dynamiquement en extrayant le préfixe commun du nom (ex: "Screen Actors Guild Award for Outstanding Performance..." → type "Screen Actors Guild Award")
|
||||||
|
- Créer l'entité `Award` (name, year, actor, awardType)
|
||||||
|
5. Passer `actor.awardsImported = true`
|
||||||
|
6. Flush
|
||||||
|
|
||||||
|
### Gestion d'erreur
|
||||||
|
|
||||||
|
Si Wikidata est indisponible ou retourne une erreur :
|
||||||
|
- Ne **pas** mettre `awardsImported = true`
|
||||||
|
- L'import du film continue normalement (les awards seront retentés au prochain import contenant cet acteur)
|
||||||
|
- Log de l'erreur
|
||||||
|
|
||||||
|
## Génération des indices (hints)
|
||||||
|
|
||||||
|
### Changements dans `GameGridGenerator`
|
||||||
|
|
||||||
|
**Avant** : appel à `WikidataGateway::getAwards()` à la volée pour chaque acteur du grid.
|
||||||
|
|
||||||
|
**Après** :
|
||||||
|
1. Pour un hint de type "award", requêter les `Award` en BDD pour l'acteur
|
||||||
|
2. Si l'acteur a des awards → en choisir un au hasard
|
||||||
|
3. Si l'acteur n'a pas d'awards → fallback sur les types "film" ou "character" (comportement existant quand Wikidata échouait)
|
||||||
|
|
||||||
|
### Stockage du hint
|
||||||
|
|
||||||
|
- `GameRow.hintData` stocke l'**ID de l'`Award`** (au lieu d'une string brute comme avant)
|
||||||
|
- `resolveHintText()` récupère le nom complet + année depuis l'entité `Award`
|
||||||
|
|
||||||
|
### Pas de filtrage par `AwardType`
|
||||||
|
|
||||||
|
Pour cette itération, on pioche dans tous les awards de l'acteur sans filtrer par type. Le filtrage (choix du joueur : "mode Oscars", "mode Golden Globes"...) sera ajouté ultérieurement.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
- UI de choix du type de récompense avant la partie
|
||||||
|
- Filtrage des awards par type lors de la génération des indices
|
||||||
|
- Commande de re-sync des awards pour les acteurs déjà importés
|
||||||
Reference in New Issue
Block a user