@atlashub/smartstack-cli 3.8.0 → 3.10.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/dist/index.js +365 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/templates/agents/action.md +1 -0
- package/templates/agents/ba-writer.md +211 -0
- package/templates/agents/explore-codebase.md +1 -0
- package/templates/agents/explore-docs.md +1 -0
- package/templates/agents/fix-grammar.md +1 -0
- package/templates/agents/snipper.md +1 -0
- package/templates/skills/admin/SKILL.md +6 -0
- package/templates/skills/ai-prompt/SKILL.md +32 -136
- package/templates/skills/ai-prompt/steps/step-01-implementation.md +122 -0
- package/templates/skills/apex/SKILL.md +120 -0
- package/templates/skills/apex/_shared.md +86 -0
- package/templates/skills/apex/references/agent-teams-protocol.md +164 -0
- package/templates/skills/apex/references/smartstack-layers.md +173 -0
- package/templates/skills/apex/steps/step-00-init.md +156 -0
- package/templates/skills/apex/steps/step-01-analyze.md +169 -0
- package/templates/skills/apex/steps/step-02-plan.md +160 -0
- package/templates/skills/apex/steps/step-03-execute.md +166 -0
- package/templates/skills/apex/steps/step-04-validate.md +138 -0
- package/templates/skills/apex/steps/step-05-examine.md +124 -0
- package/templates/skills/apex/steps/step-06-resolve.md +105 -0
- package/templates/skills/apex/steps/step-07-tests.md +130 -0
- package/templates/skills/apex/steps/step-08-run-tests.md +115 -0
- package/templates/skills/application/SKILL.md +10 -0
- package/templates/skills/application/references/application-roles-template.md +227 -0
- package/templates/skills/application/references/backend-controller-hierarchy.md +58 -0
- package/templates/skills/application/references/backend-entity-seeding.md +72 -0
- package/templates/skills/application/references/backend-verification.md +88 -0
- package/templates/skills/application/references/frontend-verification.md +111 -0
- package/templates/skills/application/references/nav-fallback-procedure.md +200 -0
- package/templates/skills/application/references/provider-template.md +158 -0
- package/templates/skills/application/references/test-frontend.md +73 -0
- package/templates/skills/application/references/test-prerequisites.md +72 -0
- package/templates/skills/application/steps/step-01-navigation.md +7 -198
- package/templates/skills/application/steps/step-03-roles.md +45 -7
- package/templates/skills/application/steps/step-03b-provider.md +15 -132
- package/templates/skills/application/steps/step-04-backend.md +20 -350
- package/templates/skills/application/steps/step-05-frontend.md +12 -101
- package/templates/skills/application/steps/step-07-tests.md +12 -132
- package/templates/skills/business-analyse/SKILL.md +67 -6
- package/templates/skills/business-analyse/html/ba-interactive.html +176 -14
- package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +1 -0
- package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +16 -4
- package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +7 -2
- package/templates/skills/business-analyse/html/src/scripts/09-export.js +103 -0
- package/templates/skills/business-analyse/html/src/scripts/10-comments.js +12 -6
- package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +24 -2
- package/templates/skills/business-analyse/html/src/styles/08-review-panel.css +12 -0
- package/templates/skills/business-analyse/html/src/template.html +1 -0
- package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +477 -0
- package/templates/skills/business-analyse/references/cache-warming-strategy.md +578 -0
- package/templates/skills/business-analyse/references/cadrage-structure-cards.md +78 -0
- package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +97 -0
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +92 -0
- package/templates/skills/business-analyse/references/deploy-data-build.md +121 -0
- package/templates/skills/business-analyse/references/deploy-modes.md +49 -0
- package/templates/skills/business-analyse/references/handoff-file-templates.md +119 -0
- package/templates/skills/business-analyse/references/handoff-mappings.md +81 -0
- package/templates/skills/business-analyse/references/html-data-mapping.md +10 -2
- package/templates/skills/business-analyse/references/init-schema-deployment.md +65 -0
- package/templates/skills/business-analyse/references/review-data-mapping.md +363 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +538 -0
- package/templates/skills/business-analyse/references/spec-auto-inference.md +57 -0
- package/templates/skills/business-analyse/references/ui-dashboard-spec.md +85 -0
- package/templates/skills/business-analyse/references/ui-resource-cards.md +110 -0
- package/templates/skills/business-analyse/references/validate-incremental-html.md +55 -0
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -1
- package/templates/skills/business-analyse/steps/step-00-init.md +186 -53
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +5 -194
- package/templates/skills/business-analyse/steps/step-03a-data.md +42 -49
- package/templates/skills/business-analyse/steps/step-03b-ui.md +12 -178
- package/templates/skills/business-analyse/steps/step-03c-compile.md +71 -2
- package/templates/skills/business-analyse/steps/step-03d-validate.md +277 -48
- package/templates/skills/business-analyse/steps/step-04-consolidation.md +175 -104
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +66 -438
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +35 -184
- package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +526 -0
- package/templates/skills/business-analyse/steps/step-06-review.md +277 -0
- package/templates/skills/cc-agent/references/agent-behavior-patterns.md +95 -0
- package/templates/skills/cc-agent/steps/step-02-generate.md +5 -78
- package/templates/skills/check-version/SKILL.md +7 -0
- package/templates/skills/controller/references/controller-code-templates.md +159 -0
- package/templates/skills/controller/references/permission-sync-templates.md +152 -0
- package/templates/skills/controller/steps/step-03-generate.md +166 -158
- package/templates/skills/controller/steps/step-04-perms.md +5 -144
- package/templates/skills/controller/templates.md +11 -2
- package/templates/skills/debug/SKILL.md +7 -0
- package/templates/skills/explore/SKILL.md +6 -0
- package/templates/skills/feature-full/SKILL.md +39 -142
- package/templates/skills/feature-full/steps/step-01-implementation.md +120 -0
- package/templates/skills/gitflow/references/init-config-template.md +135 -0
- package/templates/skills/gitflow/references/init-name-normalization.md +103 -0
- package/templates/skills/gitflow/references/plan-template.md +69 -0
- package/templates/skills/gitflow/references/start-efcore-preflight.md +70 -0
- package/templates/skills/gitflow/references/start-local-config.md +110 -0
- package/templates/skills/gitflow/steps/step-init.md +18 -289
- package/templates/skills/gitflow/steps/step-plan.md +6 -63
- package/templates/skills/gitflow/steps/step-start.md +16 -126
- package/templates/skills/mcp/SKILL.md +9 -213
- package/templates/skills/mcp/steps/step-01-healthcheck.md +108 -0
- package/templates/skills/mcp/steps/step-02-tools.md +73 -0
- package/templates/skills/notification/SKILL.md +7 -0
- package/templates/skills/quick-search/SKILL.md +5 -0
- package/templates/skills/ralph-loop/SKILL.md +99 -381
- package/templates/skills/ralph-loop/references/category-rules.md +259 -0
- package/templates/skills/ralph-loop/references/compact-loop.md +182 -0
- package/templates/skills/ralph-loop/references/core-seed-data.md +173 -21
- package/templates/skills/ralph-loop/references/task-transform-legacy.md +259 -0
- package/templates/skills/ralph-loop/references/team-orchestration.md +189 -0
- package/templates/skills/ralph-loop/steps/step-00-init.md +111 -383
- package/templates/skills/ralph-loop/steps/step-01-task.md +79 -896
- package/templates/skills/ralph-loop/steps/step-02-execute.md +68 -680
- package/templates/skills/ralph-loop/steps/step-03-commit.md +47 -277
- package/templates/skills/ralph-loop/steps/step-04-check.md +124 -607
- package/templates/skills/ralph-loop/steps/step-05-report.md +68 -367
- package/templates/skills/refactor/SKILL.md +12 -176
- package/templates/skills/refactor/steps/step-01-discover.md +60 -0
- package/templates/skills/refactor/steps/step-02-execute.md +67 -0
- package/templates/skills/review-code/SKILL.md +19 -257
- package/templates/skills/review-code/steps/step-01-smartstack.md +96 -0
- package/templates/skills/review-code/steps/step-02-detailed-review.md +80 -0
- package/templates/skills/review-code/steps/step-03-react.md +44 -0
- package/templates/skills/ui-components/SKILL.md +7 -0
- package/templates/skills/utils/SKILL.md +6 -0
- package/templates/skills/validate/SKILL.md +6 -0
- package/templates/skills/validate-feature/SKILL.md +8 -0
- package/templates/skills/workflow/SKILL.md +40 -118
- package/templates/skills/workflow/steps/step-01-implementation.md +84 -0
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
# SmartStack Controller Templates
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
3
|
+
> **⚠️ OBSOLETE - DO NOT USE THESE TEMPLATES MANUALLY**
|
|
4
|
+
>
|
|
5
|
+
> **The `/controller` skill now uses the MCP `scaffold_extension` tool to generate controllers.**
|
|
6
|
+
> These templates are kept for reference only. All controller generation MUST go through the MCP to ensure:
|
|
7
|
+
> - ✅ `[NavRoute]` attribute is included for frontend/backend sync
|
|
8
|
+
> - ✅ Permissions are correctly generated
|
|
9
|
+
> - ✅ Consistency with SmartStack conventions
|
|
10
|
+
>
|
|
11
|
+
> **To generate a controller, use:** `/controller` skill which calls MCP `scaffold_extension` automatically.
|
|
12
|
+
>
|
|
13
|
+
> **If you modify these templates, they will NOT be used.** The MCP templates in `templates/mcp-scaffolding/controller.cs.hbs` are the source of truth.
|
|
5
14
|
|
|
6
15
|
---
|
|
7
16
|
|
|
@@ -163,3 +163,10 @@ Evaluate solutions:
|
|
|
163
163
|
<priority>
|
|
164
164
|
Understanding > Speed > Completeness. Every bug must be fully understood before attempting fixes.
|
|
165
165
|
</priority>
|
|
166
|
+
|
|
167
|
+
<success_criteria>
|
|
168
|
+
- Root cause identified with evidence (not just symptoms)
|
|
169
|
+
- Fix implemented with minimal, targeted changes
|
|
170
|
+
- Original error no longer reproducible
|
|
171
|
+
- Related tests pass without regressions
|
|
172
|
+
</success_criteria>
|
|
@@ -90,3 +90,9 @@ Provide comprehensive response:
|
|
|
90
90
|
<priority>
|
|
91
91
|
Accuracy > Speed > Brevity. Provide complete answers with evidence.
|
|
92
92
|
</priority>
|
|
93
|
+
|
|
94
|
+
<success_criteria>
|
|
95
|
+
- Question answered with supporting file references and line numbers
|
|
96
|
+
- All relevant code patterns and conventions identified
|
|
97
|
+
- Dependencies and connections mapped
|
|
98
|
+
</success_criteria>
|
|
@@ -7,7 +7,7 @@ description: |
|
|
|
7
7
|
- User mentions "oneshot", "complete feature", "full-stack"
|
|
8
8
|
- Creating a module with notifications, workflows and/or AI
|
|
9
9
|
- Need for complete user experience
|
|
10
|
-
Scope: Domain
|
|
10
|
+
Scope: Domain -> Application -> Infrastructure -> API -> Web + Notifications + Workflows + AI
|
|
11
11
|
disable-model-invocation: true
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -17,7 +17,7 @@ disable-model-invocation: true
|
|
|
17
17
|
|
|
18
18
|
**Reference:** [_shared.md](../_shared.md) for architecture, permissions, i18n
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## When This Skill Activates
|
|
21
21
|
|
|
22
22
|
| Trigger | Example |
|
|
23
23
|
|---------|---------|
|
|
@@ -25,173 +25,62 @@ disable-model-invocation: true
|
|
|
25
25
|
| Full-stack | "Create the backend and frontend for..." |
|
|
26
26
|
| Integration | "With notifications and automated emails" |
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Complete Flow
|
|
29
29
|
|
|
30
30
|
```
|
|
31
|
-
DOMAIN
|
|
31
|
+
DOMAIN -> APPLICATION -> INFRASTRUCTURE -> API -> WEB
|
|
32
32
|
+ NOTIFICATIONS + WORKFLOWS + AI
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
##
|
|
35
|
+
## Phase 1: Analysis
|
|
36
36
|
|
|
37
|
-
### PHASE 1: ANALYSIS
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
□ Module/functionality?
|
|
41
|
-
□ Entities? CRUD operations? Business rules?
|
|
42
|
-
□ Notifications required? Automated emails? AI?
|
|
43
|
-
□ Display: Cards/Table/Kanban? Permissions?
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### PHASE 2: DOMAIN
|
|
47
|
-
|
|
48
|
-
```csharp
|
|
49
|
-
// {Entity}.cs - Factory Method + Behaviors
|
|
50
|
-
public class {Entity} : BaseEntity, IAuditableEntity
|
|
51
|
-
{
|
|
52
|
-
public string Name { get; private set; }
|
|
53
|
-
public {Entity}Status Status { get; private set; }
|
|
54
|
-
private {Entity}() { }
|
|
55
|
-
public static {Entity} Create(string name, Guid createdById) =>
|
|
56
|
-
new { Id = Guid.NewGuid(), Name = name, Status = {Entity}Status.Active, ... };
|
|
57
|
-
public void Update(string name) => Name = name ?? throw new DomainException("Name required");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// {Entity}Status.cs
|
|
61
|
-
public enum {Entity}Status { Active = 0, Inactive = 1, Archived = 2 }
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### PHASE 3: APPLICATION
|
|
65
|
-
|
|
66
|
-
```csharp
|
|
67
|
-
// I{Entity}Service.cs
|
|
68
|
-
Task<PagedResult<{Entity}Dto>> GetAllAsync(...);
|
|
69
|
-
Task<{Entity}Dto> CreateAsync(Create{Entity}Request request, CancellationToken ct);
|
|
70
|
-
|
|
71
|
-
// DTOs
|
|
72
|
-
public record {Entity}Dto(Guid Id, string Name, string Status, DateTime CreatedAt);
|
|
73
|
-
public record Create{Entity}Request(string Name, string? Description);
|
|
74
|
-
|
|
75
|
-
// Permissions.cs + PermissionConfiguration.cs (2 files!)
|
|
76
|
-
public const string View = "{context}.{area}.{module}.read";
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### PHASE 4: INFRASTRUCTURE
|
|
80
|
-
|
|
81
|
-
```csharp
|
|
82
|
-
// {Entity}Configuration.cs
|
|
83
|
-
builder.ToTable("{Entity}s", "{schema}");
|
|
84
|
-
builder.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
|
85
|
-
|
|
86
|
-
// {Entity}Service.cs with Notifications
|
|
87
|
-
public async Task<{Entity}Dto> CreateAsync(...) {
|
|
88
|
-
var entity = {Entity}.Create(request.Name, _currentUser.Id);
|
|
89
|
-
_context.{Entity}s.Add(entity);
|
|
90
|
-
await _context.SaveChangesAsync(ct);
|
|
91
|
-
await _notificationService.SendNotificationAsync(_currentUser.Id,
|
|
92
|
-
NotificationType.{Entity}Created, "Created", $"{entity.Name} created",
|
|
93
|
-
relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, ct);
|
|
94
|
-
return MapToDto(entity);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// DependencyInjection.cs
|
|
98
|
-
services.AddScoped<I{Entity}Service, {Entity}Service>();
|
|
99
37
|
```
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
[ApiController][Route("api/{area}/{module}")][Authorize]
|
|
105
|
-
public class {Entity}Controller : ControllerBase
|
|
106
|
-
{
|
|
107
|
-
[HttpGet][RequirePermission(Permissions.{Area}.{Module}.View)]
|
|
108
|
-
[ProducesResponseType(typeof(PagedResult<{Entity}Dto>), 200)]
|
|
109
|
-
public async Task<ActionResult<PagedResult<{Entity}Dto>>> GetAll(...);
|
|
110
|
-
|
|
111
|
-
[HttpPost][RequirePermission(Permissions.{Area}.{Module}.Create)]
|
|
112
|
-
[ProducesResponseType(typeof({Entity}Dto), 201)]
|
|
113
|
-
public async Task<ActionResult<{Entity}Dto>> Create([FromBody] request, CancellationToken ct);
|
|
114
|
-
}
|
|
38
|
+
- Module/functionality?
|
|
39
|
+
- Entities? CRUD operations? Business rules?
|
|
40
|
+
- Notifications required? Automated emails? AI?
|
|
41
|
+
- Display: Cards/Table/Kanban? Permissions?
|
|
115
42
|
```
|
|
116
43
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
// {module}Api.ts
|
|
121
|
-
export const {module}Api = {
|
|
122
|
-
getAll: (page, pageSize, search?) => apiClient.get<PagedResult<{Entity}Dto>>('/{area}/{module}', { params }),
|
|
123
|
-
create: (data) => apiClient.post<{Entity}Dto>('/{area}/{module}', data),
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// use{Module}.ts with SignalR
|
|
127
|
-
export function use{Module}() {
|
|
128
|
-
const queryClient = useQueryClient();
|
|
129
|
-
useSignalR({ onNotification: (n) => {
|
|
130
|
-
if (n.relatedEntityType === '{Entity}') queryClient.invalidateQueries(['{module}']);
|
|
131
|
-
}});
|
|
132
|
-
const createMutation = useMutation({ mutationFn: {module}Api.create, onSuccess: () => ... });
|
|
133
|
-
return { create: createMutation.mutate, ... };
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// {Module}Page.tsx with EntityCard
|
|
137
|
-
<EntityCard title={item.name} actions={[{ label: 'View', onClick: () => navigate(...) }]} />
|
|
138
|
-
|
|
139
|
-
// Routes (nested mandatory)
|
|
140
|
-
<Route path="{area}"><Route path="{module}"><Route index element={<{Module}Page />} /></Route></Route>
|
|
141
|
-
```
|
|
44
|
+
## Phases 2-7: Implementation
|
|
142
45
|
|
|
143
|
-
|
|
46
|
+
See [steps/step-01-implementation.md](steps/step-01-implementation.md) for detailed code templates covering:
|
|
47
|
+
- Phase 2: Domain (Entity + Factory + Behaviors + Enum)
|
|
48
|
+
- Phase 3: Application (Interface + DTOs + Permissions)
|
|
49
|
+
- Phase 4: Infrastructure (EF Config + Service + DI)
|
|
50
|
+
- Phase 5: API (Controller + Authorize + RequirePermission)
|
|
51
|
+
- Phase 6: Frontend (API + Hook + Page + Routes)
|
|
52
|
+
- Phase 7: Integrations (Notifications + Workflows + AI)
|
|
144
53
|
|
|
145
|
-
|
|
146
|
-
```csharp
|
|
147
|
-
await _notificationService.SendNotificationAsync(userId, NotificationType.{Entity}Created,
|
|
148
|
-
title, message, relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, actionUrl);
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### Workflow Email
|
|
152
|
-
```csharp
|
|
153
|
-
// 1. WorkflowTriggerConfiguration.cs: new { Code = "{entity}.created", ... }
|
|
154
|
-
// 2. WorkflowConfiguration.cs: new { TriggerId = ..., ... }
|
|
155
|
-
// 3. Service:
|
|
156
|
-
await _workflowService.TriggerAsync("{entity}.created", new Dictionary<string, object>{...});
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
#### AI
|
|
160
|
-
```csharp
|
|
161
|
-
var result = await _aiCompletionService.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
162
|
-
"{entity}-analyzer", new Dictionary<string, object>{ ["name"] = entity.Name }, ct);
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## COMPLETE CHECKLIST
|
|
54
|
+
## Complete Checklist
|
|
166
55
|
|
|
167
56
|
### Backend
|
|
168
57
|
```
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
58
|
+
- Domain: Entity + Factory + Behaviors + Enum + IAuditableEntity
|
|
59
|
+
- Application: Interface + DTOs + Permissions (2 files!)
|
|
60
|
+
- Infrastructure: EF Config + Service + DI + DbSet + Migration
|
|
61
|
+
- API: Controller + Authorize + RequirePermission + ProducesResponseType
|
|
173
62
|
```
|
|
174
63
|
|
|
175
64
|
### Frontend
|
|
176
65
|
```
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
66
|
+
- {module}Api.ts + use{Module}.ts (with SignalR) + {Module}Page.tsx + {Module}Form.tsx
|
|
67
|
+
- i18n: fr, en, it, de
|
|
68
|
+
- Nested routes in App.tsx
|
|
180
69
|
```
|
|
181
70
|
|
|
182
71
|
### Integrations
|
|
183
72
|
```
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
73
|
+
- Notifications: NotificationType + SendNotificationAsync + useSignalR
|
|
74
|
+
- Workflows: Trigger + Workflow + TriggerAsync
|
|
75
|
+
- AI: Prompt + OutputSchema + ExecutePromptAsync
|
|
187
76
|
```
|
|
188
77
|
|
|
189
78
|
### Validation
|
|
190
79
|
```
|
|
191
|
-
|
|
80
|
+
- dotnet build + npm run build + npm run lint OK
|
|
192
81
|
```
|
|
193
82
|
|
|
194
|
-
##
|
|
83
|
+
## Orchestrated Skills
|
|
195
84
|
|
|
196
85
|
| Skill | Phase |
|
|
197
86
|
|-------|-------|
|
|
@@ -203,7 +92,7 @@ var result = await _aiCompletionService.ExecutePromptByCodeWithValidationAsync<{
|
|
|
203
92
|
| `/ui-components` | 6 |
|
|
204
93
|
| `/efcore:migration` | 4 |
|
|
205
94
|
|
|
206
|
-
##
|
|
95
|
+
## Absolute Rules
|
|
207
96
|
|
|
208
97
|
| DO | DON'T |
|
|
209
98
|
|----|-------|
|
|
@@ -212,3 +101,11 @@ var result = await _aiCompletionService.ExecutePromptByCodeWithValidationAsync<{
|
|
|
212
101
|
| Permissions 2 files | Flat routes |
|
|
213
102
|
| SignalR hooks | Skip i18n 4 languages |
|
|
214
103
|
| ProducesResponseType | Skip logging |
|
|
104
|
+
|
|
105
|
+
<success_criteria>
|
|
106
|
+
- All layers created: Domain, Infrastructure, Application, API, Frontend
|
|
107
|
+
- Navigation, permissions, and roles seed data generated via MCP
|
|
108
|
+
- EF Core migration created and applied
|
|
109
|
+
- Tests pass (unit + integration)
|
|
110
|
+
- i18n translations in 4 languages
|
|
111
|
+
</success_criteria>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Feature Full - Implementation Phases
|
|
2
|
+
|
|
3
|
+
## Phase 2: Domain
|
|
4
|
+
|
|
5
|
+
```csharp
|
|
6
|
+
// {Entity}.cs - Factory Method + Behaviors
|
|
7
|
+
public class {Entity} : BaseEntity, IAuditableEntity
|
|
8
|
+
{
|
|
9
|
+
public string Name { get; private set; }
|
|
10
|
+
public {Entity}Status Status { get; private set; }
|
|
11
|
+
private {Entity}() { }
|
|
12
|
+
public static {Entity} Create(string name, Guid createdById) =>
|
|
13
|
+
new { Id = Guid.NewGuid(), Name = name, Status = {Entity}Status.Active, ... };
|
|
14
|
+
public void Update(string name) => Name = name ?? throw new DomainException("Name required");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// {Entity}Status.cs
|
|
18
|
+
public enum {Entity}Status { Active = 0, Inactive = 1, Archived = 2 }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Phase 3: Application
|
|
22
|
+
|
|
23
|
+
```csharp
|
|
24
|
+
// I{Entity}Service.cs
|
|
25
|
+
Task<PagedResult<{Entity}Dto>> GetAllAsync(...);
|
|
26
|
+
Task<{Entity}Dto> CreateAsync(Create{Entity}Request request, CancellationToken ct);
|
|
27
|
+
|
|
28
|
+
// DTOs
|
|
29
|
+
public record {Entity}Dto(Guid Id, string Name, string Status, DateTime CreatedAt);
|
|
30
|
+
public record Create{Entity}Request(string Name, string? Description);
|
|
31
|
+
|
|
32
|
+
// Permissions.cs + PermissionConfiguration.cs (2 files!)
|
|
33
|
+
public const string View = "{context}.{area}.{module}.read";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Phase 4: Infrastructure
|
|
37
|
+
|
|
38
|
+
```csharp
|
|
39
|
+
// {Entity}Configuration.cs
|
|
40
|
+
builder.ToTable("{Entity}s", "{schema}");
|
|
41
|
+
builder.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
|
42
|
+
|
|
43
|
+
// {Entity}Service.cs with Notifications
|
|
44
|
+
public async Task<{Entity}Dto> CreateAsync(...) {
|
|
45
|
+
var entity = {Entity}.Create(request.Name, _currentUser.Id);
|
|
46
|
+
_context.{Entity}s.Add(entity);
|
|
47
|
+
await _context.SaveChangesAsync(ct);
|
|
48
|
+
await _notificationService.SendNotificationAsync(_currentUser.Id,
|
|
49
|
+
NotificationType.{Entity}Created, "Created", $"{entity.Name} created",
|
|
50
|
+
relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, ct);
|
|
51
|
+
return MapToDto(entity);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// DependencyInjection.cs
|
|
55
|
+
services.AddScoped<I{Entity}Service, {Entity}Service>();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Phase 5: API
|
|
59
|
+
|
|
60
|
+
```csharp
|
|
61
|
+
[ApiController][Route("api/{area}/{module}")][Authorize]
|
|
62
|
+
public class {Entity}Controller : ControllerBase
|
|
63
|
+
{
|
|
64
|
+
[HttpGet][RequirePermission(Permissions.{Area}.{Module}.View)]
|
|
65
|
+
[ProducesResponseType(typeof(PagedResult<{Entity}Dto>), 200)]
|
|
66
|
+
public async Task<ActionResult<PagedResult<{Entity}Dto>>> GetAll(...);
|
|
67
|
+
|
|
68
|
+
[HttpPost][RequirePermission(Permissions.{Area}.{Module}.Create)]
|
|
69
|
+
[ProducesResponseType(typeof({Entity}Dto), 201)]
|
|
70
|
+
public async Task<ActionResult<{Entity}Dto>> Create([FromBody] request, CancellationToken ct);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Phase 6: Frontend
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// {module}Api.ts
|
|
78
|
+
export const {module}Api = {
|
|
79
|
+
getAll: (page, pageSize, search?) => apiClient.get<PagedResult<{Entity}Dto>>('/{area}/{module}', { params }),
|
|
80
|
+
create: (data) => apiClient.post<{Entity}Dto>('/{area}/{module}', data),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// use{Module}.ts with SignalR
|
|
84
|
+
export function use{Module}() {
|
|
85
|
+
const queryClient = useQueryClient();
|
|
86
|
+
useSignalR({ onNotification: (n) => {
|
|
87
|
+
if (n.relatedEntityType === '{Entity}') queryClient.invalidateQueries(['{module}']);
|
|
88
|
+
}});
|
|
89
|
+
const createMutation = useMutation({ mutationFn: {module}Api.create, onSuccess: () => ... });
|
|
90
|
+
return { create: createMutation.mutate, ... };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// {Module}Page.tsx with EntityCard
|
|
94
|
+
<EntityCard title={item.name} actions={[{ label: 'View', onClick: () => navigate(...) }]} />
|
|
95
|
+
|
|
96
|
+
// Routes (nested mandatory)
|
|
97
|
+
<Route path="{area}"><Route path="{module}"><Route index element={<{Module}Page />} /></Route></Route>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Phase 7: Integrations
|
|
101
|
+
|
|
102
|
+
### Notifications
|
|
103
|
+
```csharp
|
|
104
|
+
await _notificationService.SendNotificationAsync(userId, NotificationType.{Entity}Created,
|
|
105
|
+
title, message, relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, actionUrl);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Workflow Email
|
|
109
|
+
```csharp
|
|
110
|
+
// 1. WorkflowTriggerConfiguration.cs: new { Code = "{entity}.created", ... }
|
|
111
|
+
// 2. WorkflowConfiguration.cs: new { TriggerId = ..., ... }
|
|
112
|
+
// 3. Service:
|
|
113
|
+
await _workflowService.TriggerAsync("{entity}.created", new Dictionary<string, object>{...});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### AI
|
|
117
|
+
```csharp
|
|
118
|
+
var result = await _aiCompletionService.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
119
|
+
"{entity}-analyzer", new Dictionary<string, object>{ ["name"] = entity.Name }, ct);
|
|
120
|
+
```
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# GitFlow Config Template (v2.1.0)
|
|
2
|
+
|
|
3
|
+
## Configuration JSON
|
|
4
|
+
|
|
5
|
+
Write `.claude/gitflow/config.json` in develop worktree.
|
|
6
|
+
|
|
7
|
+
**IMPORTANT:** Store paths using `normalize_path_for_storage()` format (Windows-style: `D:/path/to/folder`). The `read_gitflow_config()` in `_shared.md` translates them to platform format at read time.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"version": "2.1.0",
|
|
12
|
+
"platform": {
|
|
13
|
+
"detected": "{GF_PLATFORM}",
|
|
14
|
+
"shell": "{GF_SHELL}",
|
|
15
|
+
"detectedAt": "{ISO_DATE}"
|
|
16
|
+
},
|
|
17
|
+
"workspace": {
|
|
18
|
+
"path": "{WORKSPACE_DIR_STORAGE_FORMAT}",
|
|
19
|
+
"name": ""
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"name": "{PROJECT_NAME}",
|
|
23
|
+
"rootFolder": "{ROOT_FOLDER_STORAGE_FORMAT}",
|
|
24
|
+
"nameVariants": {
|
|
25
|
+
"pascalCaseDot": "{PascalCase.Dot}",
|
|
26
|
+
"pascalCase": "{PascalCase}",
|
|
27
|
+
"kebabCase": "{kebab-case}",
|
|
28
|
+
"snakeCase": "{snake_case}",
|
|
29
|
+
"displayName": "{Display Name}"
|
|
30
|
+
},
|
|
31
|
+
"defaultBranch": "main",
|
|
32
|
+
"remoteUrl": "{REPO_URL}"
|
|
33
|
+
},
|
|
34
|
+
"git": {
|
|
35
|
+
"provider": "{GIT_PROVIDER}",
|
|
36
|
+
"branches": {
|
|
37
|
+
"main": "main",
|
|
38
|
+
"develop": "develop"
|
|
39
|
+
},
|
|
40
|
+
"prefixes": {
|
|
41
|
+
"feature": "feature/",
|
|
42
|
+
"release": "release/",
|
|
43
|
+
"hotfix": "hotfix/"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"worktrees": {
|
|
47
|
+
"enabled": true,
|
|
48
|
+
"mode": "{WORKTREE_MODE}",
|
|
49
|
+
"structure": {
|
|
50
|
+
"main": "{ROOT_FOLDER_STORAGE_FORMAT}/01-Main",
|
|
51
|
+
"develop": "{ROOT_FOLDER_STORAGE_FORMAT}/02-Develop",
|
|
52
|
+
"features": "{ROOT_FOLDER_STORAGE_FORMAT}/features",
|
|
53
|
+
"releases": "{ROOT_FOLDER_STORAGE_FORMAT}/releases",
|
|
54
|
+
"hotfixes": "{ROOT_FOLDER_STORAGE_FORMAT}/hotfixes"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"versioning": {
|
|
58
|
+
"strategy": "semver",
|
|
59
|
+
"current": "{VERSION}",
|
|
60
|
+
"tagPrefix": "v",
|
|
61
|
+
"sources": ["csproj", "package.json", "VERSION"]
|
|
62
|
+
},
|
|
63
|
+
"efcore": {
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"validateOnCommit": true,
|
|
66
|
+
"blockDestructive": true,
|
|
67
|
+
"migrationNaming": "{context}_v{version}_{sequence}_{Description}"
|
|
68
|
+
},
|
|
69
|
+
"workflow": {
|
|
70
|
+
"push": { "afterCommit": "worktree" },
|
|
71
|
+
"pr": { "autoLabels": true, "requireReview": true }
|
|
72
|
+
},
|
|
73
|
+
"language": { "code": "{GF_LANG}" }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Path Storage Convention
|
|
78
|
+
|
|
79
|
+
- `{ROOT_FOLDER_STORAGE_FORMAT}` = result of `normalize_path_for_storage("{ROOT_FOLDER}")`
|
|
80
|
+
- On WSL: `/mnt/d/projects/MyApp` -> stored as `D:/projects/MyApp`
|
|
81
|
+
- On Windows: `D:\projects\MyApp` -> stored as `D:/projects/MyApp`
|
|
82
|
+
- On Linux/macOS: `/home/user/projects/MyApp` -> stored as-is
|
|
83
|
+
|
|
84
|
+
## Post-Init Validation
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
PROJECT_BASE="{ROOT_FOLDER}"
|
|
88
|
+
MAIN_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "01-Main" || echo "main")
|
|
89
|
+
DEVELOP_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "02-Develop" || echo "develop")
|
|
90
|
+
ERRORS=0
|
|
91
|
+
|
|
92
|
+
# Verify bare repo
|
|
93
|
+
[ -f "$PROJECT_BASE/.bare/HEAD" ] && echo "OK .bare/HEAD" || { echo "FAIL .bare/HEAD missing"; ERRORS=$((ERRORS+1)); }
|
|
94
|
+
|
|
95
|
+
# Verify worktrees on correct branches
|
|
96
|
+
MAIN_BRANCH=$(git -C "$PROJECT_BASE/$MAIN_DIR" branch --show-current 2>/dev/null)
|
|
97
|
+
[ "$MAIN_BRANCH" = "main" ] && echo "OK $MAIN_DIR on main" || { echo "FAIL $MAIN_DIR on '$MAIN_BRANCH'"; ERRORS=$((ERRORS+1)); }
|
|
98
|
+
|
|
99
|
+
DEVELOP_BRANCH=$(git -C "$PROJECT_BASE/$DEVELOP_DIR" branch --show-current 2>/dev/null)
|
|
100
|
+
[ "$DEVELOP_BRANCH" = "develop" ] && echo "OK $DEVELOP_DIR on develop" || { echo "FAIL $DEVELOP_DIR on '$DEVELOP_BRANCH'"; ERRORS=$((ERRORS+1)); }
|
|
101
|
+
|
|
102
|
+
# Verify directories
|
|
103
|
+
for subdir in features releases hotfixes; do
|
|
104
|
+
[ -d "$PROJECT_BASE/$subdir" ] && echo "OK $subdir/" || { echo "FAIL $subdir/ missing"; ERRORS=$((ERRORS+1)); }
|
|
105
|
+
done
|
|
106
|
+
|
|
107
|
+
# Verify config directory
|
|
108
|
+
[ -d "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow" ] && echo "OK .claude/gitflow/" || { echo "FAIL .claude/gitflow/ missing"; ERRORS=$((ERRORS+1)); }
|
|
109
|
+
|
|
110
|
+
echo ""
|
|
111
|
+
[ "$ERRORS" -eq 0 ] && echo "VALIDATION: ALL CHECKS PASSED" || echo "VALIDATION: $ERRORS error(s) detected"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Workspace Mode (`--workspace`)
|
|
115
|
+
|
|
116
|
+
When called with `init --workspace`, batch-initialize all repos in a workspace.
|
|
117
|
+
|
|
118
|
+
### Workspace Execution Sequence:
|
|
119
|
+
|
|
120
|
+
1. **Ask workspace directory** (AskUserQuestion: parent folder or custom path)
|
|
121
|
+
2. **Detect or ask for repos** (scan workspace for git repos or enter URLs)
|
|
122
|
+
3. **Create `.smartstack-workspace.json`:**
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"version": "1.0.0",
|
|
126
|
+
"name": "{WORKSPACE_NAME}",
|
|
127
|
+
"createdAt": "{ISO_DATE}",
|
|
128
|
+
"updatedAt": "{ISO_DATE}",
|
|
129
|
+
"platform": { "detected": "{GF_PLATFORM}", "shell": "{GF_SHELL}" },
|
|
130
|
+
"repositories": [],
|
|
131
|
+
"defaults": { "provider": "{GIT_PROVIDER}", "worktreeMode": "organized", "language": "en" }
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
4. **Loop: For each repo, run Steps 1-10b with workspace defaults pre-populated.**
|
|
135
|
+
5. **Display global summary** with all repos initialized.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Project Name Normalization (INTELLIGENT)
|
|
2
|
+
|
|
3
|
+
**ALWAYS normalize, even if user chose the detected name.**
|
|
4
|
+
|
|
5
|
+
## Step 1: Parse input into words
|
|
6
|
+
|
|
7
|
+
Split the raw input on any separator: spaces, hyphens, underscores, dots, camelCase boundaries.
|
|
8
|
+
|
|
9
|
+
| Raw input | Parsed words |
|
|
10
|
+
|-----------|-------------|
|
|
11
|
+
| `mon super projet` | `["mon", "super", "projet"]` |
|
|
12
|
+
| `gestion-des-stocks` | `["gestion", "des", "stocks"]` |
|
|
13
|
+
| `my_awesome_app` | `["my", "awesome", "app"]` |
|
|
14
|
+
| `SmartStack.App` | `["Smart", "Stack", "App"]` |
|
|
15
|
+
| `userManagement` | `["user", "Management"]` |
|
|
16
|
+
|
|
17
|
+
## Step 2: Language detection and spell check
|
|
18
|
+
|
|
19
|
+
For EACH word, you MUST:
|
|
20
|
+
1. **Detect the language** (French, English, or technical/proper noun)
|
|
21
|
+
2. **Check spelling** - flag obvious typos
|
|
22
|
+
3. **Suggest corrections** if misspelled
|
|
23
|
+
|
|
24
|
+
| Word | Language | Spelling | Suggestion |
|
|
25
|
+
|------|----------|----------|------------|
|
|
26
|
+
| `gestion` | FR | OK | - |
|
|
27
|
+
| `gestoin` | FR | typo | -> `gestion` |
|
|
28
|
+
| `managment` | EN | typo | -> `management` |
|
|
29
|
+
| `SmartStack` | Proper noun | OK | - |
|
|
30
|
+
| `auth` | EN (abbreviation) | OK | - |
|
|
31
|
+
|
|
32
|
+
**If typos detected**, ask the user BEFORE generating variants:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
AskUserQuestion:
|
|
36
|
+
- header: "Spelling"
|
|
37
|
+
question: "Corrections detected. Accept?"
|
|
38
|
+
options:
|
|
39
|
+
- label: "Accept corrections (Recommended)"
|
|
40
|
+
description: "'gestoin' -> 'gestion', 'managment' -> 'management'"
|
|
41
|
+
- label: "Keep original"
|
|
42
|
+
description: "Use the name as typed"
|
|
43
|
+
multiSelect: false
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Step 3: Generate all name variants
|
|
47
|
+
|
|
48
|
+
From the cleaned words, generate ALL variants:
|
|
49
|
+
|
|
50
|
+
| Variant | Format | Best for |
|
|
51
|
+
|---------|--------|----------|
|
|
52
|
+
| PascalCase.Dot | `Gestion.Des.Stocks` | .NET namespace, C# project, folder name |
|
|
53
|
+
| PascalCase | `GestionDesStocks` | Class name, assembly name |
|
|
54
|
+
| kebab-case | `gestion-des-stocks` | Git repo, npm package, URL slug |
|
|
55
|
+
| snake_case | `gestion_des_stocks` | Database, Python, file system |
|
|
56
|
+
|
|
57
|
+
## Step 4: Ask user to choose the PRIMARY format
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
AskUserQuestion:
|
|
61
|
+
- header: "Format"
|
|
62
|
+
question: "Which format for the project name?"
|
|
63
|
+
options:
|
|
64
|
+
- label: "PascalCase.Dot (Recommended)"
|
|
65
|
+
description: "{PascalCase.Dot variant} - .NET convention"
|
|
66
|
+
- label: "PascalCase"
|
|
67
|
+
description: "{PascalCase variant} - single word"
|
|
68
|
+
- label: "kebab-case"
|
|
69
|
+
description: "{kebab-case variant} - git/npm convention"
|
|
70
|
+
- label: "snake_case"
|
|
71
|
+
description: "{snake_case variant} - database/python convention"
|
|
72
|
+
multiSelect: false
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Step 5: Store all derived names
|
|
76
|
+
|
|
77
|
+
Regardless of the chosen primary format, ALL variants are generated and stored:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"PROJECT_NAME": "{chosen format}",
|
|
82
|
+
"PROJECT_VARIANTS": {
|
|
83
|
+
"pascalCaseDot": "Gestion.Des.Stocks",
|
|
84
|
+
"pascalCase": "GestionDesStocks",
|
|
85
|
+
"kebabCase": "gestion-des-stocks",
|
|
86
|
+
"snakeCase": "gestion_des_stocks",
|
|
87
|
+
"displayName": "Gestion Des Stocks",
|
|
88
|
+
"words": ["gestion", "des", "stocks"],
|
|
89
|
+
"language": "fr"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Real-world examples
|
|
95
|
+
|
|
96
|
+
| User types | PascalCase.Dot | kebab-case | PascalCase |
|
|
97
|
+
|-----------|---------------|------------|------------|
|
|
98
|
+
| `smart stack app` | `SmartStack.App` | `smart-stack-app` | `SmartStackApp` |
|
|
99
|
+
| `gestion-des-stocks` | `Gestion.Des.Stocks` | `gestion-des-stocks` | `GestionDesStocks` |
|
|
100
|
+
| `Mon Projet V2` | `Mon.Projet.V2` | `mon-projet-v2` | `MonProjetV2` |
|
|
101
|
+
| `user auth module` | `User.Auth.Module` | `user-auth-module` | `UserAuthModule` |
|
|
102
|
+
| `PROJET TEST` | `Projet.Test` | `projet-test` | `ProjetTest` |
|
|
103
|
+
| `e-commerce platform` | `ECommerce.Platform` | `e-commerce-platform` | `ECommercePlatform` |
|