---
description: Guidelines for Flutter and Dartr
globs: **/*.dart
---
This is Kasy guidelines
Generate code, corrections, and refactorings that comply with the basic principles and nomenclature.

## Dart General Guidelines

### Basic Principles

- Use English for all code and documentation.
- Always declare the type of each variable and function (parameters and return value).
- variables use name that help us understand how they are used 
- You have read Martin fowler - Refactoring book
- Avoid using type any
- Create necessary types
- Don't leave blank lines within a function
- One export per file
- Prefer super contructor

### Nomenclature

- Use PascalCase for classes.
- Use camelCase for variables, functions, and methods.
- Use underscores_case for file and directory names.
- Avoid magic numbers and define constants.
- Start each function with a verb.
- Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
- Use complete words instead of abbreviations and correct spelling.
- Except for standard abbreviations like API, URL, etc.
- Except for well-known abbreviations:
  - i, j for loops
  - err for errors
  - ctx for contexts
- req, res, next for middleware function parameters
- Prefer noun for class names 
- Prefer verb for methods

### Import
- always use package import even for our project files
Ex: import 'package:kasy_kit/core/data/entities/upload_result.dart';
- Comply to the always_use_package_imports rule
- Our package is named kasy_kit
- DO avoid relative imports for files in lib/

## Kasy architecture

Feature-first, 3 layers. Full contract (with the Kasy design system, tokens,
components, i18n): **`AGENTS.md`** in this directory — read it before
generating any UI code, it is the source of truth, not this summary.

### Folder structure

```
lib
├── components/   # Kasy design-system widgets (KasyButton, KasyCard, KasyTextField, …)
├── core/         # cross-cutting: theme/, data/, states/, security/, widgets/, i18n
└── features/
    └── <feature>/
        ├── api/           # data source (Firebase / Supabase / REST) → returns entities
        ├── repositories/  # entities → domain models (business logic)
        ├── providers/     # Riverpod notifiers → immutable page state
        └── ui/            # pages, components (use provider + domain), widgets (dumb)
```

### 1. The data layer (`api/`)

Fetches data from Firebase/Supabase/REST (depends on the backend the project
was generated with), parses/serializes it, returns **entities**. The only
layer not covered by unit tests. Only `repositories/` may call `api/` classes.

```dart
final userApiProvider = Provider<UserApi>(
  (ref) => UserApi(client: Supabase.instance.client),
);

class UserApi {
  final SupabaseClient _client;
  UserApi({required SupabaseClient client}) : _client = client;

  Future<UserEntity?> get(String id) async {
    final res = await _client.from('users').select().eq('id', id);
    if (res.isEmpty) return null;
    return UserEntity.fromJson(res.first);
  }
}
```

### 2. The domain layer (`repositories/`)

Transforms entities into domain models (business logic) for the presentation
layer. Domain models use `@freezed` for immutability/union types; prefer a
typed value object over a raw `String`/`int` when the domain has an invariant
(e.g. `Email`, not a bare `String`).

```dart
final userRepositoryProvider = Provider<UserRepository>(
  (ref) => UserRepository(userApi: ref.read(userApiProvider)),
);

class UserRepository {
  final UserApi _userApi;
  UserRepository({required UserApi userApi}) : _userApi = userApi;

  Future<User?> get(String id) async {
    final entity = await _userApi.get(id);
    return entity == null ? null : User.fromEntity(entity);
  }
}
```

### 3. The presentation layer (`providers/` + `ui/`)

A Riverpod notifier (`providers/`) exposes an immutable (freezed) page state;
the view (`ui/`) `ref.watch`es it, uses `.when`/`.map` for data/loading/error,
and triggers actions back on the notifier. Views use kit components
(`KasyButton`, `KasyScreen`, …) and tokens (`context.colors.*`,
`KasySpacing.*`) — see `AGENTS.md` golden rules 1-2 — never raw Material or
hardcoded values.

```dart
@Riverpod(keepAlive: false)
class FeedbackPageNotifier extends _$FeedbackPageNotifier {
  @override
  Future<FeedbackPageState> build() async {
    final repo = ref.read(feedbackRepositoryProvider);
    final features = await repo.getActiveFeatureRequests();
    return FeedbackPageState(featureRequests: features);
  }
}
```

- for each new file, don't forget to add the required imports


