Files
Krow-workspace/docs/MOBILE/00-agent-development-rules.md

8.3 KiB

Agent Development Rules

These rules are NON-NEGOTIABLE. They are designed to prevent architectural degradation by automated agents.

1. File Creation & Structure

  1. Feature-First Packaging:
    • DO: Create new features as independent packages in apps/mobile/packages/features/<app_name>/<feature_name>.
    • DO NOT: Add features to apps/mobile/packages/core or existing apps directly.
    • DO NOT: Create cross-feature or cross-app dependencies.
  2. Path Conventions:
    • Entities: apps/mobile/packages/domain/lib/src/entities/<entity>.dart
    • Repositories (Interface): apps/mobile/packages/features/<app_name>/<feature>/lib/src/domain/repositories/<name>_repository_interface.dart
    • Repositories (Impl): apps/mobile/packages/features/<app_name>/<feature>/lib/src/data/repositories_impl/<name>_repository_impl.dart
    • Use Cases: apps/mobile/packages/features/<app_name>/<feature>/lib/src/application/<name>_usecase.dart
    • BLoCs: apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/blocs/<name>_bloc.dart
    • Pages: apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/pages/<name>_page.dart
    • Widgets: apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/widgets/<name>_widget.dart
  3. Barrel Files:
    • DO: Use export in lib/<package_name>.dart only for public APIs.
    • DO NOT: Export internal implementation details in the main package file.

2. Naming Conventions

Follow Dart standards strictly.

Type Convention Example
Files snake_case user_profile_page.dart
Classes PascalCase UserProfilePage
Variables camelCase userProfile
Interfaces terminate with Interface AuthRepositoryInterface
Implementations terminate with Impl AuthRepositoryImpl

3. Logic Placement (Strict Boundaries)

  • Business Rules: MUST reside in Use Cases (Domain/Feature Application layer).
    • Forbidden: Placing business rules in BLoCs or Widgets.
  • State Logic: MUST reside in BLoCs or StatefulWidgets (only for ephemeral UI state).
    • Forbidden: setState in Pages for complex state management.
    • Recommendation: Pages should be StatelessWidget with state delegated to BLoCs.
  • Data Transformation: MUST reside in Repositories (Data Connect layer).
    • Forbidden: Parsing JSON in the UI or Domain.
    • Pattern: Repositories map Data Connect models to Domain entities.
  • Navigation Logic: MUST reside in Flutter Modular Routes.
    • Forbidden: Navigator.push with hardcoded widgets.
    • Pattern: Use named routes via Modular.to.navigate().
  • Session Management: MUST reside in DataConnectService via SessionHandlerMixin.
    • Pattern: Automatic token refresh, auth state listening, and role-based validation.
    • UI Reaction: SessionListener widget wraps the entire app and responds to session state changes.

4. Localization (core_localization) Integration

All user-facing text MUST be localized using the centralized core_localization package:

  1. String Management:
    • Define all user-facing strings in apps/mobile/packages/core_localization/lib/src/l10n/
    • Use slang or similar i18n tooling for multi-language support
    • Access strings in presentation layer via context.strings.<key>
  2. BLoC Integration:
    • LocaleBloc manages the current locale state
    • Apps import core_localization.LocalizationModule() in their module imports
    • Wrap app with BlocProvider<LocaleBloc>() to expose locale state globally
  3. Feature Usage:
    • Pages and widgets access localized strings: Text(context.strings.buttonLabel)
    • Build methods receive BuildContext with access to current locale
    • No hardcoded English strings in feature packages
  4. Error Messages:
    • Use ErrorTranslator from core_localization to map domain failures to user-friendly messages
    • Pattern: Failures emitted from BLoCs are translated to localized strings in the UI

5. Data Connect Integration Strategy

All backend access is centralized through DataConnectService in apps/mobile/packages/data_connect:

  1. Repository Interface First: Define abstract interface class <Name>RepositoryInterface in the feature's domain/repositories/ folder.
  2. Repository Implementation: Implement the interface in data/repositories_impl/ using _service.run() wrapper.
    • Pattern: await _service.run(() => connector.<query>().execute())
    • Benefit: Automatic auth validation, token refresh, and error handling.
  3. Session Handling: Use DataConnectService.instance.initializeAuthListener(allowedRoles: [...]) in app main.dart.
    • Automatic: Token refresh with 5-minute expiry threshold.
    • Retry Logic: 3 attempts with exponential backoff (1s → 2s → 4s) before emitting error.
    • Role Validation: Configurable per app (e.g., Staff: ['STAFF', 'BOTH'], Client: ['CLIENT', 'BUSINESS', 'BOTH']).
  4. Session State Management: Wrap app with SessionListener widget to react to session changes.
    • Dialogs: Shows session expired or error dialogs for user-facing feedback.
    • Navigation: Routes to login on session loss, to home on authentication.

5. Prototype Migration Rules

You have access to prototypes/ folders. When migrating code:

  1. Extract Assets:
    • You MAY copy icons, images, and colors. But they should be tailored to the current design system. Do not change the colours and typgorahys in the design system. They are final. And you have to use these in the UI.
      • When you matching colous and typography, from the POC match it with the design system and use the colors and typography from the design system. As mentioned in the apps/mobile/docs/03-design-system-usage.md.
  2. Extract Layouts: You MAY copy build methods for UI structure.
  3. REJECT Architecture: You MUST NOT copy the GetX, Provider, or MVC patterns often found in prototypes. Refactor immediately to Bloc + Clean Architecture with Flutter Modular and Melos.

6. Handling Ambiguity

If a user request is vague:

  1. STOP: Do not guess domain fields or workflows.
  2. ANALYZE:
  • For architecture related questions, refer to apps/mobile/docs/01-architecture-principles.md or existing code.
  • For design system related questions, refer to apps/mobile/docs/03-design-system-usage.md or existing code.
  1. DOCUMENT: If you must make an assumption to proceed, add a comment // ASSUMPTION: <explanation> and mention it in your final summary.
  2. ASK: Prefer asking the user for clarification on business rules (e.g., "Should a 'Job' have a 'status'?").

7. Dependencies

  • DO NOT add 3rd party packages without checking apps/mobile/packages/core first.
  • DO NOT add firebase_auth or firebase_data_connect to any Feature package. They belong in data_connect only.
  • Service Locator: Use DataConnectService.instance for singleton access to backend operations.
  • Dependency Injection: Use Flutter Modular for BLoC (never use addSingleton for Blocs, always use add method) and UseCase injection in Module.routes().

8. Error Handling

  • Domain Failures: Define custom Failure classes in domain/failures/.
  • Data Connect Errors: Map Data Connect exceptions to Domain failures in repositories.
  • User Feedback: BLoCs emit error states; UI displays snackbars or dialogs.
  • Session Errors: SessionListener automatically shows dialogs for session expiration/errors.

9. Testing

  • Unit Tests: Test use cases and repositories with real implementations.
  • Widget Tests: Use WidgetTester to test UI widgets and BLoCs.
  • Integration Tests: Test full feature flows end-to-end with Data Connect.
  • Pattern: Use dependency injection via Modular to swap implementations if needed for testing.

10. Follow Clean Code Principles

  • Add doc comments to all classes and methods you create.
  • Keep methods and classes focused and single-responsibility.
  • Use meaningful variable names that reflect intent.
  • Keep widget build methods concise; extract complex widgets to separate files.