Files
sxchnge/frontend/AGENTS.md
T

6.5 KiB

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 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.