@atlashub/smartstack-cli 1.37.0 → 2.1.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/agents.html +147 -40
- package/.documentation/apex.html +1 -1
- package/.documentation/business-analyse.html +3 -3
- package/.documentation/cli-commands.html +2 -2
- package/.documentation/commands.html +14 -14
- package/.documentation/efcore.html +14 -14
- package/.documentation/gitflow.html +12 -12
- package/.documentation/hooks.html +41 -3
- package/.documentation/index.html +1 -1
- package/.documentation/init.html +2 -2
- package/.documentation/installation.html +11 -11
- package/.documentation/js/app.js +1 -1
- package/.documentation/ralph-loop.html +1 -1
- package/.documentation/test-web.html +4 -4
- package/config/mcp-defaults.json +62 -0
- package/dist/index.js +58 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +70010 -0
- package/dist/mcp-entry.mjs.map +1 -0
- package/package.json +14 -5
- package/templates/agents/gitflow/start.md +5 -4
- package/templates/agents/mcp-healthcheck.md +15 -13
- package/templates/mcp-scaffolding/component.tsx.hbs +298 -0
- package/templates/mcp-scaffolding/controller.cs.hbs +184 -0
- package/templates/mcp-scaffolding/entity-extension.cs.hbs +231 -0
- package/templates/mcp-scaffolding/frontend/api-client.ts.hbs +116 -0
- package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +133 -0
- package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +134 -0
- package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +261 -0
- package/templates/mcp-scaffolding/service-extension.cs.hbs +53 -0
- package/templates/mcp-scaffolding/tests/controller.test.cs.hbs +413 -0
- package/templates/mcp-scaffolding/tests/entity.test.cs.hbs +239 -0
- package/templates/mcp-scaffolding/tests/repository.test.cs.hbs +441 -0
- package/templates/mcp-scaffolding/tests/security.test.cs.hbs +442 -0
- package/templates/mcp-scaffolding/tests/service.test.cs.hbs +390 -0
- package/templates/mcp-scaffolding/tests/validator.test.cs.hbs +428 -0
- package/templates/ralph/README.md +3 -3
- package/templates/ralph/ralph.config.yaml +2 -2
- package/templates/skills/admin/SKILL.md +42 -0
- package/templates/skills/business-analyse/_shared.md +79 -15
- package/templates/skills/business-analyse/questionnaire/01-context.md +4 -4
- package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +3 -3
- package/templates/skills/business-analyse/questionnaire/03-scope.md +4 -4
- package/templates/skills/business-analyse/questionnaire/04-data.md +7 -7
- package/templates/skills/business-analyse/questionnaire/05-integrations.md +1 -1
- package/templates/skills/business-analyse/questionnaire/06-security.md +3 -3
- package/templates/skills/business-analyse/questionnaire/07-ui.md +1 -1
- package/templates/skills/business-analyse/questionnaire/08-performance.md +3 -3
- package/templates/skills/business-analyse/questionnaire/09-constraints.md +4 -4
- package/templates/skills/business-analyse/questionnaire/10-documentation.md +2 -2
- package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +2 -2
- package/templates/skills/business-analyse/questionnaire/12-migration.md +1 -1
- package/templates/skills/business-analyse/questionnaire/13-cross-module.md +2 -2
- package/templates/skills/business-analyse/steps/step-01-discover.md +50 -25
- package/templates/skills/business-analyse/steps/step-03-specify.md +63 -0
- package/templates/skills/business-analyse/steps/step-04-validate.md +23 -1
- package/templates/skills/business-analyse/steps/step-05-handoff.md +248 -66
- package/templates/skills/business-analyse/templates/tpl-handoff.md +99 -23
- package/templates/skills/cc-agent/SKILL.md +129 -0
- package/templates/skills/cc-agent/references/agent-frontmatter.md +213 -0
- package/templates/skills/cc-agent/references/permission-modes.md +102 -0
- package/templates/skills/cc-agent/references/tools-reference.md +144 -0
- package/templates/skills/cc-agent/steps/step-00-init.md +134 -0
- package/templates/skills/cc-agent/steps/step-01-design.md +186 -0
- package/templates/skills/cc-agent/steps/step-02-generate.md +204 -0
- package/templates/skills/cc-agent/steps/step-03-validate.md +130 -0
- package/templates/skills/cc-agent/templates/agent-categorized.md +67 -0
- package/templates/skills/cc-agent/templates/agent-standalone.md +56 -0
- package/templates/skills/cc-agent/templates/agent-with-skills.md +94 -0
- package/templates/skills/cc-audit/SKILL.md +108 -0
- package/templates/skills/cc-audit/references/agent-checklist.md +91 -0
- package/templates/skills/cc-audit/references/hook-checklist.md +110 -0
- package/templates/skills/cc-audit/references/skill-checklist.md +70 -0
- package/templates/skills/cc-audit/steps/step-00-init.md +98 -0
- package/templates/skills/cc-audit/steps/step-01-scan.md +142 -0
- package/templates/skills/cc-audit/steps/step-02-analyze.md +158 -0
- package/templates/skills/cc-audit/steps/step-03-report.md +142 -0
- package/templates/skills/cc-skill/SKILL.md +134 -0
- package/templates/skills/cc-skill/references/best-practices.md +167 -0
- package/templates/skills/cc-skill/references/frontmatter-reference.md +182 -0
- package/templates/skills/cc-skill/references/skill-patterns.md +199 -0
- package/templates/skills/cc-skill/steps/step-00-init.md +119 -0
- package/templates/skills/cc-skill/steps/step-01-design.md +199 -0
- package/templates/skills/cc-skill/steps/step-02-generate.md +145 -0
- package/templates/skills/cc-skill/steps/step-03-steps.md +151 -0
- package/templates/skills/cc-skill/steps/step-04-validate.md +124 -0
- package/templates/skills/cc-skill/templates/skill-forked.md +85 -0
- package/templates/skills/cc-skill/templates/skill-progressive.md +102 -0
- package/templates/skills/cc-skill/templates/skill-simple.md +75 -0
- package/templates/skills/cc-skill/templates/step-template.md +82 -0
- package/templates/skills/check-version/SKILL.md +6 -0
- package/templates/skills/controller/templates.md +82 -0
- package/templates/skills/debug/SKILL.md +4 -0
- package/templates/skills/documentation/SKILL.md +1 -0
- package/templates/skills/efcore/SKILL.md +5 -0
- package/templates/skills/efcore/references/zero-downtime-patterns.md +227 -0
- package/templates/skills/efcore/steps/db/step-deploy.md +26 -5
- package/templates/skills/efcore/steps/migration/step-03-validate.md +19 -0
- package/templates/skills/efcore/steps/shared/step-00-init.md +21 -7
- package/templates/skills/explore/SKILL.md +28 -32
- package/templates/skills/feature-full/SKILL.md +1 -0
- package/templates/skills/gitflow/SKILL.md +8 -0
- package/templates/skills/gitflow/steps/step-start.md +45 -10
- package/templates/skills/mcp/SKILL.md +38 -18
- package/templates/skills/quick-search/SKILL.md +8 -1
- package/templates/skills/ralph-loop/SKILL.md +1 -1
- package/templates/skills/ralph-loop/steps/step-00-init.md +8 -68
- package/templates/skills/ralph-loop/steps/step-04-check.md +1 -1
- package/templates/skills/refactor/SKILL.md +1 -0
- package/templates/skills/review-code/SKILL.md +11 -3
- package/templates/skills/review-code/references/owasp-api-top10.md +243 -0
- package/templates/skills/review-code/references/security-checklist.md +86 -1
- package/templates/skills/review-code/references/smartstack-conventions.md +166 -0
- package/templates/skills/ui-components/SKILL.md +31 -438
- package/templates/skills/ui-components/accessibility.md +170 -0
- package/templates/skills/ui-components/patterns/data-table.md +39 -0
- package/templates/skills/ui-components/patterns/entity-card.md +77 -0
- package/templates/skills/ui-components/patterns/grid-layout.md +91 -0
- package/templates/skills/ui-components/patterns/kanban.md +43 -0
- package/templates/skills/ui-components/style-guide.md +86 -0
- package/templates/skills/utils/SKILL.md +1 -0
- package/templates/skills/validate/SKILL.md +1 -0
- package/templates/skills/workflow/SKILL.md +27 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Template: Progressive Step Loading Skill
|
|
2
|
+
|
|
3
|
+
Use this template when creating a complex skill with multiple phases that benefit from progressive step loading.
|
|
4
|
+
|
|
5
|
+
## Generated SKILL.md format:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
---
|
|
9
|
+
name: {{SKILL_NAME}}
|
|
10
|
+
description: |
|
|
11
|
+
{{DESCRIPTION}}
|
|
12
|
+
{{#if ARGUMENT_HINT}}
|
|
13
|
+
argument-hint: "{{ARGUMENT_HINT}}"
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if DISABLE_MODEL_INVOCATION}}
|
|
16
|
+
disable-model-invocation: true
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if MODEL}}
|
|
19
|
+
model: {{MODEL}}
|
|
20
|
+
{{/if}}
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<objective>
|
|
24
|
+
{{OBJECTIVE}}
|
|
25
|
+
</objective>
|
|
26
|
+
|
|
27
|
+
<quick_start>
|
|
28
|
+
|
|
29
|
+
` ` `bash
|
|
30
|
+
/{{SKILL_NAME}} {{EXAMPLE_ARGS_1}}
|
|
31
|
+
/{{SKILL_NAME}} {{EXAMPLE_ARGS_2}}
|
|
32
|
+
` ` `
|
|
33
|
+
|
|
34
|
+
</quick_start>
|
|
35
|
+
|
|
36
|
+
<parameters>
|
|
37
|
+
|
|
38
|
+
<flags>
|
|
39
|
+
| Flag | Description |
|
|
40
|
+
|------|-------------|
|
|
41
|
+
| {{FLAG_SHORT}} | {{FLAG_DESCRIPTION}} |
|
|
42
|
+
</flags>
|
|
43
|
+
|
|
44
|
+
<examples>
|
|
45
|
+
` ` `bash
|
|
46
|
+
/{{SKILL_NAME}} {{EXAMPLE_1}}
|
|
47
|
+
/{{SKILL_NAME}} {{EXAMPLE_2}}
|
|
48
|
+
` ` `
|
|
49
|
+
</examples>
|
|
50
|
+
|
|
51
|
+
</parameters>
|
|
52
|
+
|
|
53
|
+
<workflow>
|
|
54
|
+
{{#each STEPS}}
|
|
55
|
+
{{@index_plus_one}}. {{this.title}}
|
|
56
|
+
{{/each}}
|
|
57
|
+
</workflow>
|
|
58
|
+
|
|
59
|
+
<state_variables>
|
|
60
|
+
| Variable | Type | Description |
|
|
61
|
+
|----------|------|-------------|
|
|
62
|
+
{{#each STATE_VARS}}
|
|
63
|
+
| `{ {{this.name}} }` | {{this.type}} | {{this.description}} |
|
|
64
|
+
{{/each}}
|
|
65
|
+
</state_variables>
|
|
66
|
+
|
|
67
|
+
<entry_point>
|
|
68
|
+
|
|
69
|
+
**FIRST ACTION:** Load `steps/step-00-init.md`
|
|
70
|
+
|
|
71
|
+
</entry_point>
|
|
72
|
+
|
|
73
|
+
<step_files>
|
|
74
|
+
| Step | File | Purpose |
|
|
75
|
+
|------|------|---------|
|
|
76
|
+
{{#each STEPS}}
|
|
77
|
+
| {{this.number}} | `steps/step-{{this.number}}-{{this.name}}.md` | {{this.description}} |
|
|
78
|
+
{{/each}}
|
|
79
|
+
</step_files>
|
|
80
|
+
|
|
81
|
+
<execution_rules>
|
|
82
|
+
- **Load one step at a time** - Progressive loading to minimize context
|
|
83
|
+
- **Persist state variables** across all steps
|
|
84
|
+
- **Follow next_step directive** at end of each step
|
|
85
|
+
- {{RULE_1}}
|
|
86
|
+
- {{RULE_2}}
|
|
87
|
+
</execution_rules>
|
|
88
|
+
|
|
89
|
+
<success_criteria>
|
|
90
|
+
- {{CRITERIA_1}}
|
|
91
|
+
- {{CRITERIA_2}}
|
|
92
|
+
- {{CRITERIA_3}}
|
|
93
|
+
</success_criteria>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Notes:
|
|
97
|
+
- Keep SKILL.md under 500 lines (detailed content goes in steps)
|
|
98
|
+
- Each step should be self-contained
|
|
99
|
+
- State variables persist across all steps
|
|
100
|
+
- Always start with step-00-init for argument parsing
|
|
101
|
+
- Always end with a validation/summary step
|
|
102
|
+
- Best for: workflows, generators, multi-phase operations
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Template: Simple Skill
|
|
2
|
+
|
|
3
|
+
Use this template when creating a skill that fits in a single SKILL.md file without progressive step loading.
|
|
4
|
+
|
|
5
|
+
## Generated SKILL.md format:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
---
|
|
9
|
+
name: {{SKILL_NAME}}
|
|
10
|
+
description: |
|
|
11
|
+
{{DESCRIPTION}}
|
|
12
|
+
{{#if ARGUMENT_HINT}}
|
|
13
|
+
argument-hint: "{{ARGUMENT_HINT}}"
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if DISABLE_MODEL_INVOCATION}}
|
|
16
|
+
disable-model-invocation: true
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if USER_INVOCABLE_FALSE}}
|
|
19
|
+
user-invocable: false
|
|
20
|
+
{{/if}}
|
|
21
|
+
{{#if MODEL}}
|
|
22
|
+
model: {{MODEL}}
|
|
23
|
+
{{/if}}
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<objective>
|
|
27
|
+
{{OBJECTIVE}}
|
|
28
|
+
</objective>
|
|
29
|
+
|
|
30
|
+
<quick_start>
|
|
31
|
+
|
|
32
|
+
` ` `bash
|
|
33
|
+
/{{SKILL_NAME}} {{EXAMPLE_ARGS_1}}
|
|
34
|
+
/{{SKILL_NAME}} {{EXAMPLE_ARGS_2}}
|
|
35
|
+
` ` `
|
|
36
|
+
|
|
37
|
+
</quick_start>
|
|
38
|
+
|
|
39
|
+
## Task
|
|
40
|
+
{{TASK_DESCRIPTION}}
|
|
41
|
+
|
|
42
|
+
$ARGUMENTS
|
|
43
|
+
|
|
44
|
+
<workflow>
|
|
45
|
+
|
|
46
|
+
## 1. {{FIRST_PHASE}}
|
|
47
|
+
{{FIRST_PHASE_INSTRUCTIONS}}
|
|
48
|
+
|
|
49
|
+
## 2. {{SECOND_PHASE}}
|
|
50
|
+
{{SECOND_PHASE_INSTRUCTIONS}}
|
|
51
|
+
|
|
52
|
+
## 3. {{THIRD_PHASE}}
|
|
53
|
+
{{THIRD_PHASE_INSTRUCTIONS}}
|
|
54
|
+
|
|
55
|
+
</workflow>
|
|
56
|
+
|
|
57
|
+
<execution_rules>
|
|
58
|
+
- {{RULE_1}}
|
|
59
|
+
- {{RULE_2}}
|
|
60
|
+
- {{RULE_3}}
|
|
61
|
+
</execution_rules>
|
|
62
|
+
|
|
63
|
+
<success_criteria>
|
|
64
|
+
- {{CRITERIA_1}}
|
|
65
|
+
- {{CRITERIA_2}}
|
|
66
|
+
- {{CRITERIA_3}}
|
|
67
|
+
</success_criteria>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Notes:
|
|
71
|
+
- Keep total lines under 500
|
|
72
|
+
- Description should include trigger keywords for auto-detection
|
|
73
|
+
- Use $ARGUMENTS to reference user input
|
|
74
|
+
- Workflow steps are inline (no external step files)
|
|
75
|
+
- Best for: linting, simple generation, knowledge injection, quick commands
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Template: Step File
|
|
2
|
+
|
|
3
|
+
Standard template for a progressive step loading step file.
|
|
4
|
+
|
|
5
|
+
## Generated step file format:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
---
|
|
9
|
+
name: step-{{NUMBER}}-{{NAME}}
|
|
10
|
+
description: {{DESCRIPTION}}
|
|
11
|
+
{{#if NEXT_STEP}}
|
|
12
|
+
next_step: steps/step-{{NEXT_NUMBER}}-{{NEXT_NAME}}.md
|
|
13
|
+
{{/if}}
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Step {{N}}: {{TITLE}}
|
|
17
|
+
|
|
18
|
+
## MANDATORY EXECUTION RULES:
|
|
19
|
+
- {{RULE_1}}
|
|
20
|
+
- {{RULE_2}}
|
|
21
|
+
- FORBIDDEN to proceed to next step until this step is complete
|
|
22
|
+
|
|
23
|
+
## YOUR TASK:
|
|
24
|
+
{{TASK_DESCRIPTION}}
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## EXECUTION SEQUENCE:
|
|
29
|
+
|
|
30
|
+
### 1. {{SUBTASK_1_TITLE}}
|
|
31
|
+
{{SUBTASK_1_INSTRUCTIONS}}
|
|
32
|
+
|
|
33
|
+
### 2. {{SUBTASK_2_TITLE}}
|
|
34
|
+
{{SUBTASK_2_INSTRUCTIONS}}
|
|
35
|
+
|
|
36
|
+
### 3. Show Summary
|
|
37
|
+
Display step results in compact format (table preferred).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## SUCCESS METRICS:
|
|
42
|
+
- {{METRIC_1}}
|
|
43
|
+
- {{METRIC_2}}
|
|
44
|
+
- Output is compact and scannable
|
|
45
|
+
|
|
46
|
+
## NEXT STEP:
|
|
47
|
+
{{#if NEXT_STEP}}
|
|
48
|
+
After showing summary, proceed directly to `./step-{{NEXT_NUMBER}}-{{NEXT_NAME}}.md`
|
|
49
|
+
{{else}}
|
|
50
|
+
This is the final step. Skill execution is complete.
|
|
51
|
+
{{/if}}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Step Types:
|
|
55
|
+
|
|
56
|
+
### Init Step (step-00)
|
|
57
|
+
- Parse arguments and flags
|
|
58
|
+
- Validate required inputs
|
|
59
|
+
- Initialize state variables
|
|
60
|
+
- Show configuration summary
|
|
61
|
+
|
|
62
|
+
### Analysis Step
|
|
63
|
+
- Read files, search codebase
|
|
64
|
+
- Extract patterns and information
|
|
65
|
+
- Show findings summary
|
|
66
|
+
|
|
67
|
+
### Generation Step
|
|
68
|
+
- Use templates or references
|
|
69
|
+
- Create/modify files
|
|
70
|
+
- Show what was generated
|
|
71
|
+
|
|
72
|
+
### Validation Step (usually last)
|
|
73
|
+
- Check generated output
|
|
74
|
+
- Verify conventions
|
|
75
|
+
- Display final summary and next steps
|
|
76
|
+
|
|
77
|
+
## Rules:
|
|
78
|
+
- Each step MUST be self-contained (loadable independently)
|
|
79
|
+
- State variables persist via conversation context
|
|
80
|
+
- Always show compact summary before proceeding
|
|
81
|
+
- Always reference next step at the end
|
|
82
|
+
- Last step must NOT have next_step in frontmatter
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: check-version
|
|
3
3
|
description: Verify version alignment between package.json and documentation
|
|
4
|
+
context: fork
|
|
5
|
+
agent: Explore
|
|
4
6
|
model: haiku
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash
|
|
5
8
|
---
|
|
6
9
|
|
|
10
|
+
## Current state (auto-injected)
|
|
11
|
+
- Package version: !`node -p "require('./package.json').version" 2>/dev/null || echo "no package.json"`
|
|
12
|
+
|
|
7
13
|
<objective>
|
|
8
14
|
Verify that the version in `package.json` is aligned with all documentation files in `.documentation/`.
|
|
9
15
|
Use before releases or as part of release process to ensure documentation is up-to-date.
|
|
@@ -1461,8 +1461,90 @@ public record BulkUpdate{Entity}Request(
|
|
|
1461
1461
|
□ EF Core Migration created
|
|
1462
1462
|
□ Migration applied
|
|
1463
1463
|
|
|
1464
|
+
□ API Versioning (if applicable)
|
|
1465
|
+
□ See API Versioning section below
|
|
1466
|
+
|
|
1464
1467
|
□ Correct Permission Level
|
|
1465
1468
|
□ Module (Level 3) - For main CRUD
|
|
1466
1469
|
□ Section (Level 4) - If sub-pages with different permissions
|
|
1467
1470
|
□ Resource (Level 5) - If sub-resources with distinct permissions
|
|
1468
1471
|
```
|
|
1472
|
+
|
|
1473
|
+
---
|
|
1474
|
+
|
|
1475
|
+
## API Versioning
|
|
1476
|
+
|
|
1477
|
+
**SmartStack convention:** Header-based versioning using `Asp.Versioning.Mvc`.
|
|
1478
|
+
|
|
1479
|
+
### Setup
|
|
1480
|
+
|
|
1481
|
+
```csharp
|
|
1482
|
+
// Program.cs
|
|
1483
|
+
builder.Services.AddApiVersioning(options =>
|
|
1484
|
+
{
|
|
1485
|
+
options.DefaultApiVersion = new ApiVersion(1, 0);
|
|
1486
|
+
options.AssumeDefaultVersionWhenUnspecified = true;
|
|
1487
|
+
options.ReportApiVersions = true; // Adds api-supported-versions header
|
|
1488
|
+
options.ApiVersionReader = new HeaderApiVersionReader("api-version");
|
|
1489
|
+
})
|
|
1490
|
+
.AddApiExplorer(options =>
|
|
1491
|
+
{
|
|
1492
|
+
options.GroupNameFormat = "'v'VVV";
|
|
1493
|
+
options.SubstituteApiVersionInUrl = true;
|
|
1494
|
+
});
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
### Controller Usage
|
|
1498
|
+
|
|
1499
|
+
```csharp
|
|
1500
|
+
// v1 - Default (no attribute needed if only one version exists)
|
|
1501
|
+
[ApiController]
|
|
1502
|
+
[ApiVersion("1.0")]
|
|
1503
|
+
[NavRoute("business.crm.contacts")]
|
|
1504
|
+
public class ContactsController : ControllerBase
|
|
1505
|
+
{
|
|
1506
|
+
[HttpGet]
|
|
1507
|
+
[RequirePermission(Permissions.Business.Crm.Contacts.Read)]
|
|
1508
|
+
public async Task<ActionResult<PagedResult<ContactDto>>> GetAll(...) { ... }
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// v2 - Breaking changes only
|
|
1512
|
+
[ApiController]
|
|
1513
|
+
[ApiVersion("2.0")]
|
|
1514
|
+
[NavRoute("business.crm.contacts")]
|
|
1515
|
+
public class ContactsV2Controller : ControllerBase
|
|
1516
|
+
{
|
|
1517
|
+
[HttpGet]
|
|
1518
|
+
[RequirePermission(Permissions.Business.Crm.Contacts.Read)]
|
|
1519
|
+
public async Task<ActionResult<PagedResult<ContactV2Dto>>> GetAll(...) { ... }
|
|
1520
|
+
}
|
|
1521
|
+
```
|
|
1522
|
+
|
|
1523
|
+
### Deprecation
|
|
1524
|
+
|
|
1525
|
+
```csharp
|
|
1526
|
+
[ApiVersion("1.0", Deprecated = true)] // Adds api-deprecated-versions header
|
|
1527
|
+
[ApiVersion("2.0")]
|
|
1528
|
+
public class ContactsController : ControllerBase
|
|
1529
|
+
{
|
|
1530
|
+
[HttpGet]
|
|
1531
|
+
[MapToApiVersion("1.0")]
|
|
1532
|
+
public async Task<ActionResult<PagedResult<ContactDto>>> GetAllV1(...) { ... }
|
|
1533
|
+
|
|
1534
|
+
[HttpGet]
|
|
1535
|
+
[MapToApiVersion("2.0")]
|
|
1536
|
+
public async Task<ActionResult<PagedResult<ContactV2Dto>>> GetAllV2(...) { ... }
|
|
1537
|
+
}
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1540
|
+
### SmartStack Versioning Rules
|
|
1541
|
+
|
|
1542
|
+
| Rule | Detail |
|
|
1543
|
+
|------|--------|
|
|
1544
|
+
| Default version | `1.0` (assumed when no header sent) |
|
|
1545
|
+
| Version header | `api-version: 2.0` |
|
|
1546
|
+
| When to version | Breaking changes only (field removal, type change, behavior change) |
|
|
1547
|
+
| Non-breaking changes | Add to existing version (new fields, new endpoints) |
|
|
1548
|
+
| Naming | `V2Controller` suffix or `[MapToApiVersion]` in same controller |
|
|
1549
|
+
| Deprecation | Mark old version deprecated, maintain for 2 releases minimum |
|
|
1550
|
+
| Documentation | Both versions documented via `[ProducesResponseType]` |
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
name: debug
|
|
3
3
|
description: Systematic bug debugging with deep analysis and resolution
|
|
4
4
|
argument-hint: <log|error|problem-description>
|
|
5
|
+
model: opus
|
|
5
6
|
---
|
|
6
7
|
|
|
8
|
+
## Bug to investigate
|
|
9
|
+
$ARGUMENTS
|
|
10
|
+
|
|
7
11
|
<objective>
|
|
8
12
|
Follow an ultra-deep analysis workflow to identify, understand, and resolve bugs.
|
|
9
13
|
**ULTRA THINK** at each phase transition.
|
|
@@ -9,6 +9,7 @@ description: |
|
|
|
9
9
|
- After implementing a feature to generate its documentation
|
|
10
10
|
Types: user module, developer tools, database ERD, testing tools
|
|
11
11
|
argument-hint: "<module-name> [--type user|developer|database|testing|update]"
|
|
12
|
+
model: sonnet
|
|
12
13
|
---
|
|
13
14
|
|
|
14
15
|
<objective>
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
name: efcore
|
|
3
3
|
description: EF Core Commands - Migration and database management
|
|
4
4
|
argument-hint: "<command> [options]"
|
|
5
|
+
disable-model-invocation: true
|
|
5
6
|
---
|
|
6
7
|
|
|
8
|
+
## Current state (auto-injected)
|
|
9
|
+
- Branch: !`git branch --show-current`
|
|
10
|
+
- Recent migrations: !`find . -path "*/Migrations/*.cs" -not -name "*Designer*" -not -name "*Snapshot*" 2>/dev/null | sort | tail -5 || echo "none found"`
|
|
11
|
+
|
|
7
12
|
<objective>
|
|
8
13
|
Manage EF Core migrations and database operations with progressive step loading, MCP validation, and DbContext auto-detection.
|
|
9
14
|
</objective>
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Zero-downtime migration patterns for EF Core. Use when a migration contains destructive operations (column rename, type change, column drop) that could cause downtime during deployment.
|
|
3
|
+
|
|
4
|
+
These patterns apply to production deployments where the application runs continuously. For development environments, standard migrations are sufficient.
|
|
5
|
+
</overview>
|
|
6
|
+
|
|
7
|
+
<when_to_use>
|
|
8
|
+
## When These Patterns Apply
|
|
9
|
+
|
|
10
|
+
**Destructive operations requiring zero-downtime strategy:**
|
|
11
|
+
- `RenameColumn` / `RenameTable`
|
|
12
|
+
- `DropColumn` / `DropTable`
|
|
13
|
+
- `AlterColumn` (type change, nullability change)
|
|
14
|
+
|
|
15
|
+
**Safe operations (no special handling needed):**
|
|
16
|
+
- `AddColumn` (nullable or with default value)
|
|
17
|
+
- `CreateTable`
|
|
18
|
+
- `CreateIndex`
|
|
19
|
+
- `AddForeignKey`
|
|
20
|
+
</when_to_use>
|
|
21
|
+
|
|
22
|
+
<column_rename>
|
|
23
|
+
## Pattern 1: Column Rename (5 phases)
|
|
24
|
+
|
|
25
|
+
A column rename cannot be done atomically without downtime. Use a phased approach across multiple deployments.
|
|
26
|
+
|
|
27
|
+
### Phase 1 - Add New Column (Migration 1)
|
|
28
|
+
```csharp
|
|
29
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
30
|
+
{
|
|
31
|
+
migrationBuilder.AddColumn<string>(
|
|
32
|
+
name: "FullName",
|
|
33
|
+
table: "auth_users",
|
|
34
|
+
schema: "core",
|
|
35
|
+
type: "nvarchar(256)",
|
|
36
|
+
nullable: true); // Must be nullable initially
|
|
37
|
+
|
|
38
|
+
// Backfill existing data
|
|
39
|
+
migrationBuilder.Sql(
|
|
40
|
+
"UPDATE core.auth_users SET FullName = DisplayName WHERE FullName IS NULL");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
protected override void Down(MigrationBuilder migrationBuilder)
|
|
44
|
+
{
|
|
45
|
+
migrationBuilder.DropColumn(name: "FullName", table: "auth_users", schema: "core");
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Phase 2 - Dual-Write Code (Application deployment)
|
|
50
|
+
```csharp
|
|
51
|
+
// Entity writes to BOTH columns during transition
|
|
52
|
+
public void UpdateName(string name)
|
|
53
|
+
{
|
|
54
|
+
DisplayName = name; // Old column
|
|
55
|
+
FullName = name; // New column
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Phase 3 - Backfill Remaining Data (Migration 2, optional)
|
|
60
|
+
```csharp
|
|
61
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
62
|
+
{
|
|
63
|
+
// Catch any rows missed during dual-write transition
|
|
64
|
+
migrationBuilder.Sql(
|
|
65
|
+
"UPDATE core.auth_users SET FullName = DisplayName WHERE FullName IS NULL");
|
|
66
|
+
|
|
67
|
+
// Make new column non-nullable
|
|
68
|
+
migrationBuilder.AlterColumn<string>(
|
|
69
|
+
name: "FullName",
|
|
70
|
+
table: "auth_users",
|
|
71
|
+
schema: "core",
|
|
72
|
+
type: "nvarchar(256)",
|
|
73
|
+
nullable: false,
|
|
74
|
+
defaultValue: "");
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Phase 4 - Switch Reads (Application deployment)
|
|
79
|
+
```csharp
|
|
80
|
+
// Entity now reads from new column only
|
|
81
|
+
public string Name => FullName;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Phase 5 - Drop Old Column (Migration 3)
|
|
85
|
+
```csharp
|
|
86
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
87
|
+
{
|
|
88
|
+
migrationBuilder.DropColumn(name: "DisplayName", table: "auth_users", schema: "core");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected override void Down(MigrationBuilder migrationBuilder)
|
|
92
|
+
{
|
|
93
|
+
migrationBuilder.AddColumn<string>(
|
|
94
|
+
name: "DisplayName",
|
|
95
|
+
table: "auth_users",
|
|
96
|
+
schema: "core",
|
|
97
|
+
type: "nvarchar(256)",
|
|
98
|
+
nullable: false,
|
|
99
|
+
defaultValue: "");
|
|
100
|
+
|
|
101
|
+
migrationBuilder.Sql(
|
|
102
|
+
"UPDATE core.auth_users SET DisplayName = FullName");
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
</column_rename>
|
|
106
|
+
|
|
107
|
+
<column_type_change>
|
|
108
|
+
## Pattern 2: Column Type Change (4 phases)
|
|
109
|
+
|
|
110
|
+
Changing a column type (e.g., `int` to `string`, `string` to `decimal`) follows the same dual-column approach.
|
|
111
|
+
|
|
112
|
+
### Phase 1 - Add New Typed Column
|
|
113
|
+
```csharp
|
|
114
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
115
|
+
{
|
|
116
|
+
migrationBuilder.AddColumn<decimal>(
|
|
117
|
+
name: "PriceDecimal",
|
|
118
|
+
table: "extensions_products",
|
|
119
|
+
schema: "extensions",
|
|
120
|
+
type: "decimal(18,2)",
|
|
121
|
+
nullable: true);
|
|
122
|
+
|
|
123
|
+
migrationBuilder.Sql(
|
|
124
|
+
"UPDATE extensions.extensions_products SET PriceDecimal = CAST(Price AS decimal(18,2))");
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Phase 2 - Dual-Write in Code
|
|
129
|
+
### Phase 3 - Make Non-Nullable + Switch Reads
|
|
130
|
+
### Phase 4 - Drop Old Column
|
|
131
|
+
|
|
132
|
+
Same phased pattern as column rename.
|
|
133
|
+
</column_type_change>
|
|
134
|
+
|
|
135
|
+
<large_table_operations>
|
|
136
|
+
## Pattern 3: Large Table Backfill
|
|
137
|
+
|
|
138
|
+
For tables with millions of rows, batch the backfill to avoid lock escalation.
|
|
139
|
+
|
|
140
|
+
```csharp
|
|
141
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
142
|
+
{
|
|
143
|
+
migrationBuilder.AddColumn<string>(
|
|
144
|
+
name: "NormalizedEmail",
|
|
145
|
+
table: "auth_users",
|
|
146
|
+
schema: "core",
|
|
147
|
+
type: "nvarchar(256)",
|
|
148
|
+
nullable: true);
|
|
149
|
+
|
|
150
|
+
// Batched backfill to avoid table locks
|
|
151
|
+
migrationBuilder.Sql(@"
|
|
152
|
+
DECLARE @BatchSize INT = 5000;
|
|
153
|
+
DECLARE @RowsAffected INT = 1;
|
|
154
|
+
|
|
155
|
+
WHILE @RowsAffected > 0
|
|
156
|
+
BEGIN
|
|
157
|
+
UPDATE TOP (@BatchSize) core.auth_users
|
|
158
|
+
SET NormalizedEmail = UPPER(Email)
|
|
159
|
+
WHERE NormalizedEmail IS NULL;
|
|
160
|
+
|
|
161
|
+
SET @RowsAffected = @@ROWCOUNT;
|
|
162
|
+
END
|
|
163
|
+
");
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Rules:**
|
|
168
|
+
- Batch size: 1,000-10,000 rows depending on table width
|
|
169
|
+
- Always include a `WHERE` clause to avoid re-processing
|
|
170
|
+
- Monitor transaction log growth during execution
|
|
171
|
+
- Run during low-traffic windows if possible
|
|
172
|
+
</large_table_operations>
|
|
173
|
+
|
|
174
|
+
<rollback_strategy>
|
|
175
|
+
## Rollback Strategies
|
|
176
|
+
|
|
177
|
+
### Migration Down() Method
|
|
178
|
+
Every migration MUST have a functional `Down()` method for rollback:
|
|
179
|
+
|
|
180
|
+
```csharp
|
|
181
|
+
protected override void Down(MigrationBuilder migrationBuilder)
|
|
182
|
+
{
|
|
183
|
+
// Reverse the operation
|
|
184
|
+
migrationBuilder.DropColumn(name: "NewColumn", table: "auth_users", schema: "core");
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Rollback Command
|
|
189
|
+
```bash
|
|
190
|
+
# Rollback to specific migration
|
|
191
|
+
dotnet ef database update {PreviousMigrationName} \
|
|
192
|
+
--context $DBCONTEXT \
|
|
193
|
+
--project $INFRA_PROJECT \
|
|
194
|
+
--startup-project $STARTUP_PROJECT
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Pre-Deployment Checklist
|
|
198
|
+
- [ ] `Down()` method tested locally
|
|
199
|
+
- [ ] Database backup taken before deployment
|
|
200
|
+
- [ ] Application compatible with both old and new schema (dual-write phase)
|
|
201
|
+
- [ ] Rollback procedure documented in deployment notes
|
|
202
|
+
- [ ] Monitoring alerts configured for error spike
|
|
203
|
+
</rollback_strategy>
|
|
204
|
+
|
|
205
|
+
<decision_guide>
|
|
206
|
+
## Decision Guide
|
|
207
|
+
|
|
208
|
+
| Operation | Risk | Strategy |
|
|
209
|
+
|-----------|------|----------|
|
|
210
|
+
| Add nullable column | Low | Standard migration |
|
|
211
|
+
| Add column with default | Low | Standard migration |
|
|
212
|
+
| Create table | Low | Standard migration |
|
|
213
|
+
| Create index | Medium | `CREATE INDEX CONCURRENTLY` if supported |
|
|
214
|
+
| Rename column | High | 5-phase pattern |
|
|
215
|
+
| Change column type | High | 4-phase pattern |
|
|
216
|
+
| Drop column | High | Verify no reads, then drop |
|
|
217
|
+
| Drop table | High | Verify no references, then drop |
|
|
218
|
+
| Make column non-nullable | Medium | Ensure no NULL values exist first |
|
|
219
|
+
|
|
220
|
+
**Rule of thumb:** If the operation would cause a `SqlException` on running code, use a phased approach.
|
|
221
|
+
</decision_guide>
|
|
222
|
+
|
|
223
|
+
<sources>
|
|
224
|
+
- EF Core Migrations documentation
|
|
225
|
+
- Zero-Downtime Deployments with EF Core (Microsoft patterns)
|
|
226
|
+
- Blue-Green Deployment pattern (Martin Fowler)
|
|
227
|
+
</sources>
|
|
@@ -189,18 +189,39 @@ Next: /efcore db-status, /efcore db-seed
|
|
|
189
189
|
|
|
190
190
|
## BOTH CONTEXTS:
|
|
191
191
|
|
|
192
|
-
If
|
|
192
|
+
**If `RUN_BOTH=true` (auto-detected for client projects with SmartStack NuGet):**
|
|
193
|
+
|
|
194
|
+
Run the full deploy sequence (steps 2-6) TWICE, in order:
|
|
193
195
|
|
|
194
196
|
```bash
|
|
195
|
-
# Deploy CoreDbContext first
|
|
197
|
+
# 1. Deploy CoreDbContext first (system tables: Users, Roles, Tenants...)
|
|
198
|
+
echo "=== Deploying CoreDbContext (core schema) ==="
|
|
196
199
|
DBCONTEXT="CoreDbContext"
|
|
197
|
-
|
|
200
|
+
SCHEMA="core"
|
|
201
|
+
# Run steps 2-6 with CoreDbContext...
|
|
198
202
|
|
|
199
|
-
|
|
203
|
+
dotnet ef database update \
|
|
204
|
+
--context "CoreDbContext" \
|
|
205
|
+
--project "$INFRA_PROJECT" \
|
|
206
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
207
|
+
--verbose
|
|
208
|
+
|
|
209
|
+
# 2. Then ExtensionsDbContext (client tables)
|
|
210
|
+
echo ""
|
|
211
|
+
echo "=== Deploying ExtensionsDbContext (extensions schema) ==="
|
|
200
212
|
DBCONTEXT="ExtensionsDbContext"
|
|
201
|
-
|
|
213
|
+
SCHEMA="extensions"
|
|
214
|
+
# Run steps 2-6 with ExtensionsDbContext...
|
|
215
|
+
|
|
216
|
+
dotnet ef database update \
|
|
217
|
+
--context "ExtensionsDbContext" \
|
|
218
|
+
--project "$INFRA_PROJECT" \
|
|
219
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
220
|
+
--verbose
|
|
202
221
|
```
|
|
203
222
|
|
|
223
|
+
**Order matters:** Core MUST be deployed first (Extensions may have foreign keys to Core tables).
|
|
224
|
+
|
|
204
225
|
---
|
|
205
226
|
|
|
206
227
|
## COMPLETION:
|
|
@@ -51,6 +51,25 @@ echo " Tables: $UP_TABLES"
|
|
|
51
51
|
echo " Columns: $UP_COLUMNS"
|
|
52
52
|
echo " Indexes: $UP_INDEXES"
|
|
53
53
|
echo " Foreign Keys:$UP_FOREIGN"
|
|
54
|
+
|
|
55
|
+
# Detect destructive operations
|
|
56
|
+
DROP_COL=$(grep -c "DropColumn" "$MIGRATION_FILE" || echo "0")
|
|
57
|
+
RENAME_COL=$(grep -c "RenameColumn" "$MIGRATION_FILE" || echo "0")
|
|
58
|
+
ALTER_COL=$(grep -c "AlterColumn" "$MIGRATION_FILE" || echo "0")
|
|
59
|
+
DROP_TABLE=$(grep -c "DropTable" "$MIGRATION_FILE" || echo "0")
|
|
60
|
+
DESTRUCTIVE=$((DROP_COL + RENAME_COL + ALTER_COL + DROP_TABLE))
|
|
61
|
+
|
|
62
|
+
if [ "$DESTRUCTIVE" -gt 0 ]; then
|
|
63
|
+
echo ""
|
|
64
|
+
echo "WARNING: Destructive operations detected:"
|
|
65
|
+
[ "$DROP_COL" -gt 0 ] && echo " DropColumn: $DROP_COL"
|
|
66
|
+
[ "$RENAME_COL" -gt 0 ] && echo " RenameColumn: $RENAME_COL"
|
|
67
|
+
[ "$ALTER_COL" -gt 0 ] && echo " AlterColumn: $ALTER_COL"
|
|
68
|
+
[ "$DROP_TABLE" -gt 0 ] && echo " DropTable: $DROP_TABLE"
|
|
69
|
+
echo ""
|
|
70
|
+
echo "For production deployments, consider zero-downtime migration patterns."
|
|
71
|
+
echo "See: references/zero-downtime-patterns.md"
|
|
72
|
+
fi
|
|
54
73
|
```
|
|
55
74
|
|
|
56
75
|
### 3. Ask User to Validate
|