@atlashub/smartstack-cli 1.17.0 → 1.19.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/package.json +1 -1
- package/templates/agents/efcore/db-deploy.md +5 -0
- package/templates/agents/efcore/db-reset.md +5 -0
- package/templates/agents/efcore/db-seed.md +5 -0
- package/templates/agents/efcore/db-status.md +5 -0
- package/templates/agents/efcore/migration.md +8 -0
- package/templates/agents/efcore/rebase-snapshot.md +9 -0
- package/templates/agents/efcore/squash.md +50 -20
- package/templates/commands/efcore/squash.md +24 -12
- package/templates/skills/efcore/SKILL.md +162 -0
- package/templates/skills/efcore/steps/db/step-deploy.md +208 -0
- package/templates/skills/efcore/steps/db/step-reset.md +259 -0
- package/templates/skills/efcore/steps/db/step-seed.md +244 -0
- package/templates/skills/efcore/steps/db/step-status.md +198 -0
- package/templates/skills/efcore/steps/migration/step-00-init.md +102 -0
- package/templates/skills/efcore/steps/migration/step-01-check.md +138 -0
- package/templates/skills/efcore/steps/migration/step-02-create.md +144 -0
- package/templates/skills/efcore/steps/migration/step-03-validate.md +203 -0
- package/templates/skills/efcore/steps/rebase-snapshot/step-00-init.md +173 -0
- package/templates/skills/efcore/steps/rebase-snapshot/step-01-backup.md +100 -0
- package/templates/skills/efcore/steps/rebase-snapshot/step-02-fetch.md +115 -0
- package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +108 -0
- package/templates/skills/efcore/steps/rebase-snapshot/step-04-validate.md +157 -0
- package/templates/skills/efcore/steps/shared/step-00-init.md +266 -0
- package/templates/skills/efcore/steps/squash/step-00-init.md +141 -0
- package/templates/skills/efcore/steps/squash/step-01-backup.md +120 -0
- package/templates/skills/efcore/steps/squash/step-02-fetch.md +168 -0
- package/templates/skills/efcore/steps/squash/step-03-create.md +178 -0
- package/templates/skills/efcore/steps/squash/step-04-validate.md +174 -0
- package/templates/skills/gitflow/steps/step-commit.md +14 -2
- package/templates/skills/gitflow/steps/step-finish.md +26 -0
- package/templates/skills/gitflow/steps/step-merge.md +8 -3
- package/templates/skills/gitflow/steps/step-pr.md +10 -0
- package/templates/skills/gitflow/steps/step-start.md +12 -1
- package/templates/skills/gitflow/steps/step-sync.md +24 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: step-deploy
|
|
3
|
+
description: Deploy pending migrations to database
|
|
4
|
+
next_step: null
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database Deploy
|
|
8
|
+
|
|
9
|
+
## YOUR TASK:
|
|
10
|
+
|
|
11
|
+
Apply pending EF Core migrations to the local database.
|
|
12
|
+
|
|
13
|
+
**Requires:** `steps/shared/step-00-init.md` completed
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## EXECUTION SEQUENCE:
|
|
18
|
+
|
|
19
|
+
### 1. Environment Check
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
echo "Deploy Configuration"
|
|
23
|
+
echo "===================="
|
|
24
|
+
echo ""
|
|
25
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
26
|
+
echo "Environment: $SELECTED_ENV"
|
|
27
|
+
echo "Database: $DATABASE_NAME"
|
|
28
|
+
echo "Server: $SERVER_NAME"
|
|
29
|
+
|
|
30
|
+
# Block production
|
|
31
|
+
block_production
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Check Pending Migrations
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Checking pending migrations..."
|
|
39
|
+
|
|
40
|
+
PENDING=$(dotnet ef migrations list \
|
|
41
|
+
--context "$DBCONTEXT" \
|
|
42
|
+
--project "$INFRA_PROJECT" \
|
|
43
|
+
--startup-project "$STARTUP_PROJECT" 2>/dev/null | \
|
|
44
|
+
grep -c "(Pending)" || echo "0")
|
|
45
|
+
|
|
46
|
+
echo "Pending: $PENDING migration(s)"
|
|
47
|
+
|
|
48
|
+
if [ "$PENDING" -eq 0 ]; then
|
|
49
|
+
echo ""
|
|
50
|
+
echo "No pending migrations. Database is up to date."
|
|
51
|
+
echo ""
|
|
52
|
+
echo "Next steps:"
|
|
53
|
+
echo " /efcore migration # Create new migration"
|
|
54
|
+
echo " /efcore db-status # Check status"
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. List Pending Migrations
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
echo ""
|
|
63
|
+
echo "Migrations to apply:"
|
|
64
|
+
|
|
65
|
+
dotnet ef migrations list \
|
|
66
|
+
--context "$DBCONTEXT" \
|
|
67
|
+
--project "$INFRA_PROJECT" \
|
|
68
|
+
--startup-project "$STARTUP_PROJECT" 2>/dev/null | \
|
|
69
|
+
grep "(Pending)" | while read line; do
|
|
70
|
+
echo " - $line"
|
|
71
|
+
done
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Confirmation (if not auto mode)
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
AskUserQuestion:
|
|
78
|
+
header: "Deploy"
|
|
79
|
+
question: "Apply {PENDING} migration(s) to {DATABASE_NAME}?"
|
|
80
|
+
options:
|
|
81
|
+
- label: "Yes, apply"
|
|
82
|
+
description: "Deploy to {SELECTED_ENV} environment"
|
|
83
|
+
- label: "Cancel"
|
|
84
|
+
description: "Do not apply"
|
|
85
|
+
multiSelect: false
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. Apply Migrations
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
echo ""
|
|
92
|
+
echo "Applying migrations..."
|
|
93
|
+
echo ""
|
|
94
|
+
|
|
95
|
+
dotnet ef database update \
|
|
96
|
+
--context "$DBCONTEXT" \
|
|
97
|
+
--project "$INFRA_PROJECT" \
|
|
98
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
99
|
+
--verbose
|
|
100
|
+
|
|
101
|
+
if [ $? -ne 0 ]; then
|
|
102
|
+
echo ""
|
|
103
|
+
echo "ERROR: Migration failed"
|
|
104
|
+
echo ""
|
|
105
|
+
echo "Troubleshooting:"
|
|
106
|
+
echo " - Check database connection"
|
|
107
|
+
echo " - Review migration content"
|
|
108
|
+
echo " - Try: /efcore db-reset"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 6. Verify
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
echo ""
|
|
117
|
+
echo "Verifying..."
|
|
118
|
+
|
|
119
|
+
NEW_PENDING=$(dotnet ef migrations list \
|
|
120
|
+
--context "$DBCONTEXT" \
|
|
121
|
+
--project "$INFRA_PROJECT" \
|
|
122
|
+
--startup-project "$STARTUP_PROJECT" 2>/dev/null | \
|
|
123
|
+
grep -c "(Pending)" || echo "0")
|
|
124
|
+
|
|
125
|
+
if [ "$NEW_PENDING" -eq 0 ]; then
|
|
126
|
+
echo "All migrations applied successfully."
|
|
127
|
+
else
|
|
128
|
+
echo "WARNING: $NEW_PENDING migrations still pending"
|
|
129
|
+
fi
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 7. Summary
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
echo ""
|
|
136
|
+
echo "==========================================="
|
|
137
|
+
echo "DEPLOY COMPLETE"
|
|
138
|
+
echo "==========================================="
|
|
139
|
+
echo ""
|
|
140
|
+
echo "Database: $DATABASE_NAME"
|
|
141
|
+
echo "Environment: $SELECTED_ENV"
|
|
142
|
+
echo "DbContext: $DBCONTEXT"
|
|
143
|
+
echo "Applied: $PENDING migration(s)"
|
|
144
|
+
echo ""
|
|
145
|
+
echo "==========================================="
|
|
146
|
+
echo ""
|
|
147
|
+
echo "Next steps:"
|
|
148
|
+
echo " /efcore db-status # Verify status"
|
|
149
|
+
echo " /efcore db-seed # Add test data"
|
|
150
|
+
echo ""
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## OUTPUT FORMAT:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
DEPLOY COMPLETE
|
|
159
|
+
===============
|
|
160
|
+
Database: {database_name}
|
|
161
|
+
Environment: {env}
|
|
162
|
+
DbContext: {dbcontext}
|
|
163
|
+
Applied: {N} migration(s)
|
|
164
|
+
|
|
165
|
+
Next: /efcore db-status, /efcore db-seed
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## ERROR HANDLING:
|
|
171
|
+
|
|
172
|
+
| Error | Resolution |
|
|
173
|
+
|-------|------------|
|
|
174
|
+
| Connection failed | Check SQL Server, credentials |
|
|
175
|
+
| Migration error | Review migration, consider reset |
|
|
176
|
+
| Constraint violation | Check data, may need seed |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## OPTIONS:
|
|
181
|
+
|
|
182
|
+
| Option | Description |
|
|
183
|
+
|--------|-------------|
|
|
184
|
+
| `--env {name}` | Use appsettings.{name}.json |
|
|
185
|
+
| `--verbose` | Show SQL statements |
|
|
186
|
+
| `--context {name}` | Specify DbContext |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## BOTH CONTEXTS:
|
|
191
|
+
|
|
192
|
+
If "Both" selected for DbContext:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Deploy CoreDbContext first
|
|
196
|
+
DBCONTEXT="CoreDbContext"
|
|
197
|
+
# ... run deploy ...
|
|
198
|
+
|
|
199
|
+
# Then ExtensionsDbContext
|
|
200
|
+
DBCONTEXT="ExtensionsDbContext"
|
|
201
|
+
# ... run deploy ...
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## COMPLETION:
|
|
207
|
+
|
|
208
|
+
Migrations applied. Use `/efcore db-status` to verify.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: step-reset
|
|
3
|
+
description: Reset database - drop and recreate
|
|
4
|
+
next_step: null
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database Reset
|
|
8
|
+
|
|
9
|
+
## YOUR TASK:
|
|
10
|
+
|
|
11
|
+
Completely reset the database: drop, recreate, and apply all migrations.
|
|
12
|
+
|
|
13
|
+
**WARNING:** This is DESTRUCTIVE. All data will be lost!
|
|
14
|
+
|
|
15
|
+
**Requires:** `steps/shared/step-00-init.md` completed
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## COMPLIANCE:
|
|
20
|
+
|
|
21
|
+
| FORBIDDEN | REQUIRED |
|
|
22
|
+
|-----------|----------|
|
|
23
|
+
| `sqlcmd` for DDL/DML | `dotnet ef database drop` |
|
|
24
|
+
| SQL scripts in repo | `dotnet ef database update` |
|
|
25
|
+
| INSERT via scripts | `HasData()` for seeding |
|
|
26
|
+
|
|
27
|
+
**Exception:** `sqlcmd` allowed ONLY for `BACKUP DATABASE`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## EXECUTION SEQUENCE:
|
|
32
|
+
|
|
33
|
+
### 1. Environment Check
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
echo "Reset Configuration"
|
|
37
|
+
echo "==================="
|
|
38
|
+
echo ""
|
|
39
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
40
|
+
echo "Environment: $SELECTED_ENV"
|
|
41
|
+
echo "Database: $DATABASE_NAME"
|
|
42
|
+
echo "Server: $SERVER_NAME"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "WARNING: ALL DATA WILL BE LOST!"
|
|
45
|
+
|
|
46
|
+
# Block production
|
|
47
|
+
block_production
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Confirmation (MANDATORY)
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
AskUserQuestion:
|
|
54
|
+
header: "Reset DB"
|
|
55
|
+
question: "DANGER: Permanently delete '{DATABASE_NAME}'?
|
|
56
|
+
|
|
57
|
+
ALL DATA WILL BE LOST!
|
|
58
|
+
|
|
59
|
+
This action is IRREVERSIBLE."
|
|
60
|
+
options:
|
|
61
|
+
- label: "Yes, delete {DATABASE_NAME}"
|
|
62
|
+
description: "Drop + Recreate (IRREVERSIBLE)"
|
|
63
|
+
- label: "No, cancel"
|
|
64
|
+
description: "Keep database"
|
|
65
|
+
multiSelect: false
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Optional Backup
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
AskUserQuestion:
|
|
72
|
+
header: "Backup"
|
|
73
|
+
question: "Backup database before deletion?"
|
|
74
|
+
options:
|
|
75
|
+
- label: "Yes, backup (Recommended)"
|
|
76
|
+
description: "Create .bak via sqlcmd"
|
|
77
|
+
- label: "No"
|
|
78
|
+
description: "Dev data only - continue"
|
|
79
|
+
- label: "Manual backup"
|
|
80
|
+
description: "Via SSMS/Azure Portal (stops here)"
|
|
81
|
+
multiSelect: false
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**If backup requested:**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
BACKUP_DIR=".claude/gitflow/backup/database"
|
|
88
|
+
mkdir -p "$BACKUP_DIR"
|
|
89
|
+
|
|
90
|
+
BACKUP_FILE="$BACKUP_DIR/${DATABASE_NAME}_$(date +%Y%m%d_%H%M%S).bak"
|
|
91
|
+
|
|
92
|
+
echo "Creating backup: $BACKUP_FILE"
|
|
93
|
+
|
|
94
|
+
sqlcmd -S "$SERVER_NAME" -E -Q "BACKUP DATABASE [$DATABASE_NAME] TO DISK='$BACKUP_FILE'"
|
|
95
|
+
|
|
96
|
+
if [ $? -eq 0 ]; then
|
|
97
|
+
echo "Backup created: $BACKUP_FILE"
|
|
98
|
+
else
|
|
99
|
+
echo "WARNING: Backup failed. Continue anyway?"
|
|
100
|
+
fi
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 4. Drop Database
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
echo ""
|
|
107
|
+
echo "Dropping database..."
|
|
108
|
+
|
|
109
|
+
dotnet ef database drop \
|
|
110
|
+
--context "$DBCONTEXT" \
|
|
111
|
+
--project "$INFRA_PROJECT" \
|
|
112
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
113
|
+
--force
|
|
114
|
+
|
|
115
|
+
if [ $? -ne 0 ]; then
|
|
116
|
+
echo "ERROR: Drop failed"
|
|
117
|
+
echo "Database may be in use. Close connections and retry."
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo "Database dropped."
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 5. Recreate + Apply Migrations
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
echo ""
|
|
128
|
+
echo "Recreating database with migrations..."
|
|
129
|
+
|
|
130
|
+
dotnet ef database update \
|
|
131
|
+
--context "$DBCONTEXT" \
|
|
132
|
+
--project "$INFRA_PROJECT" \
|
|
133
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
134
|
+
--verbose
|
|
135
|
+
|
|
136
|
+
if [ $? -ne 0 ]; then
|
|
137
|
+
echo ""
|
|
138
|
+
echo "ERROR: Recreation failed"
|
|
139
|
+
exit 1
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
echo "Database recreated."
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 6. Optional Seed
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
AskUserQuestion:
|
|
149
|
+
header: "Seed"
|
|
150
|
+
question: "Populate with test data (HasData)?"
|
|
151
|
+
options:
|
|
152
|
+
- label: "Yes (recommended)"
|
|
153
|
+
description: "Apply HasData configurations"
|
|
154
|
+
- label: "No"
|
|
155
|
+
description: "Empty database"
|
|
156
|
+
multiSelect: false
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**If seed requested:**
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
echo ""
|
|
163
|
+
echo "Running seed..."
|
|
164
|
+
|
|
165
|
+
# HasData is already applied via migrations
|
|
166
|
+
# For custom seeding:
|
|
167
|
+
dotnet run --project "$STARTUP_PROJECT" -- --seed 2>/dev/null || echo "No --seed argument supported"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 7. Summary
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
MIGRATION_COUNT=$(dotnet ef migrations list \
|
|
174
|
+
--context "$DBCONTEXT" \
|
|
175
|
+
--project "$INFRA_PROJECT" \
|
|
176
|
+
--startup-project "$STARTUP_PROJECT" 2>/dev/null | \
|
|
177
|
+
grep -c "^[0-9]" || echo "0")
|
|
178
|
+
|
|
179
|
+
echo ""
|
|
180
|
+
echo "==========================================="
|
|
181
|
+
echo "RESET COMPLETE"
|
|
182
|
+
echo "==========================================="
|
|
183
|
+
echo ""
|
|
184
|
+
echo "Database: $DATABASE_NAME"
|
|
185
|
+
echo "Environment: $SELECTED_ENV"
|
|
186
|
+
echo "DbContext: $DBCONTEXT"
|
|
187
|
+
echo ""
|
|
188
|
+
echo "Operations:"
|
|
189
|
+
echo " - Drop: OK"
|
|
190
|
+
echo " - Create: OK"
|
|
191
|
+
echo " - Migrations: $MIGRATION_COUNT applied"
|
|
192
|
+
if [ -n "$BACKUP_FILE" ]; then
|
|
193
|
+
echo " - Backup: $BACKUP_FILE"
|
|
194
|
+
fi
|
|
195
|
+
echo ""
|
|
196
|
+
echo "Compliance: EF Core CLI only"
|
|
197
|
+
echo ""
|
|
198
|
+
echo "==========================================="
|
|
199
|
+
echo ""
|
|
200
|
+
echo "Next steps:"
|
|
201
|
+
echo " /efcore db-status # Verify status"
|
|
202
|
+
echo " /efcore db-seed # Add test data"
|
|
203
|
+
echo ""
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## OUTPUT FORMAT:
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
RESET COMPLETE
|
|
212
|
+
==============
|
|
213
|
+
Database: {database_name}
|
|
214
|
+
Environment: {env}
|
|
215
|
+
DbContext: {dbcontext}
|
|
216
|
+
|
|
217
|
+
Operations:
|
|
218
|
+
- Drop: OK
|
|
219
|
+
- Create: OK
|
|
220
|
+
- Migrations: {N} applied
|
|
221
|
+
- Backup: {path | none}
|
|
222
|
+
|
|
223
|
+
Compliance: EF Core CLI only
|
|
224
|
+
|
|
225
|
+
Next: /efcore db-status, /efcore db-seed
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## PROTECTIONS:
|
|
231
|
+
|
|
232
|
+
| Protection | Description |
|
|
233
|
+
|------------|-------------|
|
|
234
|
+
| Env Display | Shows database BEFORE confirmation |
|
|
235
|
+
| Confirmation | Explicit request with database NAME |
|
|
236
|
+
| Production Block | Blocks if Production detected |
|
|
237
|
+
| EF Core Only | No raw SQL |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## BOTH CONTEXTS:
|
|
242
|
+
|
|
243
|
+
If "Both" selected:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Drop + Recreate CoreDbContext
|
|
247
|
+
DBCONTEXT="CoreDbContext"
|
|
248
|
+
# ... execute reset ...
|
|
249
|
+
|
|
250
|
+
# Then ExtensionsDbContext
|
|
251
|
+
DBCONTEXT="ExtensionsDbContext"
|
|
252
|
+
# ... execute reset ...
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## COMPLETION:
|
|
258
|
+
|
|
259
|
+
Database reset complete. Fresh state with all migrations applied.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: step-seed
|
|
3
|
+
description: Populate database with test data
|
|
4
|
+
next_step: null
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database Seed
|
|
8
|
+
|
|
9
|
+
## YOUR TASK:
|
|
10
|
+
|
|
11
|
+
Populate the database with test or initial data using EF Core conventions.
|
|
12
|
+
|
|
13
|
+
**Requires:** `steps/shared/step-00-init.md` completed
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## COMPLIANCE:
|
|
18
|
+
|
|
19
|
+
| FORBIDDEN | REQUIRED |
|
|
20
|
+
|-----------|----------|
|
|
21
|
+
| SQL scripts in repo | `HasData()` in configurations |
|
|
22
|
+
| `sqlcmd` with INSERT | `IDataSeeder` classes |
|
|
23
|
+
| `migrationBuilder.Sql()` INSERT | EF Core typed migrations |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## EXECUTION SEQUENCE:
|
|
28
|
+
|
|
29
|
+
### 1. Environment Check
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
echo "Seed Configuration"
|
|
33
|
+
echo "=================="
|
|
34
|
+
echo ""
|
|
35
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
36
|
+
echo "Environment: $SELECTED_ENV"
|
|
37
|
+
echo "Database: $DATABASE_NAME"
|
|
38
|
+
|
|
39
|
+
# Block production
|
|
40
|
+
block_production
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Detect Available Seed Methods
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
echo ""
|
|
47
|
+
echo "Detecting seed methods..."
|
|
48
|
+
|
|
49
|
+
SEED_METHODS=""
|
|
50
|
+
|
|
51
|
+
# HasData() in configurations (RECOMMENDED)
|
|
52
|
+
if grep -rq "\.HasData(" . --include="*.cs" 2>/dev/null; then
|
|
53
|
+
SEED_METHODS+=" hasdata"
|
|
54
|
+
echo " - HasData(): Found"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# IDataSeeder classes
|
|
58
|
+
if grep -rq "IDataSeeder\|class.*Seeder" . --include="*.cs" 2>/dev/null; then
|
|
59
|
+
SEED_METHODS+=" seeder-class"
|
|
60
|
+
echo " - Seeder classes: Found"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# --seed CLI argument
|
|
64
|
+
if grep -q "\-\-seed" ./src/*/Program.cs 2>/dev/null; then
|
|
65
|
+
SEED_METHODS+=" cli-argument"
|
|
66
|
+
echo " - CLI --seed: Found"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# WARNING: SQL scripts detected
|
|
70
|
+
if [ -f "./scripts/seed.sql" ] || find . -name "seed*.sql" 2>/dev/null | grep -q .; then
|
|
71
|
+
echo ""
|
|
72
|
+
echo "WARNING: SQL seed scripts detected - FORBIDDEN by conventions"
|
|
73
|
+
echo "Migrate to HasData() or IDataSeeder"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
if [ -z "$SEED_METHODS" ]; then
|
|
77
|
+
echo " No seed methods found"
|
|
78
|
+
fi
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Select Method
|
|
82
|
+
|
|
83
|
+
**If multiple methods available:**
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
AskUserQuestion:
|
|
87
|
+
header: "Seed"
|
|
88
|
+
question: "Which seed method to use?"
|
|
89
|
+
options:
|
|
90
|
+
- label: "HasData (Recommended)"
|
|
91
|
+
description: "Via EF Core migrations"
|
|
92
|
+
- label: "Seeder Class"
|
|
93
|
+
description: "Run DbSeeder/DataSeeder"
|
|
94
|
+
- label: "CLI --seed"
|
|
95
|
+
description: "Launch app with --seed"
|
|
96
|
+
multiSelect: false
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 4. Execute Seed
|
|
100
|
+
|
|
101
|
+
**HasData method:**
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
echo ""
|
|
105
|
+
echo "HasData is applied via migrations."
|
|
106
|
+
echo "Running database update to ensure all HasData is applied..."
|
|
107
|
+
|
|
108
|
+
dotnet ef database update \
|
|
109
|
+
--context "$DBCONTEXT" \
|
|
110
|
+
--project "$INFRA_PROJECT" \
|
|
111
|
+
--startup-project "$STARTUP_PROJECT"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Seeder Class method:**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
echo ""
|
|
118
|
+
echo "Running seeder class..."
|
|
119
|
+
|
|
120
|
+
dotnet run --project "$STARTUP_PROJECT" -- --seed
|
|
121
|
+
|
|
122
|
+
if [ $? -ne 0 ]; then
|
|
123
|
+
echo "Seed command failed or not supported."
|
|
124
|
+
echo "Check if --seed argument is implemented in Program.cs"
|
|
125
|
+
fi
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**CLI argument method:**
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
echo ""
|
|
132
|
+
echo "Running application with --seed..."
|
|
133
|
+
|
|
134
|
+
dotnet run --project "$STARTUP_PROJECT" -- --seed
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 5. Verify (Optional)
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
echo ""
|
|
141
|
+
echo "Verifying seed data..."
|
|
142
|
+
|
|
143
|
+
# Quick check - count records in key tables
|
|
144
|
+
# This is application-specific
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 6. Summary
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
echo ""
|
|
151
|
+
echo "==========================================="
|
|
152
|
+
echo "SEED COMPLETE"
|
|
153
|
+
echo "==========================================="
|
|
154
|
+
echo ""
|
|
155
|
+
echo "Database: $DATABASE_NAME"
|
|
156
|
+
echo "Environment: $SELECTED_ENV"
|
|
157
|
+
echo "Method: $SEED_METHOD"
|
|
158
|
+
echo ""
|
|
159
|
+
echo "Compliance: EF Core native, No raw SQL"
|
|
160
|
+
echo ""
|
|
161
|
+
echo "==========================================="
|
|
162
|
+
echo ""
|
|
163
|
+
echo "Next steps:"
|
|
164
|
+
echo " /efcore db-status # Check status"
|
|
165
|
+
echo " dotnet run # Start application"
|
|
166
|
+
echo ""
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## OUTPUT FORMAT:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
SEED COMPLETE
|
|
175
|
+
=============
|
|
176
|
+
Database: {database_name}
|
|
177
|
+
Environment: {env}
|
|
178
|
+
Method: {hasdata | seeder-class | cli-argument}
|
|
179
|
+
|
|
180
|
+
Compliance: EF Core native, No raw SQL
|
|
181
|
+
|
|
182
|
+
Next: /efcore db-status, dotnet run
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## NO SEED METHODS FOUND:
|
|
188
|
+
|
|
189
|
+
If no seed methods detected, display guide:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
SEED SETUP GUIDE
|
|
193
|
+
================
|
|
194
|
+
|
|
195
|
+
Option 1: HasData() in Configuration (RECOMMENDED)
|
|
196
|
+
--------------------------------------------------
|
|
197
|
+
// In UserConfiguration.cs
|
|
198
|
+
builder.HasData(new User {
|
|
199
|
+
Id = Guid.Parse("7f3c9a2e-8d1b-4e5f-a6c8-9b4d2f7e1a3c"),
|
|
200
|
+
Name = "Admin",
|
|
201
|
+
Email = "admin@example.com"
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Then run:
|
|
205
|
+
dotnet ef migrations add SeedData
|
|
206
|
+
|
|
207
|
+
Option 2: IDataSeeder Class
|
|
208
|
+
---------------------------
|
|
209
|
+
public class UserSeeder : IDataSeeder
|
|
210
|
+
{
|
|
211
|
+
public async Task SeedAsync(DbContext context)
|
|
212
|
+
{
|
|
213
|
+
if (!await context.Users.AnyAsync())
|
|
214
|
+
{
|
|
215
|
+
context.Users.Add(new User { ... });
|
|
216
|
+
await context.SaveChangesAsync();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Register in Program.cs and call via --seed argument
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## MIGRATION FROM SQL:
|
|
227
|
+
|
|
228
|
+
```csharp
|
|
229
|
+
// BEFORE (FORBIDDEN): scripts/seed.sql
|
|
230
|
+
INSERT INTO Users (Id, Name) VALUES (1, 'Admin');
|
|
231
|
+
|
|
232
|
+
// AFTER (CORRECT): UserConfiguration.cs
|
|
233
|
+
builder.HasData(new User {
|
|
234
|
+
Id = Guid.Parse("7f3c9a2e-8d1b-4e5f-a6c8-9b4d2f7e1a3c"),
|
|
235
|
+
Name = "Admin"
|
|
236
|
+
});
|
|
237
|
+
// Then: dotnet ef migrations add SeedData
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## COMPLETION:
|
|
243
|
+
|
|
244
|
+
Seed data applied. Use `/efcore db-status` to verify.
|