@atlashub/smartstack-cli 2.0.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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +57595 -4569
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/skills/business-analyse/_shared.md +55 -14
- 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 +136 -53
- package/templates/skills/business-analyse/templates/tpl-handoff.md +99 -23
- package/templates/skills/controller/templates.md +82 -0
- package/templates/skills/efcore/references/zero-downtime-patterns.md +227 -0
- package/templates/skills/efcore/steps/migration/step-03-validate.md +19 -0
- package/templates/skills/review-code/SKILL.md +4 -2
- 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/workflow/SKILL.md +27 -0
|
@@ -37,6 +37,9 @@ This document is a self-contained prompt for Claude Code.
|
|
|
37
37
|
| Feature ID | {FEAT-XXX} |
|
|
38
38
|
| Module | business/{application}/{module} |
|
|
39
39
|
| Base Permission | `business.{app}.{module}` |
|
|
40
|
+
| Project Namespace | `{project_namespace}` |
|
|
41
|
+
| DB Schema | `extensions` (client entities) / `core` (navigation, permissions) |
|
|
42
|
+
| Table Prefix | `{prefix}_` (e.g., `bik_`) |
|
|
40
43
|
| Complexity | {Simple/Medium/Complex} |
|
|
41
44
|
|
|
42
45
|
## 2. [EXPLORE] EXISTING PATTERNS
|
|
@@ -45,42 +48,73 @@ BEFORE coding, explore these files to understand the patterns:
|
|
|
45
48
|
|
|
46
49
|
```
|
|
47
50
|
BACKEND:
|
|
48
|
-
- src/
|
|
49
|
-
- src/
|
|
50
|
-
- src/
|
|
51
|
+
- src/{project_namespace}.Domain/Business/ → Entity structure + folder hierarchy
|
|
52
|
+
- src/{project_namespace}.Application/Business/ → DTOs + service interfaces
|
|
53
|
+
- src/{project_namespace}.Application/Common/Interfaces/ → Service contracts
|
|
54
|
+
- src/{project_namespace}.Infrastructure/Persistence/Configurations/ → EF Core configs (subfolder per module)
|
|
55
|
+
- src/{project_namespace}.Infrastructure/Services/ → Service implementations (subfolder per module)
|
|
56
|
+
- src/{project_namespace}.Infrastructure/Persistence/Seeding/Data/ → SeedData patterns
|
|
57
|
+
|
|
58
|
+
SEED DATA (CRITICAL):
|
|
59
|
+
- NavigationModuleConfiguration.cs → How modules are seeded (HasData)
|
|
60
|
+
- NavigationTranslationConfiguration.cs → How translations are seeded (4 languages)
|
|
61
|
+
- PermissionConfiguration.cs → How permissions are seeded (HasData)
|
|
62
|
+
- RolePermissionConfiguration.cs → How role-permission mappings are seeded
|
|
51
63
|
|
|
52
64
|
FRONTEND:
|
|
53
|
-
- web/
|
|
54
|
-
- web/
|
|
55
|
-
- web/
|
|
65
|
+
- web/src/pages/business/ → Existing pages
|
|
66
|
+
- web/src/components/ → Reusable components
|
|
67
|
+
- web/src/services/api/ → API calls
|
|
56
68
|
```
|
|
57
69
|
|
|
58
70
|
## 3. FILES TO CREATE
|
|
59
71
|
|
|
60
72
|
### 3.1 Backend
|
|
61
73
|
|
|
62
|
-
| File |
|
|
63
|
-
|
|
64
|
-
| `Domain/
|
|
65
|
-
| `Application/
|
|
66
|
-
|
|
|
67
|
-
| `
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
| File | Path Pattern | Description |
|
|
75
|
+
|------|-------------|-------------|
|
|
76
|
+
| Domain Entity | `Domain/Business/{Application}/{Module}/{Entity}.cs` | BaseEntity + IAuditableEntity |
|
|
77
|
+
| Service Interface | `Application/Common/Interfaces/I{Entity}Service.cs` | Service contract |
|
|
78
|
+
| DTOs | `Application/Business/{Application}/{Module}/DTOs/{Entity}Dto.cs` | Response, Create, Update records |
|
|
79
|
+
| Mapping | `Application/Business/{Application}/{Module}/DTOs/{Entity}MappingExtensions.cs` | Entity ↔ DTO mapping |
|
|
80
|
+
| Permission Constants | `Application/Business/{Application}/{Module}/Permissions.cs` | Compile-time constants |
|
|
81
|
+
| EF Configuration | `Infrastructure/Persistence/Configurations/{Module}/{Entity}Configuration.cs` | Table + indexes + HasData |
|
|
82
|
+
| Service Implementation | `Infrastructure/Services/{Module}/{Entity}Service.cs` | Business logic |
|
|
83
|
+
| Controller | `Api/Controllers/Business/{Application}/{Module}Controller.cs` | NavRoute + RequirePermission |
|
|
84
|
+
|
|
85
|
+
### 3.2 SeedData Core (CRITICAL — without these, module is invisible and returns 403)
|
|
86
|
+
|
|
87
|
+
> **5 mandatory files** for every new module (4 EF Core HasData + 1 Application code):
|
|
88
|
+
|
|
89
|
+
| # | File | Layer | Content |
|
|
90
|
+
|---|------|-------|---------|
|
|
91
|
+
| 1 | `NavigationModuleConfiguration.cs` | Infrastructure (HasData) | Module entry in `nav_Modules` |
|
|
92
|
+
| 2 | `NavigationTranslationConfiguration.cs` | Infrastructure (HasData) | 4 translations (fr, en, it, de) per nav entity |
|
|
93
|
+
| 3 | `PermissionConfiguration.cs` | Infrastructure (HasData) | Wildcard + CRUD permissions in `nav_Permissions` |
|
|
94
|
+
| 4 | `Permissions.cs` | Application (code) | Compile-time constants for `[RequirePermission]` |
|
|
95
|
+
| 5 | `RolePermissionConfiguration.cs` | Infrastructure (HasData) | Role→Permission for {App} Admin, {App} Manager, {App} Contributor, {App} Viewer |
|
|
96
|
+
|
|
97
|
+
### 3.3 Frontend
|
|
98
|
+
|
|
99
|
+
| File | Path Pattern | Description |
|
|
100
|
+
|------|-------------|-------------|
|
|
101
|
+
| Main Page | `pages/business/{app}/{module}/page.tsx` | List + actions |
|
|
102
|
+
| Components | `components/business/{module}/` | Entity-specific components |
|
|
103
|
+
| API Service | `services/api/{module}Api.ts` | Typed Axios calls |
|
|
104
|
+
| Translations | `i18n/locales/{lang}/{module}.json` | FR, EN, IT, DE |
|
|
76
105
|
|
|
77
106
|
## 4. DETAILED SPECIFICATIONS
|
|
78
107
|
|
|
79
108
|
### 4.1 Entity
|
|
80
109
|
|
|
110
|
+
**Base class:** `BaseEntity` + `IAuditableEntity`
|
|
111
|
+
**Table name:** `{prefix}_{EntityPlural}` in schema `extensions` (e.g., `extensions.bik_FreeBickes`)
|
|
112
|
+
**Schema:** `extensions` for business entities, `core` for system entities (navigation, permissions)
|
|
113
|
+
> DO NOT add Id, TenantId, CreatedAt, UpdatedAt, CreatedBy, UpdatedBy — these are automatic via BaseEntity + IAuditableEntity.
|
|
114
|
+
|
|
81
115
|
| Attribute | Description | Required | Rules |
|
|
82
116
|
|-----------|-------------|----------|-------|
|
|
83
|
-
|
|
|
117
|
+
| Code | Unique code per tenant | Yes | MaxLength(50), unique index with TenantId |
|
|
84
118
|
| {attr} | {description} | {Yes/No} | {validation} |
|
|
85
119
|
|
|
86
120
|
### 4.2 API Endpoints
|
|
@@ -99,6 +133,31 @@ FRONTEND:
|
|
|
99
133
|
|-------|------|----------------|
|
|
100
134
|
| BR-001 | {rule} | {where to implement} |
|
|
101
135
|
|
|
136
|
+
### 4.4 SeedData Specifications
|
|
137
|
+
|
|
138
|
+
**Navigation seeds:**
|
|
139
|
+
| Level | Code | Label FR | Label EN | Label IT | Label DE | Icon | Route |
|
|
140
|
+
|-------|------|----------|----------|----------|----------|------|-------|
|
|
141
|
+
| Module | {module} | {label_fr} | {label_en} | {label_it} | {label_de} | {Icon} | /business/{app}/{module} |
|
|
142
|
+
|
|
143
|
+
**Permission seeds:**
|
|
144
|
+
| Path | Level | Action | Description |
|
|
145
|
+
|------|-------|--------|-------------|
|
|
146
|
+
| business.{app}.{module}.* | Module | Wildcard | Full access |
|
|
147
|
+
| business.{app}.{module}.read | Module | Read | View |
|
|
148
|
+
| business.{app}.{module}.create | Module | Create | Create |
|
|
149
|
+
| business.{app}.{module}.update | Module | Update | Modify |
|
|
150
|
+
| business.{app}.{module}.delete | Module | Delete | Remove |
|
|
151
|
+
|
|
152
|
+
**Role-Permission matrix:**
|
|
153
|
+
| Permission | {App} Admin | {App} Manager | {App} Contributor | {App} Viewer |
|
|
154
|
+
|------------|-------------|---------------|-------------------|--------------|
|
|
155
|
+
| wildcard (*) | X | - | - | - |
|
|
156
|
+
| read | - | X | X | X |
|
|
157
|
+
| create | - | X | X | - |
|
|
158
|
+
| update | - | X | X | - |
|
|
159
|
+
| delete | - | - | - | - |
|
|
160
|
+
|
|
102
161
|
## 5. REQUIRED TESTS
|
|
103
162
|
|
|
104
163
|
- [ ] Unit test: Entity validation
|
|
@@ -108,12 +167,29 @@ FRONTEND:
|
|
|
108
167
|
|
|
109
168
|
## 6. POST-IMPLEMENTATION CHECKLIST
|
|
110
169
|
|
|
170
|
+
**Build & Tests:**
|
|
111
171
|
- [ ] Backend build OK
|
|
112
172
|
- [ ] Frontend build OK
|
|
113
173
|
- [ ] Tests passing
|
|
114
|
-
|
|
115
|
-
|
|
174
|
+
|
|
175
|
+
**Folder Conventions:**
|
|
176
|
+
- [ ] Domain entities in `Domain/Business/{Application}/{Module}/`
|
|
177
|
+
- [ ] Application DTOs in `Application/Business/{Application}/{Module}/DTOs/`
|
|
178
|
+
- [ ] Infrastructure configs in `Configurations/{Module}/`
|
|
179
|
+
- [ ] Infrastructure services in `Services/{Module}/`
|
|
180
|
+
- [ ] Controller in `Controllers/Business/{Application}/`
|
|
181
|
+
|
|
182
|
+
**SeedData Core (CRITICAL):**
|
|
183
|
+
- [ ] Navigation module entry (HasData in NavigationModuleConfiguration.cs)
|
|
184
|
+
- [ ] Navigation translations (4 languages in NavigationTranslationConfiguration.cs)
|
|
185
|
+
- [ ] Permissions (HasData in PermissionConfiguration.cs: wildcard + CRUD)
|
|
186
|
+
- [ ] Permission constants (Permissions.cs in Application layer)
|
|
187
|
+
- [ ] Role-Permission assignments (HasData in RolePermissionConfiguration.cs: 4 roles)
|
|
188
|
+
- [ ] EF Core migration created (includes all HasData seeds)
|
|
189
|
+
|
|
190
|
+
**Frontend & i18n:**
|
|
116
191
|
- [ ] i18n complete (4 languages)
|
|
192
|
+
- [ ] Nested routes (NOT flat)
|
|
117
193
|
- [ ] Documentation: `/business-analyse:6-doc-html {FEAT-XXX}`
|
|
118
194
|
|
|
119
195
|
---
|
|
@@ -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]` |
|
|
@@ -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>
|
|
@@ -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
|
|
@@ -151,7 +151,8 @@ The MCP tool returns a structured report. Display it as-is or integrate key find
|
|
|
151
151
|
- Authorization checks on every endpoint
|
|
152
152
|
- No `eval()`, `exec()`, dangerous functions
|
|
153
153
|
|
|
154
|
-
See [references/security-checklist.md](references/security-checklist.md) for OWASP Top 10 patterns.
|
|
154
|
+
See [references/security-checklist.md](references/security-checklist.md) for OWASP Top 10 patterns (web application vulnerabilities).
|
|
155
|
+
See [references/owasp-api-top10.md](references/owasp-api-top10.md) for OWASP API Security Top 10 (API-specific threats: BOLA, mass assignment, SSRF, resource consumption).
|
|
155
156
|
</category>
|
|
156
157
|
|
|
157
158
|
<category name="logic" priority="critical">
|
|
@@ -322,7 +323,8 @@ A good code review:
|
|
|
322
323
|
<reference_guides>
|
|
323
324
|
For detailed guidance and patterns:
|
|
324
325
|
|
|
325
|
-
- **`references/security-checklist.md`** - OWASP Top 10, authentication patterns, input validation,
|
|
326
|
+
- **`references/security-checklist.md`** - OWASP Top 10, authentication patterns, input validation, rate limiting, security headers
|
|
327
|
+
- **`references/owasp-api-top10.md`** - OWASP API Security Top 10: BOLA, mass assignment, SSRF, resource consumption, SmartStack-specific detection patterns
|
|
326
328
|
- **`references/clean-code-principles.md`** - SOLID principles, naming conventions, function design, code smell detection
|
|
327
329
|
- **`references/feedback-patterns.md`** - Valuable vs wasteful feedback patterns, communication strategies, priority labeling
|
|
328
330
|
- **`references/code-quality-metrics.md`** - Complexity calculations, maintainability index, measurement techniques
|