docs: Add AGENTS.md with project-specific guidance
Document commands, layered Provider architecture, data and auth flows, and code conventions to guide AI agents working on the codebase.
This commit is contained in:
@@ -0,0 +1,73 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
## 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<XProvider>` 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.
|
||||||
Reference in New Issue
Block a user