# AGENTS.md

This is a Flutter application for iOS and Android using Riverpod, go_router, and code generation.

## Project

Stack: Flutter stable channel, Dart 3, Riverpod (code generated providers), go_router, freezed, json_serializable, dio.

Layout:

- `lib/main.dart` entry point and provider scope
- `lib/app/router.dart` go_router configuration, the single source of routes
- `lib/app/theme.dart` ThemeData, colors, typography
- `lib/features/<feature>/presentation/` screens and widgets
- `lib/features/<feature>/application/` providers and controllers
- `lib/features/<feature>/domain/` freezed models and value objects
- `lib/features/<feature>/data/` repositories and API clients
- `lib/shared/` widgets and utilities used by more than one feature
- `test/` mirrors `lib/`

Generated files end in `.freezed.dart`, `.g.dart`. They are outputs, not sources.

## Commands

```bash
flutter pub get                                    # install dependencies
flutter run                                        # run on the connected device
flutter run -d ios / -d android                    # target a platform
dart run build_runner build --delete-conflicting-outputs   # codegen, run after model or provider changes
dart run build_runner watch --delete-conflicting-outputs   # codegen in watch mode
flutter analyze                                    # static analysis, must be clean
dart format lib test
flutter test                                       # unit and widget tests
flutter test test/features/auth                    # one directory
flutter build apk --release
flutter build ipa --release
flutter clean                                      # when the build cache is suspect
```

After changing any freezed model, JSON model, or annotated provider, run build_runner before running or testing. A missing codegen step shows up as unresolved symbols.

## Platform notes

- Permissions: declare in `android/app/src/main/AndroidManifest.xml` and `ios/Runner/Info.plist`. Both are required, and iOS needs a human readable usage string.
- Minimum versions: iOS 13, Android minSdk 23. Do not raise them without approval.
- Android system back is handled by go_router. Use `PopScope` for any screen that must confirm before leaving.
- Use `Theme.of(context).platform` for behavioral differences, not `Platform.isIOS`, so widget tests stay controllable.
- Safe areas: wrap scaffold bodies in `SafeArea`. Do not hardcode notch or status bar heights.
- Adding or upgrading a plugin with native code requires `flutter clean` and a full rebuild, hot reload will not pick it up.
- Test on both a physical Android device and an iOS simulator before calling a UI change done.

## Code style

- Widgets are classes, never functions returning a Widget. Extract a `StatelessWidget` instead of a `_buildX` method.
- Use `const` constructors wherever possible. `flutter analyze` must pass with zero warnings.
- State lives in providers. A `StatefulWidget` is only for animation controllers, focus nodes, and text controllers.
- Watch providers with `ref.watch` in build and `ref.read` in callbacks. Never call `ref.read` during build.
- Models are freezed classes with `fromJson`. No hand written `copyWith` or `==`.
- Repositories return domain models, never raw `Map<String, dynamic>`.
- Navigation goes through named routes in `lib/app/router.dart`. No `Navigator.push` with an inline `MaterialPageRoute`.
- Colors, spacing, and text styles come from the theme. No raw `Color(0xFF...)` in a widget.
- Async work in the UI layer goes through `AsyncValue` and renders loading and error states explicitly.

## Boundaries

Do not touch without explicit instruction:

- Any `.freezed.dart` or `.g.dart` file. Change the source and rerun build_runner.
- `ios/` and `android/` build configuration, signing, Gradle files, and `Podfile.lock`.
- `pubspec.lock`. Change `pubspec.yaml` and run `flutter pub get`.
- App identifiers, version, and build number in `pubspec.yaml`.
- `.github/workflows/`, fastlane configuration, and store metadata.

Needs human review: new plugins with native dependencies, permission additions, deep link configuration, and any change to `lib/app/router.dart` route names.

## Testing

- `flutter test` runs unit and widget tests.
- Required unit tests: repositories, controllers and notifiers, and any pure Dart helper.
- Widget tests cover screens with conditional rendering, using `ProviderScope` overrides for fakes.
- Integration tests in `integration_test/` cover sign in and the primary user flow only, they are slow and stay minimal.
- Golden tests are used only for shared design system widgets. Regenerate deliberately, never with a blanket update.
- A bug fix ships with a test that fails before the fix.

## Git workflow

- Branch from `main`: `feat/short-description`, `fix/short-description`.
- Conventional commits: `feat(profile): add avatar upload`.
- Generated files are committed, but regenerate them in a separate commit from behavior changes so the diff stays readable.
- PR description includes screenshots from both platforms for any UI change.
- Never commit to `main`.
