6.1 KiB
6.1 KiB
KROW Architecture Principles
This document is the AUTHORITATIVE source of truth for the KROW engineering architecture. All agents and engineers must adhere strictly to these principles. Deviations are interpreted as errors.
1. High-Level Architecture
The KROW platform follows a strict Clean Architecture implementation within a Melos Monorepo. Dependencies flow inwards towards the Domain.
graph TD
subgraph "Apps (Entry Points)"
ClientApp[apps/client]
StaffApp[apps/staff]
end
subgraph "Features (Presentation & Application)"
ClientFeature[packages/features/client/jobs]
StaffFeature[packages/features/staff/schedule]
SharedFeature[packages/features/shared/auth]
end
subgraph "Interface Adapters"
DataConnect[packages/data_connect]
DesignSystem[packages/design_system]
end
subgraph "Core Domain"
Domain[packages/domain]
Core[packages/core]
end
%% Dependency Flow
ClientApp --> ClientFeature & SharedFeature
StaffApp --> StaffFeature & SharedFeature
ClientApp --> DataConnect
StaffApp --> DataConnect
ClientFeature & StaffFeature & SharedFeature --> Domain
ClientFeature & StaffFeature & SharedFeature --> DesignSystem
ClientFeature & StaffFeature & SharedFeature --> Core
DataConnect --> Domain
DataConnect --> Core
DesignSystem --> Core
Domain --> Core
%% Strict Barriers
linkStyle default stroke-width:2px,fill:none,stroke:gray
2. Repository Structure & Package Roles
2.1 Apps (apps/)
- Role: Application entry points and Dependency Injection (DI) roots.
- Responsibilities:
- Initialize Flutter Modular.
- Assemble features into a navigation tree.
- Inject concrete implementations (from
data_connect) into Feature packages. - Configure environment-specific settings.
- RESTRICTION: NO business logic. NO UI widgets (except
AppandMain).
2.2 Features (packages/features/<APP_NAME>/<FEATURE_NAME>)
- Role: Vertical slices of user-facing functionality.
- Internal Structure:
domain/: Feature-specific Use Cases and Repository Interfaces.data/: Repository Implementations.presentation/:- Pages, BLoCs, Widgets.
- For performance make the pages as
StatelessWidgetand move the state management to the BLoC orStatefulWidgetto an external separate widget file.
- Responsibilities:
- Presentation: UI Pages, Modular Routes.
- State Management: BLoCs / Cubits.
- Application Logic: Use Cases.
- RESTRICTION: Features MUST NOT import other features. Communication happens via shared domain events.
2.3 Domain (packages/domain)
- Role: The stable heart of the system. Pure Dart.
- Responsibilities:
- Entities: Immutable data models (Data Classes).
- Failures: Domain-specific error types.
- RESTRICTION: NO Flutter dependencies. NO
json_annotation. NO package dependencies (exceptequatable).
2.4 Data Connect (packages/data_connect)
- Role: Interface Adapter for Backend Access (Datasource Layer).
- Responsibilities:
- Implement low-level Datasources or generated SDK wrappers.
- map Domain Entities to/from Firebase Data Connect generated code.
- Handle Firebase exceptions.
2.5 Design System (packages/design_system)
- Role: Visual language and component library.
- Responsibilities:
- UI components if needed. But mostly try to modify the theme file (packages/design_system/lib/src/ui_theme.dart) so we can directly use the theme in the app, to use the default material widgets.
- If not possible, and if that specific widget is used in multiple features, then try to create a shared widget in the
packages/design_system/widgets.
- If not possible, and if that specific widget is used in multiple features, then try to create a shared widget in the
- Theme definitions (Colors, Typography).
- Assets (Icons, Images).
- More details on how to use this package is available in the
docs/03-design-system-usage.md.
- UI components if needed. But mostly try to modify the theme file (packages/design_system/lib/src/ui_theme.dart) so we can directly use the theme in the app, to use the default material widgets.
- RESTRICTION:
- CANNOT change colours or typography.
- Dumb widgets only. NO business logic. NO state management (Bloc).
- More details on how to use this package is available in the
docs/03-design-system-usage.md.
2.6 Core (packages/core)
- Role: Cross-cutting concerns.
- Responsibilities:
- Extension methods.
- Logger configuration.
- Base classes for Use Cases or Result types (functional error handling).
3. Dependency Direction & Boundaries
- Domain Independence:
packages/domainknows NOTHING about the outer world. It defines what needs to be done, not how. - UI Agnosticism:
packages/featuresdepends onpackages/design_systemfor looks andpackages/domainfor logic. It does NOT know about Firebase. - Data Isolation:
packages/data_connectdepends onpackages/domainto know what interfaces to implement. It does NOT know about the UI.
4. Firebase Data Connect Strategy
Since Firebase Data Connect code does not yet exist, we adhere to a Strict Mocking Strategy:
- Interface First: All data requirements are first defined as
abstract interface class IRepositoryinpackages/domain. - Mock Implementation:
- Inside
packages/data_connect, create aMockRepositoryimplementation. - Use in-memory lists or hardcoded futures to simulate backend responses.
- CRITICAL: Do NOT put mocks in
test/folders if they are needed to run the app in "dev" mode. Put them inlib/src/mocks/.
- Inside
- Future Integration: When Data Connect is ready, we will add
RealRepositoryinpackages/data_connect. - Injection:
apps/will inject eitherMockRepositoryorRealRepositorybased on build flags or environment variables.
5. Feature Isolation
- Zero Direct Imports:
import 'package:feature_a/...'is FORBIDDEN insidepackage:feature_b. - Navigation: Use string-based routes or a shared route definition module in
core(if absolutely necessary) to navigate between features. - Data Sharing: Features do not share state directly. They share data via the underlying
Domainrepositories (e.g., both observe the sameUserstream fromAuthRepository).