agent-flutter 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/bin/agent-flutter.js +8 -0
- package/package.json +36 -0
- package/src/cli.js +494 -0
- package/templates/shared/.ignore +24 -0
- package/templates/shared/TEMPLATES.md +54 -0
- package/templates/shared/rules/document-workflow-function.md +98 -0
- package/templates/shared/rules/integration-api.md +3 -0
- package/templates/shared/rules/new-template-project.md +148 -0
- package/templates/shared/rules/ui.md +268 -0
- package/templates/shared/rules/unit-test.md +3 -0
- package/templates/shared/rules/widget-test.md +3 -0
- package/templates/shared/skills/dart-best-practices/SKILL.md +20 -0
- package/templates/shared/skills/dart-language-patterns/SKILL.md +47 -0
- package/templates/shared/skills/dart-model-reuse/SKILL.md +38 -0
- package/templates/shared/skills/dart-tooling-ci/SKILL.md +38 -0
- package/templates/shared/skills/flutter-assets-management/SKILL.md +78 -0
- package/templates/shared/skills/flutter-bloc-state-management/SKILL.md +48 -0
- package/templates/shared/skills/flutter-bloc-state-management/references/REFERENCE.md +19 -0
- package/templates/shared/skills/flutter-bloc-state-management/references/auth-bloc-example.md +96 -0
- package/templates/shared/skills/flutter-bloc-state-management/references/property-based-state.md +103 -0
- package/templates/shared/skills/flutter-dependency-injection-injectable/SKILL.md +64 -0
- package/templates/shared/skills/flutter-dependency-injection-injectable/references/REFERENCE.md +15 -0
- package/templates/shared/skills/flutter-dependency-injection-injectable/references/modules.md +42 -0
- package/templates/shared/skills/flutter-error-handling/SKILL.md +25 -0
- package/templates/shared/skills/flutter-error-handling/references/REFERENCE.md +38 -0
- package/templates/shared/skills/flutter-error-handling/references/error-mapping.md +44 -0
- package/templates/shared/skills/flutter-navigation-manager/SKILL.md +81 -0
- package/templates/shared/skills/flutter-navigation-manager/references/REFERENCE.md +71 -0
- package/templates/shared/skills/flutter-navigation-manager/references/router-config.md +57 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture/SKILL.md +89 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture/references/REFERENCE.md +19 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture/references/folder-structure.md +35 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture/references/modular-injection.md +27 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture/references/shared-core.md +29 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture-dependency-rules/SKILL.md +58 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture-dependency-rules/references/REFERENCE.md +113 -0
- package/templates/shared/skills/flutter-standard-lib-src-architecture-dependency-rules/references/repository-mapping.md +48 -0
- package/templates/shared/skills/flutter-ui-widgets/SKILL.md +152 -0
- package/templates/shared/skills/getx-localization-standard/SKILL.md +101 -0
- package/templates/shared/skills/getx-localization-standard/references/new-page-localization.example.md +61 -0
- package/templates/shared/skills/ui-documentation-workflow/SKILL.md +55 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
---
|
|
4
|
+
# AI Documentation Workflow (Function)
|
|
5
|
+
|
|
6
|
+
## **Goal**
|
|
7
|
+
To automatically generate and maintain detailed functional documentation in `spec/function-workflow.md`. This documentation bridges the gap between the high-level UI flow (from `ui-workflow.md`) and the technical implementation, focusing on **API integrations, Data Transformations, and State Management logic**.
|
|
8
|
+
|
|
9
|
+
## **Trigger**
|
|
10
|
+
This workflow is triggered when:
|
|
11
|
+
1. The `spec/ui-workflow.md` has been updated (Prerequisite).
|
|
12
|
+
2. Backend integration (API) is implemented for a feature.
|
|
13
|
+
3. Complex business logic is added (e.g., data validation, caching, error handling).
|
|
14
|
+
4. The user requests: "Update function workflow for [feature]".
|
|
15
|
+
|
|
16
|
+
## **Workflow Steps**
|
|
17
|
+
|
|
18
|
+
### **Step 1: Analyze the Implementation**
|
|
19
|
+
- **Input**: The feature folder (`lib/src/ui/<feature>`) and `spec/ui-workflow.md`.
|
|
20
|
+
- **Action**: Deep dive into the following files:
|
|
21
|
+
- `bloc/*_bloc.dart`: Identify Events, States, and Side Effects.
|
|
22
|
+
- `repository/*_repository.dart`: Identify API endpoints, Request/Response models.
|
|
23
|
+
- `model/*`: Analyze data structures.
|
|
24
|
+
- `core/managers/*`: Check for global state usage (e.g., Auth, Permission).
|
|
25
|
+
|
|
26
|
+
### **Step 2: Format the Documentation**
|
|
27
|
+
- **Output File**: `spec/function-workflow.md`
|
|
28
|
+
- **Format**: Append (or Update) a section for EACH feature using the following template:
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
## [Feature Name] (e.g., Login)
|
|
32
|
+
**Ref UI**: [Link to UI Spec Section]
|
|
33
|
+
|
|
34
|
+
### **1. Data Model**
|
|
35
|
+
**Request**: `LoginRequest`
|
|
36
|
+
- `email` (String): Required, valid email format.
|
|
37
|
+
- `password` (String): Required, min 6 chars.
|
|
38
|
+
|
|
39
|
+
**Response**: `LoginResponse`
|
|
40
|
+
- `token` (String): JWT Token.
|
|
41
|
+
- `user` (UserDto): User profile info.
|
|
42
|
+
|
|
43
|
+
### **2. State Management (BLoC)**
|
|
44
|
+
**Events**:
|
|
45
|
+
- `LoginEvent(email, password)`: Triggers the login process.
|
|
46
|
+
- `LoginReset()`: Resets state to initial.
|
|
47
|
+
|
|
48
|
+
**States**:
|
|
49
|
+
- `LoginInitial`: Form inputs enabled.
|
|
50
|
+
- `LoginLoading`: Inputs disabled, loading spinner active.
|
|
51
|
+
- `LoginSuccess(user)`: Navigation trigger.
|
|
52
|
+
- `LoginFailure(error)`: Error message display.
|
|
53
|
+
|
|
54
|
+
### **3. Functional Logic**
|
|
55
|
+
1. **Validation**:
|
|
56
|
+
- Check `email` via Regex.
|
|
57
|
+
- Check `password.length >= 6`.
|
|
58
|
+
- *If invalid*: Emit `LoginFailure(ValidationError)`.
|
|
59
|
+
|
|
60
|
+
2. **API Call**:
|
|
61
|
+
- Call `AuthRepository.login(request)`.
|
|
62
|
+
- **Endpoint**: `POST /api/v1/auth/login`
|
|
63
|
+
- **Headers**: `Content-Type: application/json`
|
|
64
|
+
|
|
65
|
+
3. **Error Handling**:
|
|
66
|
+
- **401 Unauthorized**: "Incorrect credentials".
|
|
67
|
+
- **500 Server Error**: "System error, try again".
|
|
68
|
+
- **Network Error**: "Check connection".
|
|
69
|
+
|
|
70
|
+
4. **Post-Process**:
|
|
71
|
+
- Save `token` to `SecureStorage`.
|
|
72
|
+
- Update `UserManager.currentUser`.
|
|
73
|
+
- Emit `LoginSuccess`.
|
|
74
|
+
|
|
75
|
+
### **4. Dependencies & Services**
|
|
76
|
+
- `AuthRepository`: API communication.
|
|
77
|
+
- `SecureStorage`: Token persistence.
|
|
78
|
+
- `UserManager`: Global user state.
|
|
79
|
+
|
|
80
|
+
### **5. Technical Debt / Optimization**
|
|
81
|
+
- [ ] Add rate limiting on login attempts.
|
|
82
|
+
- [ ] Cache last used email for convenience.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### **Step 3: Verification**
|
|
86
|
+
- **Consistency Check**: Ensure the "Functional Logic" aligns with the "User Flow" in `spec/ui-workflow.md`.
|
|
87
|
+
- **API Check**: Verify that the documented Endpoint and Request/Response models match the actual code in `Repository` and `Retrofit` clients.
|
|
88
|
+
- **Edge Cases**: Ensure error handling (Network, Validation, Server) is documented.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## **Prompt for AI**
|
|
93
|
+
|
|
94
|
+
### **Case 1: Single Feature**
|
|
95
|
+
> "Analyze `lib/src/ui/<feature>` and update `spec/function-workflow.md` based on the UI spec."
|
|
96
|
+
|
|
97
|
+
### **Case 2: Sync with UI Spec**
|
|
98
|
+
> "Read `spec/ui-workflow.md` and generate the corresponding functional specs in `spec/function-workflow.md`."
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
---
|
|
4
|
+
# Template Project Creation Workflow
|
|
5
|
+
|
|
6
|
+
This workflow describes the step-by-step process to generate a new Flutter project that matches the architecture and standards of the current codebase.
|
|
7
|
+
|
|
8
|
+
## 1. Project Initialization (FVM)
|
|
9
|
+
|
|
10
|
+
### 1.1 FVM Setup & Create Project
|
|
11
|
+
Use FVM (Flutter Version Management) to ensure consistent Flutter versions.
|
|
12
|
+
|
|
13
|
+
1. **Install FVM** (if needed):
|
|
14
|
+
```bash
|
|
15
|
+
dart pub global activate fvm
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. **Initialize & Create Project**:
|
|
19
|
+
```bash
|
|
20
|
+
mkdir project_name
|
|
21
|
+
cd project_name
|
|
22
|
+
|
|
23
|
+
# Initialize FVM with specific version (e.g., 3.38.5)
|
|
24
|
+
fvm use 3.38.5 --force
|
|
25
|
+
|
|
26
|
+
# Create project using FVM version
|
|
27
|
+
fvm flutter create . --org com.example
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 1.2 IDE Configuration (VS Code)
|
|
31
|
+
Create/Update `.vscode/settings.json` to use the FVM version:
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"dart.flutterSdkPath": ".fvm/flutter_sdk",
|
|
35
|
+
"search.exclude": {
|
|
36
|
+
"**/.fvm": true
|
|
37
|
+
},
|
|
38
|
+
"files.watcherExclude": {
|
|
39
|
+
"**/.fvm": true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 1.3 Update `pubspec.yaml`
|
|
45
|
+
Add the standard dependencies required for the project architecture.
|
|
46
|
+
|
|
47
|
+
**Core Dependencies:**
|
|
48
|
+
- `get`: ^4.6.x (Routing & DI)
|
|
49
|
+
- `flutter_bloc`: ^8.x.x (State Management)
|
|
50
|
+
- `equatable`: ^2.x.x
|
|
51
|
+
- `dio`: ^5.x.x (Network)
|
|
52
|
+
- `retrofit`: ^4.x.x (API Client)
|
|
53
|
+
- `json_annotation`: ^4.x.x
|
|
54
|
+
- `flutter_dotenv`: (Environment variables)
|
|
55
|
+
- `flutter_svg`: (SVG support)
|
|
56
|
+
- `intl`: (Formatting)
|
|
57
|
+
|
|
58
|
+
**Dev Dependencies:**
|
|
59
|
+
- `build_runner`: (Code generation)
|
|
60
|
+
- `retrofit_generator`:
|
|
61
|
+
- `json_serializable`:
|
|
62
|
+
|
|
63
|
+
## 2. Directory Structure Scaffolding
|
|
64
|
+
|
|
65
|
+
Remove the default `lib/main.dart` and create the following directory structure under `lib/src/`:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
lib/
|
|
69
|
+
main.dart
|
|
70
|
+
src/
|
|
71
|
+
api/ # Retrofit API clients & interceptors
|
|
72
|
+
core/
|
|
73
|
+
managers/ # System managers (Permission, Connectivity)
|
|
74
|
+
model/ # Data models (Request/Response)
|
|
75
|
+
repository/ # Data repositories
|
|
76
|
+
di/ # Dependency Injection setup
|
|
77
|
+
enums/ # App-wide enums
|
|
78
|
+
extensions/ # Dart extensions (Theme, Color, String)
|
|
79
|
+
helper/ # Utils helpers (Validation, Logger)
|
|
80
|
+
locale/ # Localization (TranslationManager)
|
|
81
|
+
ui/ # Feature modules
|
|
82
|
+
base/ # Base classes (BasePage, BaseViewModel)
|
|
83
|
+
main/ # Root/Shell Page (BottomNav)
|
|
84
|
+
home/ # Home Feature
|
|
85
|
+
widgets/ # Shared UI components (AppInput, AppButton)
|
|
86
|
+
routing/ # Per-tab Routers
|
|
87
|
+
utils/ # Constants, Colors, Styles, Assets
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 3. Core Module Setup
|
|
91
|
+
|
|
92
|
+
### 3.1 Dependency Injection (`lib/src/di/`)
|
|
93
|
+
Create `di_graph_setup.dart` to initialize core services before the app starts.
|
|
94
|
+
- **Components**:
|
|
95
|
+
- `EnvironmentModule`: Load `.env` config.
|
|
96
|
+
- `NetworkModule`: Setup Dio client.
|
|
97
|
+
- `RepositoryModule`: Register Repositories.
|
|
98
|
+
- `ManagerModule`: Register Global Managers.
|
|
99
|
+
|
|
100
|
+
### 3.2 Utilities (`lib/src/utils/`)
|
|
101
|
+
Create placeholder files for design system constants:
|
|
102
|
+
- `app_colors.dart`: Define `AppColors` class.
|
|
103
|
+
- `app_styles.dart`: Define `AppStyles` class.
|
|
104
|
+
- `app_assets.dart`: Define `AppAssets` class.
|
|
105
|
+
- `app_pages.dart`: Define `AppPages` (GetX Route definition).
|
|
106
|
+
|
|
107
|
+
### 3.3 Localization (`lib/src/locale/`)
|
|
108
|
+
Implement `TranslationManager` extending `Translations` from GetX.
|
|
109
|
+
|
|
110
|
+
## 4. App Entry Point (`main.dart`)
|
|
111
|
+
|
|
112
|
+
Configure `main.dart` to:
|
|
113
|
+
1. Load Environment variables (`dotenv`).
|
|
114
|
+
2. Initialize Dependencies (`setupDependenciesGraph()`).
|
|
115
|
+
3. Run `GetMaterialApp` with:
|
|
116
|
+
- `initialRoute`: `AppPages.main`
|
|
117
|
+
- `getPages`: `AppPages.pages`
|
|
118
|
+
- `theme`: Custom Theme.
|
|
119
|
+
|
|
120
|
+
## 5. Main Shell Implementation (Bottom Navigation)
|
|
121
|
+
|
|
122
|
+
Follow the guide in `create-bottombar.md` to implement the root navigation shell.
|
|
123
|
+
|
|
124
|
+
1. **Enums**: Create `BottomNavigationPage` enum in `lib/src/enums/`.
|
|
125
|
+
2. **Bloc**: Create `MainBloc` in `lib/src/ui/main/bloc/` to manage tab state.
|
|
126
|
+
3. **UI**: Create `MainPage` using `IndexedStack` and `CupertinoTabView` for nested navigation.
|
|
127
|
+
4. **Widget**: Create `AppBottomNavigationBar`.
|
|
128
|
+
|
|
129
|
+
## 6. Base Feature Creation (Home)
|
|
130
|
+
|
|
131
|
+
Create a standard "Home" feature to verify the setup:
|
|
132
|
+
1. **Folder**: `lib/src/ui/home/`.
|
|
133
|
+
2. **Files**:
|
|
134
|
+
- `home_page.dart`: The UI.
|
|
135
|
+
- `bloc/home_bloc.dart`: The Logic.
|
|
136
|
+
- `binding/home_binding.dart`: DI for the module.
|
|
137
|
+
3. **Routing**:
|
|
138
|
+
- Add `HomeRouter` in `lib/src/ui/routing/`.
|
|
139
|
+
- Register in `AppPages`.
|
|
140
|
+
|
|
141
|
+
## 7. Environment Setup
|
|
142
|
+
|
|
143
|
+
Create root-level environment files:
|
|
144
|
+
- `.env`
|
|
145
|
+
- `.env.staging`
|
|
146
|
+
- `.env.prod`
|
|
147
|
+
|
|
148
|
+
Add `.env*` to `.gitignore`.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
---
|
|
4
|
+
# UI Development Rules & Workflow
|
|
5
|
+
|
|
6
|
+
## **1. Core Principles (Priority P1)**
|
|
7
|
+
|
|
8
|
+
### **0. Design Tokens (STRICT)**
|
|
9
|
+
- **Typography**: 1–1 mapping from Figma. Use `AppStyles`; `height = lineHeight / fontSize`. Bundle the exact font family/weight as in Figma.
|
|
10
|
+
- **Colors**: Use `AppColors`. Do not use hex/raw colors (`Color(0xFF...)`, `Colors.red`).
|
|
11
|
+
- **Spacing**: Use `int_extensions` and `AppDimensions`. Do not use arbitrary numeric padding/margin outside tokens.
|
|
12
|
+
- **Numeric Tokens**: Preserve numeric values from Figma for all properties (radius, spacing, border width, shadow blur/spread, font size, line-height, letter-spacing…). Do not round or force presets. If defaults differ, override locally or update tokens per design.
|
|
13
|
+
- **Icon Size**: Icon 24×24; container 44×44 when required by Figma; use `AppAssets`.
|
|
14
|
+
- **Shadows**: Normalize `BoxShadow` closest to CSS box-shadow; do not change blur/spread arbitrarily.
|
|
15
|
+
- **Backgrounds**: Use `DecorationImage` + appropriate `BoxFit` (cover/contain) and correct alignment.
|
|
16
|
+
|
|
17
|
+
### **Overrides (Per-Component)**
|
|
18
|
+
- App* widgets must allow overriding tokens: `size`, `radius`, `padding/margin`, `backgroundColor`, `textStyle`, `iconSize`, `constraints`.
|
|
19
|
+
- Defaults must come from tokens (`AppStyles`, `AppColors`, `AppDimensions`) and act only as fallbacks; do not hardcode.
|
|
20
|
+
- When overriding numeric tokens, preserve Figma values (radius/spacing/border/shadow/typography); do not round or force presets.
|
|
21
|
+
|
|
22
|
+
### **Icon Consistency & Deduplication**
|
|
23
|
+
- **Single Source**: Each icon has one SVG file and one constant in `AppAssets`.
|
|
24
|
+
- **No Duplicates**: Do not add different filenames with identical graphics.
|
|
25
|
+
- **Workflow**:
|
|
26
|
+
- Normalize SVG (remove metadata, sort attributes, flatten stroke→fill, remove masks/filters if unnecessary).
|
|
27
|
+
- Compute content hash after normalization; if duplicates → consolidate to one file and update references.
|
|
28
|
+
- Variants (color/size/solid/outline) must be clearly named and considered different when geometry/semantics differ.
|
|
29
|
+
- **CI/Pre-commit**: Recommended duplicate check for `assets/images/icons/`; fail on duplicates.
|
|
30
|
+
|
|
31
|
+
### **Temporary Policy (Icons)**
|
|
32
|
+
- Current phase: **each screen adds its own icons**, do not reuse icons across screens. Name by screen to avoid confusion. Policy will be updated when moving to project-wide reuse.
|
|
33
|
+
|
|
34
|
+
### **SVG Color Handling**
|
|
35
|
+
- **Default**: Do not use `color`/`colorFilter` when the SVG already has correct Figma colors.
|
|
36
|
+
- **Allowed**: Only apply `color`/`colorFilter` when design requires recolor (active/inactive…) and the icon is flattened stroke→fill.
|
|
37
|
+
- **Prohibited**: Avoid `colorFilter` for multi-color SVGs; it easily causes color shifts on render.
|
|
38
|
+
### **A. Widget Standardization (App* Prefix)**
|
|
39
|
+
- **Rule**: ALWAYS check `lib/src/ui/widgets/` first.
|
|
40
|
+
- **Convention**: Shared widgets MUST use the `App` prefix.
|
|
41
|
+
- **Usage**:
|
|
42
|
+
- `AppInput` instead of `TextField`.
|
|
43
|
+
- `AppButtonBar` instead of `IconButton` (for back/actions).
|
|
44
|
+
- `AppButton` instead of `ElevatedButton`.
|
|
45
|
+
- `AppTextGradient` instead of `Text` (when gradient needed).
|
|
46
|
+
- `AppCardSection` for container groupings.
|
|
47
|
+
|
|
48
|
+
### **B. Styling Source of Truth**
|
|
49
|
+
- **Colors**: NEVER hardcode hex codes or `Colors.red`. Use `AppColors` from `lib/src/utils/app_colors.dart`.
|
|
50
|
+
- **Typography**: Use `AppStyles` from `lib/src/utils/app_styles.dart`.
|
|
51
|
+
- **Example**:
|
|
52
|
+
```dart
|
|
53
|
+
// ✅ Correct
|
|
54
|
+
Text('Title', style: AppStyles.h1.copyWith(color: AppColors.primary));
|
|
55
|
+
|
|
56
|
+
// ❌ Incorrect
|
|
57
|
+
Text('Title', style: TextStyle(fontSize: 20, color: Colors.blue));
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### **C. Localization (Priority P1)**
|
|
61
|
+
- **No Raw Strings**: All user-facing text MUST be localized.
|
|
62
|
+
- **Implementation**:
|
|
63
|
+
- Add keys to `lib/src/locale/locale_key.dart` (snake_case: `feature_screen_element`).
|
|
64
|
+
- Update **ALL** translation files (`lib/src/locale/lang_en.dart`, `lib/src/locale/lang_ja.dart`). Optional modularization by feature:
|
|
65
|
+
- `lib/src/locale/en/<feature>.dart`
|
|
66
|
+
- `lib/src/locale/ja/<feature>.dart`
|
|
67
|
+
- Aggregators `lang_en.dart` / `lang_ja.dart` merge feature maps to reduce conflicts when multiple tasks add keys while keeping `enUs` / `jaJp`.
|
|
68
|
+
- **Usage**: Use `.tr` extension.
|
|
69
|
+
- **Integration**: `lib/src/locale/translation_manager.dart` consumes `enUs` and `jaJp`. **Do not rename** these variables in aggregators.
|
|
70
|
+
- **Common Keys**:
|
|
71
|
+
- Create common modules: `lib/src/core/localization/en/common.dart` and `ja/common.dart`.
|
|
72
|
+
- Use `common_*` keys for widespread phrases (Save/Cancel/OK/Back/Next/Loading/Error/Retry…).
|
|
73
|
+
- When text matches common, **reuse** the common key instead of creating a feature key.
|
|
74
|
+
```dart
|
|
75
|
+
// ✅ Correct
|
|
76
|
+
Text(LocaleKey.home_title.tr);
|
|
77
|
+
|
|
78
|
+
// ❌ Incorrect
|
|
79
|
+
Text('Home');
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### **D. Data Model Layer (Priority P1)**
|
|
83
|
+
- **Separation of Concerns**: Request and Response models MUST be separated.
|
|
84
|
+
- **Folder Structure**:
|
|
85
|
+
- `lib/src/core/model/request/`: Models sent **TO** the API (e.g., `LoginRequest`).
|
|
86
|
+
- `lib/src/core/model/response/`: Models received **FROM** the API (e.g., `LoginResponse`).
|
|
87
|
+
- `lib/src/core/model/`: UI/domain models (e.g., `NotificationModel`, `CalendarEventModel`, `WorkDetailRecord`).
|
|
88
|
+
- **Implementation**:
|
|
89
|
+
- Do NOT mix UI logic in models.
|
|
90
|
+
- Use `factory .fromJson` and `Map toJson` when applicable.
|
|
91
|
+
- **No dynamic data in UI**: Pages/components MUST receive typed models via constructor/BLoC state; do not hardcode demo lists in widgets.
|
|
92
|
+
- **Demo/Mock Data Location**: Keep all demo/sample data in `lib/src/utils/app_demo_data.dart` only. Import from there when previewing or testing UI.
|
|
93
|
+
- **Reuse-first**: Before creating a new model, check the [Model Registry](../../spec/model-registry.md) and follow [Dart Model Reuse Skill](../skills/dart-model-reuse/SKILL.md). Prefer extending existing models (optional fields) or composition over duplication.
|
|
94
|
+
|
|
95
|
+
### **E. Composition & State**
|
|
96
|
+
- **State**: Default to `StatelessWidget`. Use `StatefulWidget` only for local UI logic (animations, focus).
|
|
97
|
+
- **Encapsulation**: "Smart Components" should handle their own internal state (e.g., `AppInput` handles password visibility toggle).
|
|
98
|
+
- **Layout**: Use `Flex` (Column/Row) + int extensions (`n.height`/`n.width`) for spacing. Avoid `Padding` for simple gaps.
|
|
99
|
+
|
|
100
|
+
### **F. Assets Management (Priority P1)**
|
|
101
|
+
- **Rule**: Follow the [Assets Management Skill](../skills/flutter-assets-management/SKILL.md) strictly.
|
|
102
|
+
- **Naming**: MUST match Figma layer names in `snake_case`.
|
|
103
|
+
- **Registry**: All assets MUST be defined in `lib/src/utils/app_assets.dart`.
|
|
104
|
+
- **Usage**:
|
|
105
|
+
```dart
|
|
106
|
+
// ✅ Correct
|
|
107
|
+
SvgPicture.asset(AppAssets.icons_home_active_svg);
|
|
108
|
+
|
|
109
|
+
// ❌ Incorrect
|
|
110
|
+
SvgPicture.asset('assets/images/icons/home_active.svg');
|
|
111
|
+
```
|
|
112
|
+
- **Workflow**:
|
|
113
|
+
1. Rename layer in Figma to `snake_case`.
|
|
114
|
+
2. Export to `assets/images/` or `assets/icons/`.
|
|
115
|
+
3. Register path in `AppAssets`.
|
|
116
|
+
4. Use `AppAssets.name` in code.
|
|
117
|
+
- **SVG Hygiene (Priority P1)**:
|
|
118
|
+
- Flatten stroke → fill để tint/recolor an toàn.
|
|
119
|
+
- Remove mask/clip/filter phức tạp; đảm bảo `viewBox` 24×24 cho icon.
|
|
120
|
+
- Kiểm tra render qua `SvgPicture.asset` trong container 44×44, icon 24×24.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## **2. Standard Page Architecture**
|
|
125
|
+
|
|
126
|
+
Every page must follow this folder structure under `lib/src/ui/`:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
lib/src/ui/<page_name>/
|
|
130
|
+
├── binding/
|
|
131
|
+
│ └── <page_name>_binding.dart # Dependency Injection
|
|
132
|
+
├── interactor/
|
|
133
|
+
│ └── <page_name>_bloc.dart # Logic & State (GetX Controller or Bloc)
|
|
134
|
+
├── components/
|
|
135
|
+
│ ├── <page_name>_header.dart # Local UI parts
|
|
136
|
+
│ └── <page_name>_form.dart
|
|
137
|
+
└── <page_name>_page.dart # Main Entry Point
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## **3. New Page Creation Workflow**
|
|
143
|
+
|
|
144
|
+
Follow these steps when creating a new UI screen:
|
|
145
|
+
|
|
146
|
+
### **Step 1: Preparation**
|
|
147
|
+
- Check Figma/Design.
|
|
148
|
+
- Identify reusable components -> Are they in `lib/src/ui/widgets`?
|
|
149
|
+
- Identify unique components -> Plan to put them in `components/`.
|
|
150
|
+
|
|
151
|
+
### **Step 2: Scaffolding**
|
|
152
|
+
- Create the folder structure (See [Lib Src Architecture Skill](../skills/flutter-standard-lib-src-architecture/SKILL.md)):
|
|
153
|
+
```bash
|
|
154
|
+
mkdir -p lib/src/ui/my_new_feature/{binding,interactor,components}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### **Step 3: Data Modeling (If API involved)**
|
|
158
|
+
- Create Request model in `lib/src/core/model/request/`.
|
|
159
|
+
- Create Response model in `lib/src/core/model/response/`.
|
|
160
|
+
|
|
161
|
+
### **Step 4: Logic & Binding**
|
|
162
|
+
- Create the Controller/Bloc in `interactor/` (See [Bloc Skill](../skills/flutter-bloc-state-management/SKILL.md)).
|
|
163
|
+
- Create the Binding in `binding/` to inject the controller.
|
|
164
|
+
|
|
165
|
+
### **Step 5: Localization**
|
|
166
|
+
- **Identify Strings**: List all text in the new UI (See [GetX Localization Skill](../skills/getx-localization-standard/SKILL.md)).
|
|
167
|
+
- **Update Keys**: Add entries to `locale_key.dart` (e.g., `my_feature_title`).
|
|
168
|
+
- **Update Translations**: Add translations to `lang_en.dart`, `lang_ja.dart`.
|
|
169
|
+
|
|
170
|
+
### **Step 6: Main Page Implementation**
|
|
171
|
+
- Create `<page_name>_page.dart` (See [UI Widgets Skill](../skills/flutter-ui-widgets/SKILL.md)).
|
|
172
|
+
- Use `AppScaffold` (if available) or standard `Scaffold`.
|
|
173
|
+
- **Import Rules**:
|
|
174
|
+
- Use `AppColors` / `AppStyles`.
|
|
175
|
+
- Use `App*` widgets.
|
|
176
|
+
- Use `LocaleKey.my_key.tr` for text.
|
|
177
|
+
- **Radius & Icon**:
|
|
178
|
+
- If Figma requires radius = 14, **must** use `BorderRadius.circular(14)` at the corresponding component.
|
|
179
|
+
- Icon 24×24; if framed, use container 40×40/44×44 per Figma.
|
|
180
|
+
- **Documentation Comments (STRICT)**:
|
|
181
|
+
- Add top-of-class `///` description for every Page and Component, summarizing its purpose and main actions.
|
|
182
|
+
- Generator reads these docs to build `spec/ui-workflow.md` (run `dart run tool/generate_ui_workflow_spec.dart`).
|
|
183
|
+
- Example:
|
|
184
|
+
```dart
|
|
185
|
+
/// CustomerDetailPage: Shows overview, cases, and inspection history for a customer.
|
|
186
|
+
class CustomerDetailPage extends StatelessWidget { ... }
|
|
187
|
+
|
|
188
|
+
/// CustomerDetailHeader: Displays customer status badges and next schedule.
|
|
189
|
+
class CustomerDetailHeader extends StatelessWidget { ... }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### **Step 7: Component Extraction**
|
|
193
|
+
- **Rule**: If a widget block is > 50 lines or reused twice, extract it to `components/` (See [Idiomatic Flutter Skill](../skills/idiomatic-flutter/SKILL.md)).
|
|
194
|
+
- Keep the main `build()` method clean and readable.
|
|
195
|
+
|
|
196
|
+
### **Step 8: Route Registration (Choose One)**
|
|
197
|
+
- See [Navigation Manager Skill](../skills/flutter-navigation-manager/SKILL.md).
|
|
198
|
+
- **Scenario A: Full Screen Page (Hides Bottom Bar)**
|
|
199
|
+
- Register in `lib/src/utils/app_pages.dart`.
|
|
200
|
+
- Use `Get.toNamed(AppPages.myFeature)`.
|
|
201
|
+
- **Scenario B: Nested Page (Keeps Bottom Bar Visible)**
|
|
202
|
+
- Register in `lib/src/ui/routing/<feature>_router.dart` (e.g., `home_router.dart`).
|
|
203
|
+
- Corresponds to the active tab (Home, Customer, etc.).
|
|
204
|
+
- **Scenario C: Common Shared Page (Accessible from ANY Tab)**
|
|
205
|
+
- Register in `lib/src/ui/routing/common_router.dart`.
|
|
206
|
+
- Used for shared screens like Notification, Privacy Policy, etc. that keep the Bottom Bar visible.
|
|
207
|
+
|
|
208
|
+
### **Step 9: Widget Preview (Priority P1)**
|
|
209
|
+
- **Requirement**: Every page and complex component MUST have a `@Preview` annotation for quick iteration.
|
|
210
|
+
- **Setup**:
|
|
211
|
+
1. Import `package:flutter/widget_previews.dart`.
|
|
212
|
+
2. Create a helper class `PreviewTranslations` to map localization keys.
|
|
213
|
+
3. Create a public top-level function annotated with `@Preview`.
|
|
214
|
+
4. Wrap the widget in `GetMaterialApp` to provide context, localization, and DI.
|
|
215
|
+
- **Template**:
|
|
216
|
+
```dart
|
|
217
|
+
import 'package:flutter/widget_previews.dart';
|
|
218
|
+
import 'package:link_home/src/locale/lang_en.dart';
|
|
219
|
+
import 'package:link_home/src/locale/lang_ja.dart';
|
|
220
|
+
|
|
221
|
+
// ... (Page Code) ...
|
|
222
|
+
|
|
223
|
+
class PreviewTranslations extends Translations {
|
|
224
|
+
@override
|
|
225
|
+
Map<String, Map<String, String>> get keys => {
|
|
226
|
+
'en_US': enUs,
|
|
227
|
+
'ja_JP': jaJp,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
@Preview(
|
|
232
|
+
size: Size(390, 844), // iPhone 12 Standard
|
|
233
|
+
)
|
|
234
|
+
Widget previewPageName() {
|
|
235
|
+
// Inject Dependencies if needed
|
|
236
|
+
if (!Get.isRegistered<PageBloc>()) {
|
|
237
|
+
Get.put(PageBloc());
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return GetMaterialApp(
|
|
241
|
+
debugShowCheckedModeBanner: false,
|
|
242
|
+
useInheritedMediaQuery: true, // MUST be true for correct sizing
|
|
243
|
+
translations: PreviewTranslations(),
|
|
244
|
+
locale: const Locale('ja', 'JP'), // Default Preview Locale
|
|
245
|
+
fallbackLocale: const Locale('en', 'US'),
|
|
246
|
+
home: const PageName(),
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## **4. Checklist Before PR**
|
|
254
|
+
- [ ] No hardcoded colors/styles?
|
|
255
|
+
- [ ] No raw strings? (Localization used)
|
|
256
|
+
- [ ] Used `App*` widgets where possible?
|
|
257
|
+
- [ ] Page broken down into `components/`?
|
|
258
|
+
- [ ] Logic separated into `interactor/`?
|
|
259
|
+
- [ ] **Data Models Separated?** (Request/Response in `core/model/`)
|
|
260
|
+
- [ ] File naming matches `<feature>_<type>.dart`?
|
|
261
|
+
- [ ] **Route Registered?**
|
|
262
|
+
- [ ] If Full Screen: Added to `AppPages`?
|
|
263
|
+
- [ ] If Nested: Added to `ui/routing/<tab>_router.dart`?
|
|
264
|
+
- [ ] If Shared: Added to `ui/routing/common_router.dart`?
|
|
265
|
+
- [ ] **Widget Preview Added?** (`@Preview` with correct `Size` and `GetMaterialApp` wrapper)
|
|
266
|
+
- [ ] **Design Tokens Applied?** (Typography/Colors/Spacing match Figma)
|
|
267
|
+
- [ ] **Radius preserved from Figma?** (e.g., r14 at relevant components)
|
|
268
|
+
- [ ] **SVG Hygiene OK?** (viewBox 24×24, tintable, no complex masks/filters)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Dart Best Practices
|
|
3
|
+
description: General purity standards for Dart development.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dart Best Practices
|
|
7
|
+
|
|
8
|
+
## **Priority: P1**
|
|
9
|
+
|
|
10
|
+
- **Scoping**:
|
|
11
|
+
- No global variables.
|
|
12
|
+
- Private globals (if required) must start with `_`.
|
|
13
|
+
- **Immutability**: Use `const` > `final` > `var`.
|
|
14
|
+
- **Config**: Use `--dart-define` for secrets. Never hardcode API keys.
|
|
15
|
+
- **Naming**: Follow [effective-dart](https://dart.dev/guides/language/effective-dart) (PascalCase classes, camelCase members).
|
|
16
|
+
|
|
17
|
+
```dart
|
|
18
|
+
import 'models/user.dart'; // Good
|
|
19
|
+
import 'package:app/models/user.dart'; // Avoid local absolute
|
|
20
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Dart Language Patterns
|
|
3
|
+
description: Modern Dart standards (3.x+) including null safety and patterns.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dart Language Patterns
|
|
7
|
+
|
|
8
|
+
## **Priority: P0 (CRITICAL)**
|
|
9
|
+
|
|
10
|
+
Modern Dart standards for safety, performance, and readability.
|
|
11
|
+
|
|
12
|
+
## Implementation Guidelines
|
|
13
|
+
|
|
14
|
+
- **Null Safety**: Avoid `!`. Use `?.`, `??`, or short-circuiting. Use `late` only if necessary.
|
|
15
|
+
- **Immutability**: Use `final` for all variables. Prefer plain immutable classes with `const` constructors; use `Equatable` only when value equality is needed.
|
|
16
|
+
- **Pattern Matching (3.x)**: Use `switch (value)` with patterns and destructuring.
|
|
17
|
+
- **Records**: Use Records (e.g., `(String, int)`) for returning multiple values.
|
|
18
|
+
- **Sealed Classes**: Use `sealed class` for exhaustive state handling in domain logic.
|
|
19
|
+
- **Extensions**: Use `extension` to add utility methods to third-party types.
|
|
20
|
+
- **Wildcards (3.7+)**: Use `_` for unused variables in declarations and patterns.
|
|
21
|
+
- **Tear-offs**: Prefer using tear-offs (e.g., `list.forEach(print)`) over anonymous lambdas (e.g., `list.forEach((e) => print(e))`).
|
|
22
|
+
- **Asynchrony**: Prefer `async/await` over raw `Future.then`. Use `unawaited` for fire-and-forget logic if necessary.
|
|
23
|
+
- **Collections**: Use `collection-if`, `collection-for`, and spread operators `...`.
|
|
24
|
+
|
|
25
|
+
## Anti-Patterns
|
|
26
|
+
|
|
27
|
+
- **No ! Operator**: Do not use the bang operator `!` unless you can prove the value is non-null via `if` or `assert`.
|
|
28
|
+
- **No var for members**: Do not use `var` for class members; use `final` or explicit types.
|
|
29
|
+
- **No logic in constructors**: Do not perform complex calculations or async work inside constructors.
|
|
30
|
+
|
|
31
|
+
## Code
|
|
32
|
+
|
|
33
|
+
```dart
|
|
34
|
+
// Sealed class and Switch expression
|
|
35
|
+
sealed class Result {}
|
|
36
|
+
class Success extends Result { final String data; Success(this.data); }
|
|
37
|
+
class Failure extends Result {}
|
|
38
|
+
|
|
39
|
+
String message(Result r) => switch (r) {
|
|
40
|
+
Success(data: var d) => "Got $d",
|
|
41
|
+
Failure() => "Error",
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Related Topics
|
|
46
|
+
|
|
47
|
+
feature-based-clean-architecture | tooling
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Dart Model Reuse & Evolution"
|
|
3
|
+
description: "Guides model reuse/composition and safe extension. Invoke when adding/updating UI/domain models or preventing duplicate screen-specific models."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dart Model Reuse & Evolution
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
Prevent duplicate models across features and keep UI data strongly typed. Reuse existing models where possible; evolve them safely when needed.
|
|
10
|
+
|
|
11
|
+
## Where Models Live
|
|
12
|
+
- Request: `lib/src/core/model/request/`
|
|
13
|
+
- Response: `lib/src/core/model/response/`
|
|
14
|
+
- UI/Domain: `lib/src/core/model/`
|
|
15
|
+
- Demo/Mock Data: `lib/src/utils/app_demo_data.dart` (only)
|
|
16
|
+
|
|
17
|
+
## Reuse-first Policy
|
|
18
|
+
- Before adding a new model:
|
|
19
|
+
- Check the Model Registry: `spec/model-registry.md` for existing shared models and their purposes.
|
|
20
|
+
- Also check `lib/src/core/model/` for an existing model with overlapping fields.
|
|
21
|
+
- Prefer reuse if ≥70% fields overlap and semantics match.
|
|
22
|
+
- If needed, add optional fields to the existing model (keep backward compatibility).
|
|
23
|
+
- If semantics differ, compose: nest existing model rather than duplicating fields.
|
|
24
|
+
|
|
25
|
+
## Evolution Rules
|
|
26
|
+
- Additive changes only on active branches (append fields, keep constructors compatible).
|
|
27
|
+
- Use optional fields (`Type?`) and sensible defaults to avoid breaking code.
|
|
28
|
+
- Keep `fromJson`/`toJson` aligned when applicable.
|
|
29
|
+
|
|
30
|
+
## Naming & Ownership
|
|
31
|
+
- Names must reflect domain, not screens (`CustomerProjectInfo`, not `CustomerProjectListItem`).
|
|
32
|
+
- Shared models are owned at `lib/src/core/model/`; screens cannot fork them.
|
|
33
|
+
|
|
34
|
+
## Checklist (Mandatory)
|
|
35
|
+
- Reuse considered?
|
|
36
|
+
- Composition preferred over duplication?
|
|
37
|
+
- Demo data added to `app_demo_data.dart`, not UI?
|
|
38
|
+
- Request/Response models separated?
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Dart Tooling & CI"
|
|
3
|
+
description: Standards for analysis, linting, formatting, and automation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tooling & CI
|
|
7
|
+
|
|
8
|
+
## **Priority: P1 (HIGH)**
|
|
9
|
+
|
|
10
|
+
Standards for code quality, formatting, and generation.
|
|
11
|
+
|
|
12
|
+
## Implementation Guidelines
|
|
13
|
+
|
|
14
|
+
- **Linter**: Use `analysis_options.yaml`. Enforce `always_use_package_imports` and `require_trailing_commas`.
|
|
15
|
+
- **Formatting**: Use `dart format . --line-length 80`. Run on every commit.
|
|
16
|
+
- **DCM**: Use `dart_code_metrics` for complexity checks (Max cyclomatic complexity: 15).
|
|
17
|
+
- **Build Runner**: Always use `--delete-conflicting-outputs` with code generation.
|
|
18
|
+
- **CI Pipeline**: All PRs MUST pass `analyze`, `format`, and `test` steps.
|
|
19
|
+
- **Imports**: Group imports: `dart:`, `package:`, then relative.
|
|
20
|
+
- **Documentation**: Use `///` for public APIs. Link symbols using `[Class]`.
|
|
21
|
+
|
|
22
|
+
## Code
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
# analysis_options.yaml
|
|
26
|
+
analyzer:
|
|
27
|
+
errors:
|
|
28
|
+
todo: ignore
|
|
29
|
+
missing_required_param: error
|
|
30
|
+
linter:
|
|
31
|
+
rules:
|
|
32
|
+
- prefer_single_quotes
|
|
33
|
+
- unawaited_futures
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Related Topics
|
|
37
|
+
|
|
38
|
+
language | testing
|