@atlashub/smartstack-cli 3.34.0 → 3.36.0
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/.documentation/init.html +409 -0
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +118 -70
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -2
- package/templates/mcp-scaffolding/controller.cs.hbs +5 -1
- package/templates/skills/apex/SKILL.md +6 -3
- package/templates/skills/apex/references/post-checks.md +225 -0
- package/templates/skills/apex/references/smartstack-api.md +29 -1
- package/templates/skills/apex/references/smartstack-frontend.md +27 -0
- package/templates/skills/apex/references/smartstack-layers.md +18 -2
- package/templates/skills/apex/steps/step-00-init.md +77 -1
- package/templates/skills/apex/steps/step-01-analyze.md +21 -0
- package/templates/skills/apex/steps/step-03-execute.md +94 -5
- package/templates/skills/apex/steps/step-04-examine.md +7 -1
- package/templates/skills/business-analyse/SKILL.md +4 -3
- package/templates/skills/business-analyse/_shared.md +9 -0
- package/templates/skills/business-analyse/schemas/application-schema.json +13 -0
- package/templates/skills/business-analyse/steps/step-00-init.md +190 -34
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +129 -10
- package/templates/skills/business-analyse/steps/step-01b-applications.md +184 -13
- package/templates/skills/business-analyse/steps/step-03c-compile.md +14 -2
- package/templates/skills/business-analyse/steps/step-03d-validate.md +5 -1
- package/templates/skills/documentation/SKILL.md +175 -9
- package/templates/skills/efcore/steps/squash/step-03-create.md +6 -4
- package/templates/skills/gitflow/_shared.md +3 -1
- package/templates/skills/gitflow/steps/step-pr.md +34 -0
- package/templates/skills/ralph-loop/SKILL.md +31 -2
- package/templates/skills/ralph-loop/references/category-rules.md +29 -0
- package/templates/skills/ralph-loop/references/compact-loop.md +85 -2
- package/templates/skills/ralph-loop/references/section-splitting.md +439 -0
- package/templates/skills/ralph-loop/references/team-orchestration.md +331 -14
- package/templates/skills/ralph-loop/steps/step-00-init.md +4 -0
- package/templates/skills/ralph-loop/steps/step-01-task.md +27 -0
- package/templates/skills/ralph-loop/steps/step-02-execute.md +206 -1
- package/templates/skills/ralph-loop/steps/step-05-report.md +19 -0
- package/scripts/health-check.sh +0 -168
- package/scripts/postinstall.js +0 -18
|
@@ -22,6 +22,28 @@ All code goes through skills (/controller, /application, /ui-components, /efcore
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## Foundation Mode Detection
|
|
26
|
+
|
|
27
|
+
**IF `{foundation_mode}` == true:**
|
|
28
|
+
|
|
29
|
+
This is a foundation-only execution (called by ralph-loop Phase 0). Execute ONLY:
|
|
30
|
+
- Layer 0: Domain entities + EF configs + Migration
|
|
31
|
+
|
|
32
|
+
**SKIP ALL OTHER LAYERS:**
|
|
33
|
+
- Layer 1: Application + API + Seed Data → SKIP
|
|
34
|
+
- Layer 2: Frontend → SKIP
|
|
35
|
+
- Layer 3: Tests → SKIP
|
|
36
|
+
|
|
37
|
+
After Layer 0 completes and builds successfully:
|
|
38
|
+
- Commit with message: `chore(foundation): entities for {module_code}`
|
|
39
|
+
- Jump to step-04 for POST-CHECKs (domain + infrastructure only)
|
|
40
|
+
- End execution
|
|
41
|
+
|
|
42
|
+
**IF `{foundation_mode}` == false:**
|
|
43
|
+
Execute ALL layers normally (Layer 0 → Layer 1 → Layer 2 → Layer 3).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
25
47
|
## Layer 0 — Domain + Infrastructure (sequential, agent principal)
|
|
26
48
|
|
|
27
49
|
### Domain Entities
|
|
@@ -44,16 +66,26 @@ For each entity:
|
|
|
44
66
|
|
|
45
67
|
### Migration (BLOCKING)
|
|
46
68
|
|
|
69
|
+
> **CRITICAL — Migration must cover ALL entities, not just the first batch.**
|
|
70
|
+
> Root cause (test-apex-007): Migration was created once for 3 entities, then 4 more entities
|
|
71
|
+
> were added later without re-running migration → 4 entities had no database tables.
|
|
72
|
+
> **RULE:** Create/update migration AFTER ALL entities and EF configs are registered in DbContext.
|
|
73
|
+
> If entities are added incrementally, create a NEW migration for each batch.
|
|
74
|
+
|
|
47
75
|
```
|
|
48
|
-
1.
|
|
49
|
-
2.
|
|
50
|
-
3.
|
|
76
|
+
1. Verify ALL entities have been added as DbSet in ExtensionsDbContext
|
|
77
|
+
2. Verify ALL EF configurations are registered (ApplyConfigurationsFromAssembly or individual)
|
|
78
|
+
3. MCP suggest_migration → get standardized name
|
|
79
|
+
4. dotnet ef migrations add {Name} --project src/{Infra}.csproj --startup-project src/{Api}.csproj -o Persistence/Migrations
|
|
80
|
+
5. Cleanup corrupted EF Core artifacts:
|
|
51
81
|
for d in src/*/bin?Debug; do [ -d "$d" ] && rm -rf "$d"; done
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
6. dotnet ef database update (if local DB)
|
|
83
|
+
7. dotnet build → MUST PASS
|
|
84
|
+
8. Verify: dotnet ef migrations has-pending-model-changes → MUST report "No pending model changes"
|
|
54
85
|
```
|
|
55
86
|
|
|
56
87
|
**BLOCKING:** If build fails after migration, fix EF configs before proceeding.
|
|
88
|
+
**BLOCKING:** If `has-pending-model-changes` reports pending changes, entities are missing from the migration — create a new migration.
|
|
57
89
|
|
|
58
90
|
### Post-Layer 0 Build Gate
|
|
59
91
|
|
|
@@ -67,10 +99,66 @@ dotnet build
|
|
|
67
99
|
|
|
68
100
|
## Layer 1 — Application + API + Seed Data
|
|
69
101
|
|
|
102
|
+
### NavRoute and Permission Kebab-Case (CRITICAL)
|
|
103
|
+
|
|
104
|
+
> **ALL NavRoute segments and permission codes MUST use kebab-case for multi-word identifiers.**
|
|
105
|
+
> Root cause (test-apex-007): Controllers had `[NavRoute("business.humanresources.employees")]`
|
|
106
|
+
> instead of `[NavRoute("business.human-resources.employees")]`. This mismatched seed data routes
|
|
107
|
+
> and permission codes, causing 404s and permission denials at runtime.
|
|
108
|
+
|
|
109
|
+
**Rules:**
|
|
110
|
+
- NavRoute: `business.human-resources.employees` (NEVER `business.humanresources.employees`)
|
|
111
|
+
- Permissions: `business.human-resources.employees.read` (segments MATCH NavRoute exactly)
|
|
112
|
+
- Seed data codes: `human-resources` (NEVER `humanresources`)
|
|
113
|
+
- C# class names stay PascalCase (`HumanResourcesController`) — only route/permission strings use kebab-case
|
|
114
|
+
- POST-CHECKs 41 + 48 validate this. Fix BEFORE committing.
|
|
115
|
+
|
|
116
|
+
### Controller Route Attribute (BLOCKING)
|
|
117
|
+
|
|
118
|
+
> **Controllers with `[NavRoute]` must NOT have `[Route]` attribute.**
|
|
119
|
+
> Root cause (test-apex-007): ALL 7 controllers had BOTH `[Route("api/...")]` AND `[NavRoute("...")]`.
|
|
120
|
+
> In SmartStack, `[NavRoute]` resolves routes dynamically from Navigation entities in the database at startup.
|
|
121
|
+
> Having `[Route]` alongside causes route conflicts → all endpoints return 404.
|
|
122
|
+
|
|
123
|
+
**Rules:**
|
|
124
|
+
- `[NavRoute("context.app.module")]` is the ONLY route attribute needed on controllers
|
|
125
|
+
- **FORBIDDEN:** `[Route("api/business/human-resources/employees")]` alongside `[NavRoute]`
|
|
126
|
+
- **FORBIDDEN:** `[Route("api/[controller]")]` alongside `[NavRoute]`
|
|
127
|
+
- If generating via MCP `scaffold_extension` with `navRoute` option → output is correct (NavRoute only)
|
|
128
|
+
- If generating via `/controller` skill → verify NO `[Route]` is added
|
|
129
|
+
- POST-CHECK 50 validates this. Fix BEFORE committing.
|
|
130
|
+
|
|
131
|
+
### Validators DI Registration (CRITICAL)
|
|
132
|
+
|
|
133
|
+
> After creating validators, they MUST be registered in DI. Without registration, `[FromBody]` DTOs are never validated.
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
In DependencyInjection.cs (or ServiceCollectionExtensions.cs):
|
|
137
|
+
services.AddValidatorsFromAssemblyContaining<Create{Entity}DtoValidator>();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
POST-CHECK 46 validates this. If validators exist but no DI registration → BLOCKING.
|
|
141
|
+
|
|
70
142
|
### If economy_mode: Sequential execution
|
|
71
143
|
|
|
72
144
|
Execute each item from the plan sequentially using skills and MCP.
|
|
73
145
|
|
|
146
|
+
### Date Fields — Use DateOnly (CRITICAL)
|
|
147
|
+
|
|
148
|
+
> **ALL date-only fields in DTOs MUST use `DateOnly`, NEVER `string`.**
|
|
149
|
+
> Root cause (test-apex-007): WorkLog DTO had `string Date` instead of `DateOnly Date`.
|
|
150
|
+
> This causes: no date validation, inconsistent date formats, parsing errors.
|
|
151
|
+
|
|
152
|
+
**Type mapping for DTOs:**
|
|
153
|
+
| Domain type | DTO type | Example |
|
|
154
|
+
|-------------|----------|---------|
|
|
155
|
+
| `DateTime` | `DateTime` | `CreatedAt`, `UpdatedAt` |
|
|
156
|
+
| Date-only field | `DateOnly` | `Date`, `StartDate`, `EndDate`, `BirthDate` |
|
|
157
|
+
| `string` for date | **FORBIDDEN** | Never use `string` for dates |
|
|
158
|
+
| `DateTime` for date-only | **Avoid** | Use `DateOnly` when no time component needed |
|
|
159
|
+
|
|
160
|
+
POST-CHECK 47 validates this. If a DTO has `string` type for a property named `*Date*` → BLOCKING.
|
|
161
|
+
|
|
74
162
|
### Code Generation (if entities have codePattern != "manual")
|
|
75
163
|
|
|
76
164
|
For each entity with auto-generated code pattern (from feature.json or step-02 decisions):
|
|
@@ -114,6 +202,7 @@ Code stays in CreateDto, user provides it, validator has regex rule.
|
|
|
114
202
|
- A dead link (navigate to a route with no page) is a BLOCKING issue (POST-CHECK 42)
|
|
115
203
|
- Read `references/smartstack-frontend.md` for mandatory patterns (sections 3b + 8)
|
|
116
204
|
- Generate i18n JSON files for all 4 languages (fr, en, it, de) — `src/i18n/locales/{lang}/{module}.json`
|
|
205
|
+
- **I18n REGISTRATION (CRITICAL):** After creating i18n JSON files, register EACH new namespace in the i18n config file (config.ts/index.ts/i18n.ts). Unregistered namespaces → `useTranslation(['module'])` returns empty strings at runtime. POST-CHECK 45 validates this.
|
|
117
206
|
- All pages must follow loading → error → content pattern with CSS variables
|
|
118
207
|
|
|
119
208
|
### If NOT economy_mode: Agent Teams (parallel)
|
|
@@ -262,7 +262,13 @@ AC2: {criterion} → PASS / FAIL (evidence: {file:line or test})
|
|
|
262
262
|
| Security | TenantId filter, RequirePermission, no Guid.Empty, no !.Value | PASS / N/A |
|
|
263
263
|
| Seed data | completeness, deterministic GUIDs, no ContextId/RoleId constants | PASS / N/A |
|
|
264
264
|
| Code quality | PaginatedResult, EntityLookup (no FK select/input), CSS vars, search param | PASS / N/A |
|
|
265
|
-
|
|
|
265
|
+
| Migration completeness | ModelSnapshot covers ALL DbSet entities (POST-CHECK 44, 49) | PASS / N/A |
|
|
266
|
+
| NavRoute kebab-case | NavRoute + permissions use kebab-case (POST-CHECK 48) | PASS / N/A |
|
|
267
|
+
| DateOnly DTOs | Date fields use DateOnly not string (POST-CHECK 47) | PASS / N/A |
|
|
268
|
+
| I18n registration | Namespaces registered in i18n config (POST-CHECK 45) | PASS / N/A |
|
|
269
|
+
| Validators DI | FluentValidation registered in DI (POST-CHECK 46) | PASS / N/A |
|
|
270
|
+
| Route/NavRoute conflict | No [Route] alongside [NavRoute] on controllers (POST-CHECK 50) | PASS / N/A |
|
|
271
|
+
| POST-CHECKs | 50 checks from references/post-checks.md | PASS / N/A |
|
|
266
272
|
| Acceptance criteria | AC1..ACn | {X}/{Y} PASS |
|
|
267
273
|
```
|
|
268
274
|
|
|
@@ -43,6 +43,7 @@ The skill auto-detects which use case applies by scanning existing features in `
|
|
|
43
43
|
|
|
44
44
|
Step-00 handles detection automatically:
|
|
45
45
|
- **New vs Update**: scans `docs/business/` for existing applications
|
|
46
|
+
- **Single vs Multi-app**: multi-app detection in step-01, application identity confirmed in step-01b (always)
|
|
46
47
|
- **Single vs Multi-module**: determined during step-02 decomposition
|
|
47
48
|
- **Language**: detected from config or asked once
|
|
48
49
|
- **Review mode**: if `-review` flag, routes directly to step-06
|
|
@@ -151,7 +152,7 @@ When step-00 detects that the description matches an existing application:
|
|
|
151
152
|
**New application workflow (single or multi-app):**
|
|
152
153
|
- **Step 00:** Detection, scan existing, create master feature.json (draft)
|
|
153
154
|
- **Step 01:** Cadrage: context, stakeholders, scope, application roles (framed)
|
|
154
|
-
- **Step 01b:**
|
|
155
|
+
- **Step 01b:** Application identity (always): confirm code, route, icon, seed data (lightweight single-app / full decomposition multi-app)
|
|
155
156
|
- **Step 02:** Decomposition: modules, dependencies, client checkpoint (decomposed) — per application in multi-app mode
|
|
156
157
|
- **Step 03a:** Per-module data: sections, entities, business rules, questionnaires
|
|
157
158
|
- **Step 03b:** Per-module UI: state machines, wireframes, layouts, dashboards
|
|
@@ -207,12 +208,12 @@ When step-00 detects that the description matches an existing application:
|
|
|
207
208
|
| ---- | --------------------------------- | ------ | ---------------------------------------------------- |
|
|
208
209
|
| 00 | `steps/step-00-init.md` | Sonnet | Auto-detect new/update, scan existing, create master feature.json |
|
|
209
210
|
| 01 | `steps/step-01-cadrage.md` | Opus | Framing: context, stakeholders, scope, application roles + multi-app detection |
|
|
210
|
-
| 01b | `steps/step-01b-applications.md` | Opus |
|
|
211
|
+
| 01b | `steps/step-01b-applications.md` | Opus | Application identity: confirm code, route, icon, seedData (lightweight single-app, full decomposition multi-app) |
|
|
211
212
|
| 02 | `steps/step-02-decomposition.md` | Opus | Module decomposition, dependency graph, client checkpoint (per application in multi-app) |
|
|
212
213
|
| 03a1 | `steps/step-03a1-setup.md` | Opus | Per-module: setup, sections, questionnaires, cross-refs |
|
|
213
214
|
| 03a2 | `steps/step-03a2-analysis.md` | Opus | Per-module: objectives, entities, BRs, process flow |
|
|
214
215
|
| 03b | `steps/step-03b-ui.md` | Opus | Per-module: state machines, wireframes, layouts, dashboards |
|
|
215
|
-
| 03c | `steps/step-03c-compile.md` | Opus | Per-module: actors, UCs, FRs, permissions, navigation, seedDataCore (
|
|
216
|
+
| 03c | `steps/step-03c-compile.md` | Opus | Per-module: actors, UCs, FRs, permissions, navigation, seedDataCore (9 arrays), i18n |
|
|
216
217
|
| 03d | `steps/step-03d-validate.md` | Sonnet | Per-module: validation, write, incremental HTML, loop decision |
|
|
217
218
|
| 04a | `steps/step-04a-collect.md` | Opus | Collect module summaries & cross-module interactions |
|
|
218
219
|
| 04b | `steps/step-04b-analyze.md` | Opus | Analyze permission coherence, semantic validation, E2E flows |
|
|
@@ -98,6 +98,15 @@ Level 1: Context (business)
|
|
|
98
98
|
Level 4: Section (approve) ← sidebar nav (workflow)
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
**CRITICAL — Application identification (Level 2):**
|
|
102
|
+
The application is formally identified in step-01b (ALWAYS, even for single-app mode):
|
|
103
|
+
- Code: PascalCase (e.g., "HumanResources")
|
|
104
|
+
- Route: kebab-case (e.g., "/business/human-resources")
|
|
105
|
+
- Icon: Lucide icon name
|
|
106
|
+
- Sort order: position in navigation
|
|
107
|
+
This creates the `seedDataCore.navigationApplications` entry that links modules to their parent application.
|
|
108
|
+
The `seedDataCore.applicationRoles` entries are also built from `cadrage.applicationRoles`.
|
|
109
|
+
|
|
101
110
|
| BA Phase | Levels treated | What is defined |
|
|
102
111
|
|----------|---------------|-----------------|
|
|
103
112
|
| Cadrage (step-01) | Context + Application | Problem, stakeholders, scope, application-level roles |
|
|
@@ -54,6 +54,19 @@
|
|
|
54
54
|
"pattern": "^[a-z]{2,5}_$",
|
|
55
55
|
"description": "Application table prefix for database tables (e.g., rh_, fi_, crm_). Defined during cadrage, used by all entities in this application."
|
|
56
56
|
},
|
|
57
|
+
"applicationCode": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "PascalCase application code for navigation hierarchy (e.g., HumanResources). Confirmed in step-01b."
|
|
60
|
+
},
|
|
61
|
+
"applicationRoute": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"pattern": "^/[a-z-/]+$",
|
|
64
|
+
"description": "Kebab-case route path for navigation (e.g., /business/human-resources). Confirmed in step-01b."
|
|
65
|
+
},
|
|
66
|
+
"applicationIcon": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Lucide icon name for application navigation entry (e.g., users, shopping-cart). Confirmed in step-01b."
|
|
69
|
+
},
|
|
57
70
|
"workflow": {
|
|
58
71
|
"type": "object",
|
|
59
72
|
"description": "Iterative module loop state",
|
|
@@ -129,10 +129,116 @@ existing_projects: array of { projectName, projectId, applications[], version }
|
|
|
129
129
|
|
|
130
130
|
> **Project Resume Detection:** If a project-level feature.json is found at `docs/business-analyse/*/feature.json`, check its `metadata.workflow` to determine resume point. The project may have partially completed applications.
|
|
131
131
|
|
|
132
|
+
## Step 3b: Early Multi-Application Detection from Prompt (NEW)
|
|
133
|
+
|
|
134
|
+
> **Detect multi-app structure BEFORE asking for a single application name.**
|
|
135
|
+
> When the user's prompt explicitly describes multiple applications, we must recognize this immediately
|
|
136
|
+
> and set `workflow.mode = "project"` to avoid doing cadrage for a single app.
|
|
137
|
+
|
|
138
|
+
**Detection patterns (ANY match = multi-app detected):**
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
const multiAppPatterns = [
|
|
142
|
+
// French patterns
|
|
143
|
+
/une\s+application\s+\w+.*une\s+application\s+\w+/is,
|
|
144
|
+
/application\s*\d?\s*[:]\s*\w+.*application\s*\d?\s*[:]\s*\w+/is,
|
|
145
|
+
/premier[e]?\s+application.*deuxième\s+application/is,
|
|
146
|
+
/app\s*1\s*[:.].*app\s*2\s*[:.]*/is,
|
|
147
|
+
// English patterns
|
|
148
|
+
/an?\s+application\s+(for\s+)?\w+.*an?\s+application\s+(for\s+)?\w+/is,
|
|
149
|
+
/application\s*#?\d\s*[:.].*application\s*#?\d\s*[:.]*/is,
|
|
150
|
+
/first\s+app.*second\s+app/is,
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
const isMultiApp = multiAppPatterns.some(p => p.test(feature_description));
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**IF multi-app detected:**
|
|
157
|
+
|
|
158
|
+
1. Extract candidate applications from the prompt:
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
// Parse the prompt to identify application boundaries
|
|
162
|
+
// Each "une application X" / "an application X" block = one candidate
|
|
163
|
+
const candidates = extractApplicationCandidates(feature_description);
|
|
164
|
+
// Result example:
|
|
165
|
+
// [
|
|
166
|
+
// { name: "RH", description: "gestion des employes, conges, temps", modules: ["Employes", "Conges", "Temps"] },
|
|
167
|
+
// { name: "Projet", description: "gestion des projets, saisie du temps", modules: ["Projets", "Temps"] }
|
|
168
|
+
// ]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
2. Detect shared modules across candidates:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const allModules = candidates.flatMap(c => c.modules);
|
|
175
|
+
const sharedModules = allModules.filter((m, i) => allModules.indexOf(m) !== i);
|
|
176
|
+
// Example: sharedModules = ["Temps"] → appears in both RH and Projet
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
3. Display detection result and confirm:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
{language == "fr"
|
|
183
|
+
? "### Détection multi-application\n\nJ'ai détecté **{candidates.length} applications** dans votre description :"
|
|
184
|
+
: "### Multi-application detection\n\nI detected **{candidates.length} applications** in your description:"}
|
|
185
|
+
|
|
186
|
+
| # | Application | Modules identifiés |
|
|
187
|
+
|---|-------------|-------------------|
|
|
188
|
+
{for each candidate: index | name | modules.join(", ")}
|
|
189
|
+
|
|
190
|
+
{sharedModules.length > 0
|
|
191
|
+
? "⚠️ **Modules partagés détectés :** {sharedModules.join(', ')} — ces modules apparaissent dans plusieurs applications. Ils pourraient constituer une application transversale dédiée."
|
|
192
|
+
: ""}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Ask via AskUserQuestion:
|
|
196
|
+
```
|
|
197
|
+
question: "{language == 'fr' ? 'Confirmez-vous cette structure multi-application ?' : 'Do you confirm this multi-application structure?'}"
|
|
198
|
+
header: "Architecture"
|
|
199
|
+
options:
|
|
200
|
+
- label: "{language == 'fr' ? 'Oui, {candidates.length} applications' : 'Yes, {candidates.length} applications'}"
|
|
201
|
+
description: "{language == 'fr' ? 'Créer un projet avec les applications identifiées' : 'Create a project with the identified applications'}"
|
|
202
|
+
- label: "{language == 'fr' ? 'Extraire les modules partagés' : 'Extract shared modules'}" (only if sharedModules.length > 0)
|
|
203
|
+
description: "{language == 'fr' ? 'Créer une application dédiée pour {sharedModules.join(', ')} ({candidates.length + 1} applications au total)' : 'Create a dedicated app for {sharedModules.join(', ')} ({candidates.length + 1} total)'}"
|
|
204
|
+
- label: "{language == 'fr' ? 'Application unique' : 'Single application'}"
|
|
205
|
+
description: "{language == 'fr' ? 'Tout regrouper en une seule application avec plusieurs modules' : 'Group everything into one application with multiple modules'}"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**IF "Oui, N applications" or "Extraire les modules partagés":**
|
|
209
|
+
|
|
210
|
+
```yaml
|
|
211
|
+
workflow_mode: "project"
|
|
212
|
+
project_name: derived from feature_description
|
|
213
|
+
candidate_applications: [{ name, description, modules, context }]
|
|
214
|
+
shared_modules_extracted: boolean # true if user chose extraction
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
→ Skip step 4 (application name) — applications will be confirmed in step-01b
|
|
218
|
+
→ Continue to step 5 (language selection)
|
|
219
|
+
|
|
220
|
+
**IF "Application unique":**
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
workflow_mode: "application"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
→ Continue to step 4 normally
|
|
227
|
+
|
|
228
|
+
**IF no multi-app patterns detected:**
|
|
229
|
+
→ Continue to step 4 normally
|
|
230
|
+
|
|
132
231
|
## Step 4: Determine Application Name
|
|
133
232
|
|
|
233
|
+
> **This step is SKIPPED if `workflow_mode = "project"` (multi-app detected in step 3b).**
|
|
234
|
+
|
|
134
235
|
```
|
|
135
|
-
IF
|
|
236
|
+
IF workflow_mode = "project":
|
|
237
|
+
application_name = project_name // Project-level name, not a single app name
|
|
238
|
+
context = "business" // Default, each app can have its own context
|
|
239
|
+
→ Skip to step 5
|
|
240
|
+
|
|
241
|
+
ELSE IF workflow_type = "update":
|
|
136
242
|
application_name = existing app name (from step 3)
|
|
137
243
|
ELSE:
|
|
138
244
|
Analyze {feature_description} to extract application name
|
|
@@ -149,12 +255,13 @@ ELSE:
|
|
|
149
255
|
**Validate business context:**
|
|
150
256
|
```
|
|
151
257
|
validate_business_context("business")
|
|
152
|
-
→ BA restricted to 'business' context only
|
|
258
|
+
→ BA restricted to 'business' context only (in standalone mode)
|
|
259
|
+
→ In project mode, each application can target any context
|
|
153
260
|
```
|
|
154
261
|
|
|
155
262
|
**Store:**
|
|
156
263
|
```yaml
|
|
157
|
-
application_name: string
|
|
264
|
+
application_name: string # or project_name if project mode
|
|
158
265
|
context: "business"
|
|
159
266
|
```
|
|
160
267
|
|
|
@@ -216,15 +323,22 @@ feature_id: string
|
|
|
216
323
|
## Step 7: Create Output Directory Structure
|
|
217
324
|
|
|
218
325
|
```
|
|
219
|
-
IF
|
|
326
|
+
IF workflow_mode = "project":
|
|
327
|
+
// Project mode: create project-level directory + per-app directories later (in step-01b)
|
|
328
|
+
mkdir -p docs/business-analyse/v1.0
|
|
329
|
+
docs_dir = "docs/business-analyse/v{version}"
|
|
330
|
+
|
|
331
|
+
ELSE IF workflow_type = "new":
|
|
220
332
|
mkdir -p docs/business/{application_name}/business-analyse/v1.0
|
|
333
|
+
docs_dir = "docs/business/{app}/business-analyse/v{version}"
|
|
334
|
+
|
|
221
335
|
ELSE:
|
|
222
336
|
Directory already exists from ba-writer.createVersion()
|
|
223
337
|
```
|
|
224
338
|
|
|
225
339
|
**Store:**
|
|
226
340
|
```yaml
|
|
227
|
-
docs_dir:
|
|
341
|
+
docs_dir: string
|
|
228
342
|
```
|
|
229
343
|
|
|
230
344
|
## Step 8: Deploy JSON Schemas to Project (MANDATORY)
|
|
@@ -277,34 +391,67 @@ See [references/cache-warming-strategy.md](../references/cache-warming-strategy.
|
|
|
277
391
|
Create the master feature document using ba-writer agent.
|
|
278
392
|
|
|
279
393
|
```
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
394
|
+
IF workflow_mode = "project":
|
|
395
|
+
// PROJECT MODE: Create project-level feature.json
|
|
396
|
+
ba-writer.createProjectFeature({
|
|
397
|
+
id: generate_project_id(), // PROJ-NNN
|
|
398
|
+
version: {version},
|
|
399
|
+
scope: "project",
|
|
400
|
+
status: "draft",
|
|
401
|
+
metadata: {
|
|
402
|
+
projectName: {project_name},
|
|
403
|
+
language: {language},
|
|
404
|
+
featureDescription: {feature_description},
|
|
405
|
+
workflowType: {workflow_type},
|
|
406
|
+
analysisMode: "interactive",
|
|
407
|
+
mcpAvailable: true,
|
|
408
|
+
candidateApplications: {candidate_applications}, // From step 3b detection
|
|
409
|
+
sharedModulesExtracted: {shared_modules_extracted},
|
|
410
|
+
workflow: {
|
|
411
|
+
mode: "project",
|
|
412
|
+
applicationOrder: [],
|
|
413
|
+
currentApplicationIndex: 0,
|
|
414
|
+
completedApplications: []
|
|
415
|
+
}
|
|
299
416
|
}
|
|
300
|
-
}
|
|
301
|
-
})
|
|
302
|
-
```
|
|
417
|
+
})
|
|
303
418
|
|
|
304
|
-
|
|
305
|
-
`docs/business/{app}/business-analyse/v{version}/feature.json`
|
|
419
|
+
Output path: docs/business-analyse/v{version}/feature.json
|
|
306
420
|
|
|
307
|
-
|
|
421
|
+
Store:
|
|
422
|
+
project_id: string // PROJ-NNN
|
|
423
|
+
feature_id: project_id // In project mode, feature_id = project_id for step-01
|
|
424
|
+
|
|
425
|
+
ELSE:
|
|
426
|
+
// SINGLE-APP MODE: Create application-level feature.json
|
|
427
|
+
ba-writer.createApplicationFeature({
|
|
428
|
+
id: {feature_id},
|
|
429
|
+
version: {version},
|
|
430
|
+
scope: "application",
|
|
431
|
+
status: "draft",
|
|
432
|
+
metadata: {
|
|
433
|
+
application: {application_name},
|
|
434
|
+
context: "business",
|
|
435
|
+
language: {language},
|
|
436
|
+
featureDescription: {feature_description},
|
|
437
|
+
workflowType: {workflow_type},
|
|
438
|
+
analysisMode: "interactive",
|
|
439
|
+
mcpAvailable: true,
|
|
440
|
+
workflow: {
|
|
441
|
+
mode: "application",
|
|
442
|
+
moduleOrder: [],
|
|
443
|
+
currentModuleIndex: 0,
|
|
444
|
+
completedModules: [],
|
|
445
|
+
currentModule: null
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
Output path: docs/business/{app}/business-analyse/v{version}/feature.json
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
> **Note:** In project mode, per-application feature.json files are created later in step-01b.
|
|
454
|
+
> In single-app mode, step-02 (decomposition) determines if it's single or multi-module.
|
|
308
455
|
|
|
309
456
|
## Step 10: Update Config
|
|
310
457
|
|
|
@@ -335,13 +482,18 @@ Update `.business-analyse/config.json` with new feature information.
|
|
|
335
482
|
|--------------------|----------------------------------------------|
|
|
336
483
|
| Feature ID | {feature_id} |
|
|
337
484
|
| Workflow | {workflow_type} |
|
|
338
|
-
|
|
|
485
|
+
| Mode | {workflow_mode === "project" ? "Multi-application project" : "Single application"} |
|
|
486
|
+
| Application/Project| {workflow_mode === "project" ? project_name + " (" + candidate_applications.length + " apps)" : "business/" + application_name} |
|
|
339
487
|
| Output Path | {docs_dir}/feature.json |
|
|
340
488
|
| Language | {language} |
|
|
341
489
|
| Version | {version} |
|
|
342
490
|
| MCP Available | true |
|
|
343
491
|
| Analysis Mode | Interactive (always) |
|
|
344
492
|
|
|
493
|
+
{workflow_mode === "project"
|
|
494
|
+
? "Candidate applications: " + candidate_applications.map(a => a.name).join(", ")
|
|
495
|
+
: ""}
|
|
496
|
+
|
|
345
497
|
NEXT STEP: step-01-cadrage
|
|
346
498
|
═══════════════════════════════════════════════════════════════
|
|
347
499
|
```
|
|
@@ -352,14 +504,18 @@ After showing initialization summary, proceed to `./step-01-cadrage.md`
|
|
|
352
504
|
|
|
353
505
|
**Pass context variables:**
|
|
354
506
|
```yaml
|
|
355
|
-
feature_id: string
|
|
507
|
+
feature_id: string # FEAT-NNN (single-app) or PROJ-NNN (project)
|
|
356
508
|
feature_description: string
|
|
357
509
|
workflow_type: "new" | "update"
|
|
358
|
-
|
|
510
|
+
workflow_mode: "application" | "project"
|
|
511
|
+
application_name: string # Single-app: app name. Project: project name.
|
|
512
|
+
applicationCode: string # PascalCase derived from application_name (preliminary, confirmed in step-01b)
|
|
513
|
+
project_id: string | null # PROJ-NNN if project mode, null if single-app
|
|
514
|
+
candidate_applications: array | null # Pre-identified apps from prompt (project mode only)
|
|
515
|
+
shared_modules_extracted: boolean # True if user chose to extract shared modules as new app
|
|
359
516
|
language: string
|
|
360
517
|
docs_dir: string
|
|
361
518
|
mcp_available: boolean
|
|
362
|
-
workflow_mode: "application"
|
|
363
519
|
analysisMode: "interactive"
|
|
364
520
|
version: string
|
|
365
521
|
```
|