Skip to content

Architecture technique

TakCastel edited this page Jul 3, 2026 · 2 revisions

Architecture technique

Spec technique transverse. L'existant d'abord, puis les services à construire pour couvrir Système-de-jeu, Économie, Carte-galactique.

Existant (depuis la migration Laravel, juillet 2026)

  • Monorepo : api/ (Laravel 12, API JSON /api/v1, port 8000) + front/ (Next.js, port 3000, app joueur). Voir ADR 0001 et ADR 0002.
  • PostgreSQL (Docker, port 54322). Schéma canonique dans api/database/migrations/, seeds dans api/database/seeders/. Tables core en place : profiles, forum (categories/forums/topics/posts), characters, groups/group_members, chat_messages, items/inventory/economy_history, ships, wiki.
  • Auth : Fortify + Sanctum (session SPA par cookies, CSRF). Le front consomme exclusivement l'API (front/src/shared/utils/api.ts).
  • Architecture front : Feature-Driven Development (src/features/<domaine>/), composants partagés dans src/shared/.
  • Prod : Docker Compose sur VPS (swor.fr = front, api.swor.fr = Laravel), CI GitHub Actions (tests PHPUnit + typecheck/build front).
  • Back-office Filament à venir sur /admin (#39) ; temps réel via Laravel Reverb (#38).

Rôles et sécurité

  • Rôles : joueur / animateur (MJ) / modérateur / admin, stockés sur profiles.role (enum UserRole) (🔶 ou table de rôles multiples — un modérateur peut être MJ).
  • Toute la logique métier est côté serveur (controllers + policies/gates Laravel) : les écritures sensibles (jets de dés, transactions, validation de fiche, tick économique) ne passent jamais par le client. Gates admin et moderate en place.
  • Le back-office Filament vérifiera le rôle via les mêmes gates (#39).

Services à construire

1. Service de jets de dés

  • Génération côté serveur uniquement : endpoint API qui tire le jet (random_int), l'insère dans dice_rolls et le lie au post — le client ne fournit jamais un résultat.
  • Idempotence : un jet est rattaché à une déclaration d'action unique (pas de reroll en cas de retry réseau).
  • Diffusion en temps réel sur le sujet via Reverb/Echo (les autres participants voient le jet arriver).

2. Arbitre IA (évaluation de difficulté)

Appel API Claude par action déclarée : entrée = action + contexte du sujet + fiche mécanique du personnage ; sortie = JSON structuré {compétence, DD, avantage, justification, conséquences_suggérées}.

Patterns d'implémentation :

  • Sorties structurées (output_config.format avec JSON schema, ou client.messages.parse()) : garantit un verdict parsable, pas de post-traitement fragile.
  • Prompt caching : le prompt système (règles d'arbitrage, échelle des DD, format de réponse) est volumineux et stable → placé en tête avec cache_control, le contenu volatile (post, fiche) après. Les relectures de cache coûtent ~0,1× le prix d'entrée.
  • Maîtrise des coûts : quota de jets arbitrés par joueur/jour, cache 15 min sur une même action re-soumise, monitoring du champ usage de chaque réponse.
  • Streaming inutile ici (réponse courte) ; latence cible < 3 s.

Choix du modèle (prix au 2026-06, par million de tokens) :

Modèle Input / Output Position
Claude Haiku 4.5 (claude-haiku-4-5) $1 / $5 Le moins cher et le plus rapide — à évaluer en premier sur ce cas d'usage (tâche courte et cadrée)
Claude Sonnet 5 (claude-sonnet-5) $3 / $15 (intro $2/$10 jusqu'au 31/08/2026) Meilleur jugement narratif, si Haiku arbitre mal les cas subtils
Claude Opus 4.8 (claude-opus-4-8) $5 / $25 Plafond qualité, sans doute surdimensionné pour un DD

🔶 Décision à prendre sur éval réelle : constituer un jeu de ~50 actions RP annotées (DD attendu par un humain) et comparer les modèles dessus. Ordre de grandeur du coût : un arbitrage ≈ 2–3 k tokens d'entrée (dont l'essentiel caché) + ~200 de sortie → une fraction de centime par action avec Haiku ; le quota par joueur est le vrai garde-fou.

3. Tick économique

  • Job planifié hebdomadaire : Laravel scheduler (routes/console.php + schedule:run), job en file d'attente, transactionnel.
  • Chaque tick est journalisé (econ_ticks, econ_tick_entries) et rejouable en lecture ; en cas d'échec, rollback complet du tick.
  • Les règles de production (infrastructure → ressources) sont des données, pas du code : table infra_types avec les rendements, éditable depuis Filament.

4. Carte galactique

  • Données en base (star_systems, planets, planet_states par ère), rendu client : SVG interactif (zoom/pan via viewBox) tant que < ~200 systèmes ; passage canvas/WebGL seulement si besoin réel. 🔶
  • Pas de tuiles ni de serveur carto : la galaxie est un espace 2D abstrait, pas une carte géographique.

5. Notifications & realtime

  • Table notifications + Laravel Reverb (WebSockets) pour la cloche in-app (story #15).
  • Le chat (#38) et les jets de dés utilisent le même canal Reverb par sujet.

Modèle de données — vue des deltas

Les tables à ajouter, regroupées par spec (détail dans chaque page) :

Domaine Tables nouvelles
Système-de-jeu dice_rolls, action_checks, gm_requests, damage_events
Personnages-et-compagnons companions, character_reviews
Économie resources_balances, infrastructures, infra_types, enterprises (+shares/sites), employments, econ_ticks, econ_tick_entries, econ_events
Carte-galactique star_systems, planet_states, planet_control_history (extension de planets)
Forum topic_participants, topic_follows, notifications (+colonnes sur topics/posts)
Wiki-Univers wiki_article_revisions, wiki_proposals (+colonnes sur wiki_articles)

Chaque ajout arrive par migration Laravel dans api/database/migrations/, avec ses policies dans le même changement.

Environnements

Env Où Particularités
Dev local Postgres Docker (npm run docker:up) + npm run dev:api / dev:front Seeders Laravel
CI GitHub Actions Tests PHPUnit (api) + typecheck & build (front)
Prod VPS Docker Compose (docker-compose.prod.yml) swor.fr (front) + api.swor.fr (Laravel) via Nginx

🔶 Un environnement de staging pourra devenir nécessaire quand il y aura plusieurs contributeurs actifs.