@atlashub/smartstack-cli 3.14.0 → 3.16.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 +26 -28
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +626 -141
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/efcore/migration.md +15 -0
- package/templates/skills/apex/steps/step-04-validate.md +64 -5
- package/templates/skills/application/references/frontend-verification.md +20 -0
- package/templates/skills/application/steps/step-04-backend.md +17 -1
- package/templates/skills/application/steps/step-05-frontend.md +49 -23
- package/templates/skills/application/templates-seed.md +14 -4
- package/templates/skills/business-analyse/html/ba-interactive.html +165 -0
- package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +2 -0
- package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +85 -0
- package/templates/skills/business-analyse/html/src/styles/05-modules.css +65 -0
- package/templates/skills/business-analyse/html/src/template.html +13 -0
- package/templates/skills/business-analyse/schemas/application-schema.json +5 -0
- package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +1 -0
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +90 -0
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +4 -0
- package/templates/skills/business-analyse/steps/step-03a1-setup.md +39 -0
- package/templates/skills/efcore/steps/shared/step-00-init.md +55 -0
- package/templates/skills/ralph-loop/SKILL.md +1 -0
- package/templates/skills/ralph-loop/references/category-rules.md +131 -27
- package/templates/skills/ralph-loop/references/compact-loop.md +61 -3
- package/templates/skills/ralph-loop/references/core-seed-data.md +251 -5
- package/templates/skills/ralph-loop/references/error-classification.md +143 -0
- package/templates/skills/ralph-loop/steps/step-05-report.md +54 -0
- package/templates/skills/review-code/references/smartstack-conventions.md +16 -0
- package/templates/skills/validate-feature/SKILL.md +11 -1
- package/templates/skills/validate-feature/steps/step-00-dependencies.md +121 -0
- package/templates/skills/validate-feature/steps/step-04-api-smoke.md +61 -13
- package/templates/skills/validate-feature/steps/step-05-db-validation.md +250 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: step-05-db-validation
|
|
3
|
+
description: Validate database schema, migrations, seed data, and multi-tenant isolation against real SQL Server
|
|
4
|
+
prev_step: steps/step-04-api-smoke.md
|
|
5
|
+
next_step: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Step 5: Database Validation (SQL Server LocalDB)
|
|
9
|
+
|
|
10
|
+
> **Purpose:** Verify that migrations apply correctly, seed data inserts, LINQ queries execute real SQL, and multi-tenant isolation works on a REAL SQL Server instance — not SQLite.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. Verify LocalDB Availability
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
sqllocaldb info MSSQLLocalDB
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**If LocalDB is NOT available:**
|
|
21
|
+
- Display warning: `LocalDB not found — skipping DB validation`
|
|
22
|
+
- Set `DB_VALIDATION = SKIPPED`
|
|
23
|
+
- Skip to section 8 (Summary)
|
|
24
|
+
|
|
25
|
+
**If LocalDB is available:**
|
|
26
|
+
- Continue to section 2
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2. Locate Infrastructure Project
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
INFRA_PROJECT=$(ls src/*Infrastructure*/*.csproj 2>/dev/null | head -1)
|
|
34
|
+
API_PROJECT=$(ls src/*Api*/*.csproj 2>/dev/null | head -1)
|
|
35
|
+
|
|
36
|
+
if [ -z "$INFRA_PROJECT" ] || [ -z "$API_PROJECT" ]; then
|
|
37
|
+
echo "WARNING: Infrastructure or API project not found — skipping DB validation"
|
|
38
|
+
DB_VALIDATION="SKIPPED"
|
|
39
|
+
# Skip to section 8
|
|
40
|
+
fi
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. Check Pending Model Changes
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
dotnet ef migrations has-pending-model-changes \
|
|
49
|
+
--project "$INFRA_PROJECT" \
|
|
50
|
+
--startup-project "$API_PROJECT"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| Exit Code | Meaning | Action |
|
|
54
|
+
|-----------|---------|--------|
|
|
55
|
+
| 0 | No pending changes | PASS — continue |
|
|
56
|
+
| Non-zero | Model has changes not in a migration | **FAIL — BLOCKING** |
|
|
57
|
+
|
|
58
|
+
**If FAIL:**
|
|
59
|
+
- Display: `MIGRATION MISSING: EF Core model has changes not captured in a migration`
|
|
60
|
+
- Provide fix: `dotnet ef migrations add {SuggestedName} --project {InfraProject} --startup-project {ApiProject} -o Persistence/Migrations`
|
|
61
|
+
- **BLOCK** — do NOT continue until migration is created
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 4. Apply Migrations on Temp Database
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Create unique test database name
|
|
69
|
+
DB_NAME="SmartStack_Validate_$(date +%s)"
|
|
70
|
+
CONN_STRING="Server=(localdb)\\MSSQLLocalDB;Database=$DB_NAME;Integrated Security=true;TrustServerCertificate=true;Connect Timeout=120;"
|
|
71
|
+
|
|
72
|
+
# Apply ALL migrations from scratch
|
|
73
|
+
dotnet ef database update \
|
|
74
|
+
--connection "$CONN_STRING" \
|
|
75
|
+
--project "$INFRA_PROJECT" \
|
|
76
|
+
--startup-project "$API_PROJECT"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Result | Meaning | Action |
|
|
80
|
+
|--------|---------|--------|
|
|
81
|
+
| Success | All migrations apply cleanly | PASS — continue |
|
|
82
|
+
| Failure | Migration chain is broken | **FAIL — BLOCKING** |
|
|
83
|
+
|
|
84
|
+
**If FAIL:**
|
|
85
|
+
- Parse the error output
|
|
86
|
+
- Common issues:
|
|
87
|
+
- `Invalid column name` → migration references a column that doesn't exist yet (ordering issue)
|
|
88
|
+
- `There is already an object named` → duplicate migration or missing Down() method
|
|
89
|
+
- `Cannot insert duplicate key` → seed data in migration conflicting
|
|
90
|
+
- **BLOCK** — fix the migration before continuing
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 5. Run Integration Tests Against Real SQL Server
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Find integration test project
|
|
98
|
+
TEST_PROJECT=$(ls tests/*Tests.Integration*/*.csproj 2>/dev/null | head -1)
|
|
99
|
+
|
|
100
|
+
if [ -n "$TEST_PROJECT" ]; then
|
|
101
|
+
# Integration tests use DatabaseFixture which creates its own LocalDB instance
|
|
102
|
+
# and applies real migrations — this validates LINQ → SQL translation
|
|
103
|
+
dotnet test "$TEST_PROJECT" --no-build --verbosity normal
|
|
104
|
+
else
|
|
105
|
+
echo "INFO: No integration test project found — running unit tests only"
|
|
106
|
+
TEST_PROJECT=$(ls tests/*Tests*/*.csproj 2>/dev/null | head -1)
|
|
107
|
+
if [ -n "$TEST_PROJECT" ]; then
|
|
108
|
+
dotnet test "$TEST_PROJECT" --filter "FullyQualifiedName~Integration" --no-build --verbosity normal
|
|
109
|
+
fi
|
|
110
|
+
fi
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**What this validates:**
|
|
114
|
+
- **LINQ → SQL**: Queries execute against real SQL Server, not SQLite
|
|
115
|
+
- **Multi-tenant isolation**: Global query filters enforced at SQL Server level
|
|
116
|
+
- **Soft delete**: SQL Server handles IsDeleted filter correctly
|
|
117
|
+
- **EF Core configuration**: Indexes, relationships, constraints verified
|
|
118
|
+
- **Repository operations**: CRUD operations hit real SQL Server
|
|
119
|
+
|
|
120
|
+
| Result | Meaning |
|
|
121
|
+
|--------|---------|
|
|
122
|
+
| All tests pass | PASS — LINQ→SQL, isolation, and EF configs work on real SQL Server |
|
|
123
|
+
| Test failures | **FAIL** — investigate: some queries may not translate to SQL Server |
|
|
124
|
+
|
|
125
|
+
**Common SQLite → SQL Server differences caught:**
|
|
126
|
+
- `LIKE` is case-insensitive in SQLite, case-sensitive in SQL Server
|
|
127
|
+
- Date functions differ (`date('now')` vs `GETUTCDATE()`)
|
|
128
|
+
- String concatenation (`||` vs `+`)
|
|
129
|
+
- `LIMIT` vs `TOP`
|
|
130
|
+
- `AUTOINCREMENT` vs `IDENTITY`
|
|
131
|
+
- `COLLATE` behavior differences
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 6. Verify Seed Data Execution
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Use the test database from step 4 to verify seed data
|
|
139
|
+
# Start the API against the temp database
|
|
140
|
+
dotnet run --project "$API_PROJECT" \
|
|
141
|
+
--urls "http://localhost:5097" \
|
|
142
|
+
-- --ConnectionStrings:DefaultConnection="$CONN_STRING" > /tmp/validate-seed-check.log 2>&1 &
|
|
143
|
+
SEED_PID=$!
|
|
144
|
+
|
|
145
|
+
# Wait for startup
|
|
146
|
+
STARTED=false
|
|
147
|
+
for i in $(seq 1 15); do
|
|
148
|
+
if ! kill -0 $SEED_PID 2>/dev/null; then
|
|
149
|
+
echo "API crashed during startup with seed data"
|
|
150
|
+
break
|
|
151
|
+
fi
|
|
152
|
+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5097/health 2>/dev/null)
|
|
153
|
+
if [ "$HTTP_CODE" != "000" ]; then
|
|
154
|
+
STARTED=true
|
|
155
|
+
break
|
|
156
|
+
fi
|
|
157
|
+
sleep 1
|
|
158
|
+
done
|
|
159
|
+
|
|
160
|
+
if [ "$STARTED" = "true" ]; then
|
|
161
|
+
# Verify seed data exists by checking API endpoints
|
|
162
|
+
# Login with test credentials
|
|
163
|
+
TOKEN=$(curl -s -X POST http://localhost:5097/api/auth/login \
|
|
164
|
+
-H "Content-Type: application/json" \
|
|
165
|
+
-d '{"email":"admin@smartstack.io","password":"Admin123!"}' \
|
|
166
|
+
| grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
|
|
167
|
+
|
|
168
|
+
if [ -n "$TOKEN" ]; then
|
|
169
|
+
# Check navigation modules exist (core seed data)
|
|
170
|
+
NAV_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5097/api/platform/navigation/modules \
|
|
171
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
172
|
+
-H "X-Tenant-Id: 11111111-1111-1111-1111-111111111111")
|
|
173
|
+
|
|
174
|
+
if [ "$NAV_STATUS" = "200" ]; then
|
|
175
|
+
echo "PASS: Core seed data verified (navigation modules accessible)"
|
|
176
|
+
else
|
|
177
|
+
echo "WARNING: Core seed data may not be seeded (HTTP $NAV_STATUS)"
|
|
178
|
+
fi
|
|
179
|
+
else
|
|
180
|
+
echo "WARNING: Could not authenticate — seed data verification via API skipped"
|
|
181
|
+
echo "INFO: Integration tests already verify seed data at DB level via DatabaseFixture"
|
|
182
|
+
fi
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Cleanup
|
|
186
|
+
kill $SEED_PID 2>/dev/null
|
|
187
|
+
wait $SEED_PID 2>/dev/null
|
|
188
|
+
rm -f /tmp/validate-seed-check.log
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 7. Cleanup Temp Database
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Drop the temp database created in step 4
|
|
197
|
+
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "
|
|
198
|
+
IF DB_ID('$DB_NAME') IS NOT NULL
|
|
199
|
+
BEGIN
|
|
200
|
+
ALTER DATABASE [$DB_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
|
|
201
|
+
DROP DATABASE [$DB_NAME];
|
|
202
|
+
END
|
|
203
|
+
" 2>/dev/null
|
|
204
|
+
|
|
205
|
+
# Alternative if sqlcmd is not available
|
|
206
|
+
if [ $? -ne 0 ]; then
|
|
207
|
+
dotnet ef database drop --force \
|
|
208
|
+
--connection "$CONN_STRING" \
|
|
209
|
+
--project "$INFRA_PROJECT" \
|
|
210
|
+
--startup-project "$API_PROJECT" 2>/dev/null
|
|
211
|
+
fi
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 8. Validation Summary
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
## DB Validation: {EntityName}
|
|
220
|
+
|
|
221
|
+
| Check | Result | Details |
|
|
222
|
+
|--------------------------------|-----------|--------------------------------------------|
|
|
223
|
+
| LocalDB available | PASS/SKIP | sqllocaldb info MSSQLLocalDB |
|
|
224
|
+
| Pending model changes | PASS/FAIL | dotnet ef migrations has-pending |
|
|
225
|
+
| Migrations apply cleanly | PASS/FAIL | dotnet ef database update on temp DB |
|
|
226
|
+
| Integration tests (SQL Server) | PASS/FAIL | dotnet test --filter Integration |
|
|
227
|
+
| Seed data accessible | PASS/WARN | API endpoints return seeded data |
|
|
228
|
+
| Temp DB cleanup | PASS/WARN | Database dropped |
|
|
229
|
+
|
|
230
|
+
DB Validation Result: {PASS / FAIL / SKIPPED}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Interpretation:**
|
|
234
|
+
- **PASS**: All 6 gaps covered — migrations, SQL Server, LINQ→SQL, isolation, seed data verified
|
|
235
|
+
- **FAIL**: One or more checks failed — fix before committing
|
|
236
|
+
- **SKIPPED**: LocalDB not available — tests ran on SQLite only (partial coverage)
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Error Classification (DB-specific)
|
|
241
|
+
|
|
242
|
+
| Error Pattern | Category | Fix |
|
|
243
|
+
|---------------|----------|-----|
|
|
244
|
+
| `Invalid column name '{Column}'` | Migration ordering | Reorder migration or split into multiple |
|
|
245
|
+
| `Cannot insert duplicate key` | Seed data conflict | Make seed data idempotent (check before insert) |
|
|
246
|
+
| `String or binary data would be truncated` | Column length | Increase `MaxLength` in EF config |
|
|
247
|
+
| `The INSERT statement conflicted with the FOREIGN KEY constraint` | Missing parent data | Ensure parent entities are seeded first |
|
|
248
|
+
| `Cannot insert the value NULL into column` | Missing NOT NULL | Add default value or make column nullable |
|
|
249
|
+
| `Login failed for user` | LocalDB auth | Run `sqllocaldb start MSSQLLocalDB` |
|
|
250
|
+
| `A network-related or instance-specific error` | LocalDB not running | Run `sqllocaldb start MSSQLLocalDB` |
|