quel-est-ce-pokemon/docs/ARCHITECTURE.md
Maxiwere45 8608fc023c docs: sync ARCHITECTURE and README with actual codebase
Add missing providers (locale, theme, genFilter, caughtCount), all 6
pages, full widget inventory, core/l10n layers, and game mechanics
(hints, skips, shiny, bonuses, bilingual input, gen filter).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 21:58:37 +02:00

4.8 KiB
Raw Permalink Blame History

Application Architecture

Overview

L'application suit une Clean Architecture allégée en trois couches, avec une règle de dépendance stricte : les dépendances pointent vers l'intérieur. Le state management est assuré par Riverpod (providers manuels).

Couches

core (transversal)

  • AppConstants : toutes les constantes métier en un seul endroit (vies, points, shiny odds, plages de générations, clés SharedPreferences, URL API).
  • logger : wrapper minimal autour de dart:developer.

domain (Dart pur)

  • Entités : Pokemon, immuable, sans dépendance Flutter/DB/API.
  • Repository (interface) : PokemonRepository définit le contrat d'accès aux données.
  • Jeu : GameState (état immuable) et GameEngine (règles pures, testables).
    • GameEngine gère : soumission de réponse, vies, hints, skips, score, Shiny, bonus périodiques.
    • GameStatus : loading | playing | roundWon | gameOver.
    • GuessResult : correct | wrong | gameOver | invalid.

data

  • DTO : PokemonDto centralise tout le parsing JSON (API Tyradex + SQLite).
    • fromTyradexJson(), fromDb(), toDb().
  • Datasources :
    • PokemonLocalDataSource — SQLite via sqflite ; absent (null) sur le web.
    • PokemonRemoteDataSource — HTTP vers Tyradex + PokéAPI (genus anglais).
  • Repository (impl) : PokemonRepositoryImpl applique « DB locale d'abord, sinon API + cache ».

l10n

Internationalisation complète FR / EN via flutter_localizations + intl. Fichiers générés : app_localizations.dart, app_localizations_fr.dart, app_localizations_en.dart. La langue active est persistée dans SharedPreferences (AppConstants.prefsLocale).

presentation

Providers (Riverpod)

Provider Type Rôle
pokemonRepositoryProvider Provider DI du repository
pokedexProvider AsyncNotifier<List<Pokemon>> Chargement + cache du Pokédex
gameProvider Notifier<GameState> État de la partie en cours
selectedTabProvider StateProvider<int> Onglet de navigation courant
localeProvider Notifier<Locale> Langue active (FR/EN) + persistance
themeProvider Notifier<AppPalette> Palette de couleurs active (5 thèmes) + persistance
genFilterProvider Notifier<Set<int>> Générations sélectionnées pour le jeu + persistance
caughtCountProvider Provider<int> Nombre de Pokémon capturés (dérivé de pokedexProvider)

Pages

Fichier Rôle
main_page.dart Hub de navigation par onglets (Jeu / Pokédex / Système)
guess_page.dart Écran principal du jeu (silhouette, input, lives, score)
game_over_page.dart Écran de fin de partie avec stats de session
pokemon_list.dart Pokédex : liste filtrée + recherche par nom
pokemon_detail.dart Fiche détaillée : stats, type, genus, toggle normal/shiny
system_page.dart Paramètres (langue, palette) et statistiques globales

Widgets notables

  • Réutilisables : PokemonImage, PokemonTile, PokemonTypeWidget, ScanlineOverlay.
  • guess/ : GuessSilhouette, GuessInputSection, LivesRow, ScoreBoard, GenFilterSection.
  • detail/ : PokemonDetailTop, PokemonStatsPanel.
  • game_over/ : GameOverHeader, GameOverStats, GameOverActions, HingeDivider.
  • list/ : PokedexListHeader, PokedexCountBar.
  • system/ : LanguagePicker, PalettePicker, SectionTitle, SystemHeader, SystemStats.

Thème

type_colors.dart : couleur et libellé localisé par type Pokémon.

Flux de données

UI (Consumer) → Notifier → GameEngine (règles) + Repository (données)
                                 → DataSource (SQLite / HTTP) → DTO → Entity

Riverpod re-render automatiquement les consommateurs concernés. Plus de bus d'événements global ni d'accès inter-pages via l'arbre de widgets.

Mécaniques de jeu (résumé)

  • Vies : 3 au départ ; une vie perdue par mauvaise réponse ; game over à 0.
  • Hints : 3 au départ ; révèle partiellement le nom ; +1 tous les 5 bonnes réponses consécutives.
  • Skips : 3 au départ ; passe au Pokémon suivant sans pénalité ; +1 tous les 10 bonnes réponses.
  • Score : +10 pts normal, +20 pts shiny ; meilleur score persisté via SharedPreferences.
  • Shiny : 1 chance sur 10 (AppConstants.shinyOdds).
  • Filtre de génération : le joueur choisit parmi Gen IIX ; persisté entre les sessions.
  • Acceptation bilingue : le nom FR ou EN est accepté quelle que soit la langue de l'UI.

Tests

  • test/domain/game_engine_test.dart : règles du jeu.
  • test/data/pokemon_dto_test.dart : parsing JSON ↔ DB.
  • test/data/pokemon_repository_test.dart : logique du repository (datasources factices).
  • test/widget_test.dart : smoke test de démarrage de l'app.