# Frontend Agent Guidelines These instructions extend the repository-wide rules in the root `AGENTS.md` and apply whenever a task adds or modifies Dart or Flutter code under `frontend/`. Before completing the task, review the entire frontend diff produced by the current task, fix every in-scope issue found, and then perform the required validation. Use the [`$review-frontend-change`](../.agents/skills/review-frontend-change/SKILL.md) skill to perform this completion workflow. ## Preserve the frontend architecture This applies to `frontend/app`, every shared package and future web/mobile clients, including in-memory stubs. Keep an explicit data model even when it currently resembles the DTO; do not use a provider as a substitute for that model. The UI depends on providers/models; providers depend on service contracts; service implementations own DTO conversion through mappers. Replacing a service must not require DTO or networking changes in widgets or providers. - Strictly preserve the existing `dto` -> `mapper` -> `service` -> `model` -> `provider` flow. Widgets consume models and provider state; they must not bypass the flow by parsing transport data or calling backend APIs directly. - Keep responsibilities separated: - DTOs represent serialized transport contracts only. - Mappers convert between DTOs and frontend domain models. - Services own API and external I/O operations and return mapped models. - Models express frontend domain and presentation data without transport or provider lifecycle concerns. - Providers coordinate services, state transitions, loading and error state, and expose models to widgets. - Extend the established layer for new behavior instead of introducing parallel data paths, embedding mapping in services or providers, or moving business state into widgets. ## Reuse definitions and avoid naming stutter - Search existing DTOs, models, providers, widgets, and shared utilities before introducing another representation of the same concept. - Avoid stutter in type names, field names, parameters, nested access paths, directories, and filenames. The surrounding package or directory already provides context; each child name should add meaning instead of repeating it. - Prefer concise access such as `payment.details.id` over `payment.payment.paymentId`. - Avoid repeating a parent directory in a filename. For example, prefer `payment/widget.dart` over `payment/payment_widget.dart` and `profile/header.dart` over `profile/profile_header.dart`. - Keep architectural suffixes such as `DTO`, `Mapper`, `Service`, `Model`, and `Provider` only where they clarify the layer; do not repeat the domain name around them, such as `PaymentPaymentDTO`. ## Keep widgets structured and files focused - Keep widgets declarative and focused on presentation, composition, and user interaction. Move state orchestration and side effects into the established provider, service, or controller layer. - Review large `build` methods, deeply nested widget trees, and files containing multiple responsibilities. Extract cohesive widgets or supporting files with clear ownership before the code becomes difficult to scan or test. - Prefer one primary public widget or feature concept per file. Small private helpers may remain when they are tightly coupled and improve readability; do not fragment code into trivial files mechanically. - Treat reasonable file size as a cohesion and readability requirement rather than a fixed line limit. Generated files are excluded from this review. - Preserve lifecycle correctness when extracting widgets or providers, including disposal, subscription cleanup, mounted checks, asynchronous race handling, and minimal provider notifications. ## Maintain Dart header layout - Keep hand-written imports ordered from generic to specific: 1. Dart SDK imports (`dart:`). 2. Flutter SDK packages. 3. Third-party packages. 4. Shared internal packages such as `pshared`. 5. The current application package, such as `pweb` or `backoffice`. 6. Relative imports, when they are necessary. - Group imports from the same package together and sort their paths within the group. Separate every distinct package group with one blank line. - Place generated-code imports, including imports under a package's `generated/` path, after all hand-written import groups. Group generated imports by package and separate distinct generated package groups with one blank line. - Place `part` directives after all hand-written and generated import groups; they are the final directives in the header. Sort multiple `part` directives consistently. In a part file, keep the required `part of` directive first and do not add imports that Dart forbids there. - Separate the final header directive from the first declaration or annotation with exactly one empty line, meaning two consecutive newline characters. This is the layout produced by `dart format`. - Verify header layout with `dart format` and `flutter analyze`. Do not change lint configuration preemptively. If an analyzer rule actually conflicts with this layout, adjust only the narrowest affected package configuration, document why, and rerun the checks. ## Review implementation quality - Review the current task's frontend contribution for correctness, readability, maintainability, testability, accessibility, responsive behavior, and consistency with surrounding code and architecture. - Check loading, empty, success, and error states; nullability; asynchronous behavior; provider update scope; navigation; and user-visible failure paths. - Remove duplicated logic, dead code, unnecessary indirection, speculative abstractions, and avoidable widget rebuilds introduced by the task. - Add or update focused tests for changed widgets, DTO mapping, services, models, providers, edge cases, and failure paths as applicable. - Fix all findings caused by the current task before reporting completion. ## Required validation - Run `dart format --output=none --set-exit-if-changed` for every changed Dart file. - Run `flutter analyze` from each affected frontend package directory. - From the repository root, run `make test-frontend`, plus every applicable command from the root `AGENTS.md` change-scoped security requirements, after all review fixes are complete. - All commands must succeed before the task is reported as complete. Do not silently skip, suppress, or weaken checks. Report the commands and outcomes in the final response, or report the exact environmental blocker without claiming successful validation.