# AGENTS.md Project-specific guidance for AI agents working on the MyIce Mobile codebase. ## Project Flutter mobile app (Dart SDK `>=3.1.0 <4.0.0`) for MyIce, a hockey club management platform. Talks to the backend at `https://myice.parano.ch`. UI is in French. Licensed under GPL-3.0-or-later (see `LICENSE`). ## Commands ```bash flutter pub get # install dependencies flutter run # run app (default device) flutter analyze # static analysis (flutter_lints) — MUST pass flutter test # widget tests — see note below dart run flutter_launcher_icons # regenerate launcher icons from assets/icon/logo.png flutter build apk --release # release build (android / ios / macos / web) ``` Always run `flutter analyze` before considering work done. Fix any new warnings/errors you introduce. There is currently one pre-existing `use_build_context_synchronously` info at `lib/screens/schedule_screen.dart:32` — leave it unless your changes touch that code. ### Known test issue `test/widget_test.dart` is the default Flutter starter test (tests a counter that does not exist in this app) and currently **fails**. Do not rely on `flutter test` as a gate until it is replaced with real tests. If you add tests, replace this file rather than appending to it. ## Architecture Layered architecture with the **Provider** pattern (`package:provider`): ``` lib/ ├── main.dart # MultiProvider setup, root routing (auth gate) ├── config/api_config.dart # baseUrl only ├── models/ # Plain data classes, fromJson / toJson factories ├── services/ # Data access (HTTP, auth, cache) — no Flutter UI │ ├── api_service.dart # Dio client, bearer token interceptor │ ├── auth_service.dart # OAuth flow + SharedPreferences token/account storage │ └── schedule_cache_service.dart # Per-account event & filter caching ├── providers/ # ChangeNotifiers — app state, reactive ├── screens/ # Full-page widgets └── widgets/ # Reusable UI components ``` ### Data flow 1. `main.dart` wires `ApiService` (single instance) into three providers: `AuthProvider`, `ScheduleProvider`, `EventDetailProvider`. 2. `AppRoot` calls `AuthProvider.init()` on first frame → restores token from `SharedPreferences`, validates via `/userinfo`, gates between `LoginScreen` and `ScheduleScreen`. 3. Screens read state via `Consumer` and dispatch actions on the provider. 4. Screens trigger loading in `initState` via `WidgetsBinding.instance.addPostFrameCallback`. ### Auth flow - OAuth via `flutter_web_auth_2` using custom URL scheme `myice://callback`. - Token is stored in `SharedPreferences` (key `access_token`), injected as a Dio bearer interceptor. - On 401/token expiry, `AuthProvider.init()` clears the token and returns to login. - The selected account is persisted (key `selected_account`). ## Conventions - **No comments** in source code — code should be self-explanatory. - **Models**: immutable fields, `fromJson` factory constructor, `toJson` method when caching is needed. JSON keys use snake_case, Dart fields use camelCase. - **Providers**: extend `ChangeNotifier`, expose public state fields + action methods, call `notifyListeners()` after mutations. - **UI strings are hardcoded in French** — `intl` is a dependency but localization is not yet wired up. - **Caching is keyed by account** — events, filters, and timestamps all namespace by account name in `SharedPreferences`. - **Only "Jeu" events are shown** — `ScheduleProvider` filters `eventType == 'Jeu'` from the full schedule. - **Style**: Material 3, indigo seed color, `const` constructors where possible, `super.key` parameter. ## Do not - Do not commit `.flutter-plugins-dependencies` — it is auto-generated and contains machine-specific paths. - Do not add comments unless explicitly asked. - Do not introduce new dependencies without checking `pubspec.yaml` first. - Do not use a state management solution other than Provider without discussing.