a0112d696e
Add the full GNU General Public License v3 text as LICENSE, declare the license in pubspec.yaml, and document it in README and AGENTS.md.
74 lines
4.1 KiB
Markdown
74 lines
4.1 KiB
Markdown
# 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<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.
|