@atlashub/smartstack-cli 1.16.0 → 1.18.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.
Files changed (41) hide show
  1. package/dist/index.js +74897 -1477
  2. package/dist/index.js.map +1 -1
  3. package/package.json +5 -1
  4. package/templates/agents/efcore/db-deploy.md +5 -0
  5. package/templates/agents/efcore/db-reset.md +5 -0
  6. package/templates/agents/efcore/db-seed.md +5 -0
  7. package/templates/agents/efcore/db-status.md +5 -0
  8. package/templates/agents/efcore/migration.md +8 -0
  9. package/templates/agents/efcore/rebase-snapshot.md +41 -12
  10. package/templates/agents/efcore/squash.md +59 -19
  11. package/templates/commands/efcore/_shared.md +117 -0
  12. package/templates/commands/efcore/db-deploy.md +32 -4
  13. package/templates/commands/efcore/db-reset.md +38 -2
  14. package/templates/commands/efcore/db-status.md +24 -6
  15. package/templates/commands/efcore/migration.md +57 -9
  16. package/templates/commands/efcore/rebase-snapshot.md +56 -3
  17. package/templates/commands/efcore/squash.md +85 -18
  18. package/templates/skills/efcore/SKILL.md +162 -0
  19. package/templates/skills/efcore/steps/db/step-deploy.md +208 -0
  20. package/templates/skills/efcore/steps/db/step-reset.md +259 -0
  21. package/templates/skills/efcore/steps/db/step-seed.md +244 -0
  22. package/templates/skills/efcore/steps/db/step-status.md +198 -0
  23. package/templates/skills/efcore/steps/migration/step-00-init.md +102 -0
  24. package/templates/skills/efcore/steps/migration/step-01-check.md +138 -0
  25. package/templates/skills/efcore/steps/migration/step-02-create.md +144 -0
  26. package/templates/skills/efcore/steps/migration/step-03-validate.md +203 -0
  27. package/templates/skills/efcore/steps/rebase-snapshot/step-00-init.md +173 -0
  28. package/templates/skills/efcore/steps/rebase-snapshot/step-01-backup.md +100 -0
  29. package/templates/skills/efcore/steps/rebase-snapshot/step-02-fetch.md +115 -0
  30. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +108 -0
  31. package/templates/skills/efcore/steps/rebase-snapshot/step-04-validate.md +157 -0
  32. package/templates/skills/efcore/steps/shared/step-00-init.md +266 -0
  33. package/templates/skills/efcore/steps/squash/step-00-init.md +141 -0
  34. package/templates/skills/efcore/steps/squash/step-01-backup.md +120 -0
  35. package/templates/skills/efcore/steps/squash/step-02-fetch.md +168 -0
  36. package/templates/skills/efcore/steps/squash/step-03-create.md +178 -0
  37. package/templates/skills/efcore/steps/squash/step-04-validate.md +174 -0
  38. package/templates/skills/gitflow/steps/step-commit.md +25 -20
  39. package/templates/skills/gitflow/steps/step-start.md +9 -0
  40. package/templates/skills/review-code/SKILL.md +77 -0
  41. package/templates/skills/review-code/references/smartstack-conventions.md +302 -0
@@ -29,12 +29,31 @@ Options: `--force`, `--no-cross-check`, `--rebase-first`
29
29
 
30
30
  ---
31
31
 
32
- ## STEP 1: Contexte Git
32
+ ## STEP 1: Contexte Git et DbContext
33
33
 
34
34
  ```bash
35
35
  CURRENT_BRANCH=$(git branch --show-current)
36
36
  # Extraire type (feature/hotfix/release) et nom
37
- detect_efcore_project
37
+ detect_efcore_project # Appelle detect_dbcontext() automatiquement
38
+
39
+ echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
40
+ echo "Schema: $SCHEMA"
41
+ ```
42
+
43
+ **Si DbContext non détecté automatiquement :**
44
+
45
+ ```javascript
46
+ AskUserQuestion({
47
+ questions: [{
48
+ question: "Quel DbContext utiliser pour cette migration ?",
49
+ header: "DbContext",
50
+ options: [
51
+ { label: "CoreDbContext", description: "Entités SmartStack (User, Role, Navigation...)" },
52
+ { label: "ExtensionsDbContext", description: "Entités client spécifiques" }
53
+ ],
54
+ multiSelect: false
55
+ }]
56
+ })
38
57
  ```
39
58
 
40
59
  ---
@@ -68,32 +87,61 @@ AskUserQuestion({
68
87
 
69
88
  ---
70
89
 
71
- ## STEP 4: Nom Migration
90
+ ## STEP 4: Nom Migration (via MCP)
91
+
92
+ **OBLIGATOIRE : Utiliser le MCP pour le nommage conforme**
72
93
 
73
94
  Pattern: `{context}_v{version}_{sequence}_{Description}`
74
95
 
96
+ **4.1 Demander la description à l'utilisateur :**
97
+
75
98
  ```javascript
76
99
  AskUserQuestion({
77
100
  questions: [{
78
- question: "Description courte (ex: AddUserRoles)",
101
+ question: "Description courte de la migration (ex: Add User Roles)",
79
102
  header: "Description",
80
103
  options: [
81
- { label: "Add", description: "Ajout tables/colonnes" },
82
- { label: "Update", description: "Modification structure" },
83
- { label: "Fix", description: "Correction schéma" },
84
- { label: "Remove", description: "Suppression éléments" }
104
+ { label: "Add...", description: "Ajout tables/colonnes" },
105
+ { label: "Update...", description: "Modification structure" },
106
+ { label: "Fix...", description: "Correction schéma" },
107
+ { label: "Remove...", description: "Suppression éléments" }
85
108
  ],
86
109
  multiSelect: false
87
110
  }]
88
111
  })
112
+ // L'utilisateur peut aussi saisir un texte libre
89
113
  ```
90
114
 
115
+ **4.2 Appeler le MCP pour obtenir le nom conforme :**
116
+
117
+ ```javascript
118
+ // $DESCRIPTION = réponse de l'utilisateur (ex: "Add User Roles")
119
+ // $DBCONTEXT_TYPE = "core" ou "extensions" (de detect_dbcontext)
120
+
121
+ mcp__smartstack__suggest_migration({
122
+ description: DESCRIPTION,
123
+ context: DBCONTEXT_TYPE
124
+ })
125
+
126
+ // Résultat: core_v1.8.0_001_AddUserRoles
127
+ ```
128
+
129
+ > **INTERDIT :** Calculer le nom manuellement. Toujours déléguer au MCP.
130
+
91
131
  ---
92
132
 
93
133
  ## STEP 5: Création
94
134
 
95
135
  ```bash
96
- dotnet ef migrations add "$MIGRATION_NAME" -o Persistence/Migrations --verbose
136
+ # $MIGRATION_NAME = résultat du MCP
137
+ # $DBCONTEXT = CoreDbContext ou ExtensionsDbContext (de detect_dbcontext)
138
+
139
+ dotnet ef migrations add "$MIGRATION_NAME" \
140
+ --context "$DBCONTEXT" \
141
+ --project "$INFRA_PROJECT" \
142
+ --startup-project "$STARTUP_PROJECT" \
143
+ -o Persistence/Migrations \
144
+ --verbose
97
145
  ```
98
146
 
99
147
  ---
@@ -18,7 +18,29 @@ model: sonnet
18
18
  CURRENT_BRANCH=$(git branch --show-current)
19
19
  [[ ! $CURRENT_BRANCH =~ ^(feature|release|hotfix)/ ]] && exit 1
20
20
  [ -n "$(git status --porcelain)" ] && { echo "Working directory non clean"; exit 1; }
21
- detect_efcore_project
21
+
22
+ # Détecte projet ET DbContext (core vs extensions)
23
+ detect_efcore_project # Appelle detect_dbcontext() automatiquement
24
+ determine_base_branch # Détermine la branche parente
25
+
26
+ echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
27
+ echo "Branche parente: $BASE_BRANCH"
28
+ ```
29
+
30
+ **Si DbContext non détecté automatiquement :**
31
+
32
+ ```javascript
33
+ AskUserQuestion({
34
+ questions: [{
35
+ question: "Quel DbContext utiliser ?",
36
+ header: "DbContext",
37
+ options: [
38
+ { label: "CoreDbContext", description: "Entités SmartStack" },
39
+ { label: "ExtensionsDbContext", description: "Entités client" }
40
+ ],
41
+ multiSelect: false
42
+ }]
43
+ })
22
44
  ```
23
45
 
24
46
  ---
@@ -69,11 +91,42 @@ done
69
91
 
70
92
  ## STEP 6: Régénérer Migration Consolidée
71
93
 
94
+ **OBLIGATOIRE : Utiliser le MCP pour le nommage conforme**
95
+
96
+ ```bash
97
+ # Construire la description
98
+ BRANCH_NAME_CLEAN=$(echo "$CURRENT_BRANCH" | sed 's|.*/||' | sed 's/-/ /g')
99
+ DESCRIPTION="${BRANCH_NAME_CLEAN} Consolidated"
100
+ ```
101
+
102
+ **Appel MCP OBLIGATOIRE :**
103
+
104
+ ```javascript
105
+ // Obtenir le nom conforme via MCP
106
+ mcp__smartstack__suggest_migration({
107
+ description: DESCRIPTION, // Ex: "user auth Consolidated"
108
+ context: DBCONTEXT_TYPE // "core" ou "extensions" (de detect_dbcontext)
109
+ })
110
+
111
+ // Résultat: core_v1.7.0_001_UserAuthConsolidated
112
+ ```
113
+
114
+ **Puis créer la migration :**
115
+
72
116
  ```bash
73
- MIGRATION_NAME="${BRANCH_TYPE}_${VERSION}_${BRANCH_NAME}_Consolidated"
74
- dotnet ef migrations add "$MIGRATION_NAME" -o Persistence/Migrations --verbose
117
+ # $MIGRATION_NAME = résultat du MCP
118
+ # $DBCONTEXT = CoreDbContext ou ExtensionsDbContext
119
+
120
+ dotnet ef migrations add "$MIGRATION_NAME" \
121
+ --context "$DBCONTEXT" \
122
+ --project "$INFRA_PROJECT" \
123
+ --startup-project "$STARTUP_PROJECT" \
124
+ -o Persistence/Migrations \
125
+ --verbose
75
126
  ```
76
127
 
128
+ > **Convention :** `{context}_v{version}_{sequence}_{Description}` - Jamais de nom hardcodé
129
+
77
130
  ---
78
131
 
79
132
  ## STEP 7: Validation
@@ -48,7 +48,10 @@ determine_base_branch # Voir _shared.md
48
48
  ```bash
49
49
  CURRENT_BRANCH=$(git branch --show-current)
50
50
  [ -n "$(git status --porcelain)" ] && { echo "Working directory non propre"; exit 1; }
51
- detect_efcore_project
51
+ detect_efcore_project # Appelle detect_dbcontext() → $DBCONTEXT, $DBCONTEXT_TYPE, $SCHEMA
52
+
53
+ echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
54
+ echo "Schema: $SCHEMA"
52
55
 
53
56
  # Compter migrations LOCALES uniquement (pas celles héritées)
54
57
  git fetch origin "$BASE_BRANCH" --quiet
@@ -103,24 +106,52 @@ echo "Backup: $BACKUP_DIR"
103
106
 
104
107
  ---
105
108
 
106
- ## STEP 4: Récupérer ModelSnapshot de la Branche Parente (CRUCIAL)
109
+ ## STEP 4: Récupérer Migrations ET Snapshot de la Branche Parente (CRUCIAL)
107
110
 
108
111
  ```bash
109
112
  # Sauvegarder snapshot actuel
110
113
  cp "$MIGRATIONS_DIR"/*ModelSnapshot.cs "$BACKUP_DIR/"
111
114
 
112
- # Récupérer le snapshot de la branche parente
115
+ # Récupérer TOUTES les migrations de la branche parente
113
116
  git fetch origin "$BASE_BRANCH" --quiet
117
+
118
+ # 1. Récupérer le ModelSnapshot
114
119
  git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR"/*ModelSnapshot.cs
115
120
 
116
- echo "ModelSnapshot récupéré depuis: origin/$BASE_BRANCH"
121
+ # 2. Récupérer les fichiers de migration de la branche parente
122
+ # (pour ne pas perdre les migrations déjà présentes sur develop/main)
123
+ for base_mig in $BASE_MIGRATIONS; do
124
+ base_file=$(basename "$base_mig")
125
+ base_name="${base_file%.cs}"
126
+
127
+ # Récupérer le fichier migration ET son Designer
128
+ git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR/${base_name}.cs" 2>/dev/null || true
129
+ git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR/${base_name}.Designer.cs" 2>/dev/null || true
130
+ done
131
+
132
+ echo "Récupéré depuis origin/$BASE_BRANCH:"
133
+ echo " - ModelSnapshot"
134
+ echo " - $(echo "$BASE_MIGRATIONS" | wc -l) migrations"
117
135
  ```
118
136
 
119
137
  **Pourquoi c'est crucial:**
120
138
  - Le snapshot de `$BASE_BRANCH` contient l'état VALIDÉ et COMPLET
139
+ - Les **migrations existantes** de `$BASE_BRANCH` doivent être conservées
121
140
  - Les migrations parallèles sur d'autres branches sont incluses
122
141
  - Évite la perte d'information de schéma (cf. [Bokio best practices](https://www.bokio.se/engineering-blog/how-to-squash-ef-core-migrations/))
123
142
 
143
+ **Résultat attendu:**
144
+ ```
145
+ feature/multitenant après squash:
146
+ ├── core_v1.8.0_001_InitialSchema.cs ← De develop (conservé)
147
+ ├── core_v1.8.0_001_InitialSchema.Designer.cs
148
+ ├── core_v1.9.0_001_MultitenantConsolidated.cs ← Squash de la feature (MCP)
149
+ ├── core_v1.9.0_001_MultitenantConsolidated.Designer.cs
150
+ └── CoreDbContextModelSnapshot.cs ← De develop
151
+ ```
152
+
153
+ ⚠️ **ATTENTION:** Si le résultat ne montre pas les migrations de develop, le squash a échoué!
154
+
124
155
  ---
125
156
 
126
157
  ## STEP 5: Supprimer Migrations de la Branche (pas celles héritées)
@@ -139,36 +170,64 @@ echo "Supprimé: ${#BRANCH_ONLY_MIGRATIONS[@]} migrations"
139
170
 
140
171
  ## STEP 6: Créer Migration Consolidée
141
172
 
173
+ **OBLIGATOIRE: Utiliser le MCP pour le nommage conforme**
174
+
142
175
  ```bash
143
- # Nommage selon contexte
176
+ # Construire la description selon le contexte
144
177
  case "$BRANCH_TYPE" in
145
178
  feature)
146
- BRANCH_NAME=$(echo "$CURRENT_BRANCH" | sed 's|feature/||')
147
- MIGRATION_NAME="Feature_${BRANCH_NAME}_Consolidated"
179
+ BRANCH_NAME=$(echo "$CURRENT_BRANCH" | sed 's|feature/||' | sed 's/-/ /g')
180
+ DESCRIPTION="${BRANCH_NAME} Consolidated"
148
181
  ;;
149
182
  release)
150
- VERSION=$(echo "$CURRENT_BRANCH" | sed 's|release/||' | tr '.' '_')
151
- MIGRATION_NAME="Release_${VERSION}_Initial"
183
+ VERSION=$(echo "$CURRENT_BRANCH" | sed 's|release/||')
184
+ DESCRIPTION="Release ${VERSION} Initial"
152
185
  ;;
153
186
  hotfix)
154
- VERSION=$(echo "$CURRENT_BRANCH" | sed 's|hotfix/||' | tr '.' '_')
155
- MIGRATION_NAME="Hotfix_${VERSION}_Fix"
187
+ VERSION=$(echo "$CURRENT_BRANCH" | sed 's|hotfix/||')
188
+ DESCRIPTION="Hotfix ${VERSION} Fix"
156
189
  ;;
157
190
  develop)
158
- MIGRATION_NAME="Develop_Consolidated_$(date +%Y%m%d)"
191
+ DESCRIPTION="Develop Consolidated"
159
192
  ;;
160
193
  *)
161
- MIGRATION_NAME="Consolidated_$(date +%Y%m%d_%H%M%S)"
194
+ DESCRIPTION="Consolidated"
162
195
  ;;
163
196
  esac
197
+ ```
198
+
199
+ **Appel MCP OBLIGATOIRE:**
200
+
201
+ ```javascript
202
+ // $DESCRIPTION = construit ci-dessus (ex: "multitenant Consolidated")
203
+ // $DBCONTEXT_TYPE = "core" ou "extensions" (de detect_dbcontext)
204
+
205
+ mcp__smartstack__suggest_migration({
206
+ description: DESCRIPTION,
207
+ context: DBCONTEXT_TYPE // JAMAIS hardcodé!
208
+ })
209
+
210
+ // Résultat: core_v1.9.0_001_MultitenantConsolidated
211
+ ```
212
+
213
+ > **INTERDIT :** Calculer le nom manuellement ou hardcoder le context.
214
+
215
+ **Puis créer la migration:**
216
+
217
+ ```bash
218
+ # MIGRATION_NAME = résultat du MCP (ex: core_v1.9.0_001_MultitenantConsolidated)
219
+ # DBCONTEXT = CoreDbContext ou ExtensionsDbContext (de detect_dbcontext)
164
220
 
165
221
  dotnet ef migrations add "$MIGRATION_NAME" \
222
+ --context "$DBCONTEXT" \
166
223
  --project "$INFRA_PROJECT" \
167
224
  --startup-project "$STARTUP_PROJECT" \
168
225
  -o Persistence/Migrations \
169
226
  --verbose
170
227
  ```
171
228
 
229
+ > **Convention:** `{context}_v{version}_{sequence}_{Description}` - Jamais de nom hardcodé
230
+
172
231
  ---
173
232
 
174
233
  ## STEP 7: Validation
@@ -192,11 +251,19 @@ dotnet ef migrations script --no-build --idempotent > /dev/null
192
251
 
193
252
  ```
194
253
  SQUASH - {CURRENT_BRANCH}
195
- Base: {BASE_BRANCH} (snapshot récupéré)
196
- Backup: {BACKUP_DIR}
197
- Avant: {MIGRATION_COUNT} migrations
198
- Apres: 1 migration ({MIGRATION_NAME})
199
- Conformite: EF Core CLI, Pas de .sql, Snapshot parent
254
+ Base: {BASE_BRANCH}
255
+ Backup: {BACKUP_DIR}
256
+
257
+ Récupéré de {BASE_BRANCH}:
258
+ - ModelSnapshot
259
+ - {BASE_MIGRATION_COUNT} migrations (conservées)
260
+
261
+ Consolidé:
262
+ - Avant: {MIGRATION_COUNT} migrations (propres à la branche)
263
+ - Après: 1 migration ({MIGRATION_NAME})
264
+
265
+ Total final: {BASE_MIGRATION_COUNT + 1} migrations
266
+ Conformité: MCP suggest_migration, EF Core CLI, Snapshot parent
200
267
 
201
268
  Prochains: /efcore:db-reset, /efcore:db-deploy, /gitflow:3-commit
202
269
  ```
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: efcore
3
+ description: EF Core Commands - Migration and database management
4
+ argument-hint: "<command> [options]"
5
+ ---
6
+
7
+ <objective>
8
+ Manage EF Core migrations and database operations with progressive step loading, MCP validation, and DbContext auto-detection.
9
+ </objective>
10
+
11
+ <quick_start>
12
+ **Database operations:**
13
+ ```bash
14
+ /efcore db-status # Check migration status
15
+ /efcore db-deploy # Apply pending migrations
16
+ /efcore db-reset # Drop + recreate database
17
+ /efcore db-seed # Populate with test data
18
+ ```
19
+
20
+ **Migration operations:**
21
+ ```bash
22
+ /efcore migration # Create migration for current branch
23
+ /efcore squash # Consolidate branch migrations
24
+ /efcore rebase-snapshot # Sync snapshot with parent branch
25
+ /efcore scan # Scan for cross-branch conflicts
26
+ /efcore conflicts # Analyze migration conflicts
27
+ ```
28
+ </quick_start>
29
+
30
+ <parameters>
31
+
32
+ <subcommands>
33
+ | Command | Description | Steps |
34
+ |---------|-------------|-------|
35
+ | `db-status` | Display migrations and database status | steps/db/status/ |
36
+ | `db-deploy` | Apply pending migrations | steps/db/deploy/ |
37
+ | `db-reset` | Drop + recreate database | steps/db/reset/ |
38
+ | `db-seed` | Populate with test data | steps/db/seed/ |
39
+ | `migration` | Create/recreate migration | steps/migration/ |
40
+ | `squash` | Consolidate migrations | steps/squash/ |
41
+ | `rebase-snapshot` | Sync snapshot with parent | steps/rebase-snapshot/ |
42
+ | `scan` | Scan for conflicts | (MCP-centric) |
43
+ | `conflicts` | Analyze conflicts | (MCP-centric) |
44
+ </subcommands>
45
+
46
+ <flags>
47
+ | Flag | Description |
48
+ |------|-------------|
49
+ | `--context <name>` | Specify DbContext (CoreDbContext/ExtensionsDbContext) |
50
+ | `--env <name>` | Use appsettings.{name}.json |
51
+ | `--verbose` | Show detailed output |
52
+ | `--force` | Skip confirmations |
53
+ | `--dry-run` | Preview without executing |
54
+ </flags>
55
+
56
+ </parameters>
57
+
58
+ <state_variables>
59
+ **Shared state across all steps:**
60
+
61
+ | Variable | Type | Description |
62
+ |----------|------|-------------|
63
+ | `{command}` | string | Current subcommand |
64
+ | `{dbcontext}` | string | CoreDbContext or ExtensionsDbContext |
65
+ | `{dbcontext_type}` | string | "core" or "extensions" |
66
+ | `{schema}` | string | Database schema |
67
+ | `{infra_project}` | string | Path to Infrastructure project |
68
+ | `{startup_project}` | string | Path to API/Web project |
69
+ | `{migrations_dir}` | string | Path to Migrations folder |
70
+ | `{base_branch}` | string | Parent branch (develop/main) |
71
+ | `{branch_type}` | string | feature/release/hotfix |
72
+ | `{auto_mode}` | boolean | Skip confirmations |
73
+ </state_variables>
74
+
75
+ <entry_point>
76
+
77
+ **ROUTING LOGIC:**
78
+
79
+ 1. Parse command and flags from input
80
+ 2. Load shared init step: `steps/shared/step-00-init.md`
81
+ 3. Route to command-specific steps:
82
+
83
+ | Command | Route To |
84
+ |---------|----------|
85
+ | `db-status` | `steps/db/step-status.md` |
86
+ | `db-deploy` | `steps/db/step-deploy.md` |
87
+ | `db-reset` | `steps/db/step-reset.md` |
88
+ | `db-seed` | `steps/db/step-seed.md` |
89
+ | `migration` | `steps/migration/step-00-init.md` |
90
+ | `squash` | `steps/squash/step-00-init.md` |
91
+ | `rebase-snapshot` | `steps/rebase-snapshot/step-00-init.md` |
92
+ | `scan` | Use `commands/efcore/scan.md` (MCP-centric, no steps) |
93
+ | `conflicts` | Use `commands/efcore/conflicts.md` (MCP-centric, no steps) |
94
+
95
+ </entry_point>
96
+
97
+ <shared_functions>
98
+ **Always load first:** `steps/shared/step-00-init.md`
99
+
100
+ This step provides:
101
+ - `detect_efcore_project()` - Find EF Core project files
102
+ - `detect_dbcontext()` - Auto-detect Core vs Extensions
103
+ - `detect_environment()` - Load connection string
104
+ - `determine_base_branch()` - Find parent branch
105
+ - `block_production()` - Safety check
106
+
107
+ **MCP Integration:**
108
+ - `mcp__smartstack__suggest_migration` - Generate compliant names
109
+ - `mcp__smartstack__check_migrations` - Analyze conflicts
110
+ - `mcp__smartstack__validate_conventions` - Validate structure
111
+ </shared_functions>
112
+
113
+ <dual_dbcontext>
114
+ SmartStack uses **two separate DbContexts**:
115
+
116
+ | Context | DbContext | Schema | History Table |
117
+ |---------|-----------|--------|---------------|
118
+ | `core` | `CoreDbContext` | `core` | `core.__EFMigrationsHistory` |
119
+ | `extensions` | `ExtensionsDbContext` | `extensions` | `extensions.__EFMigrationsHistory` |
120
+
121
+ **Auto-detection priority:**
122
+ 1. SmartStack.Domain exists → CoreDbContext
123
+ 2. Client with SmartStack NuGet → ExtensionsDbContext
124
+ 3. Code scan for DbContext classes
125
+ 4. Ask user if ambiguous
126
+ </dual_dbcontext>
127
+
128
+ <naming_convention>
129
+ **Migration naming (MCP MANDATORY):**
130
+
131
+ Pattern: `{context}_v{version}_{sequence}_{Description}`
132
+
133
+ Examples:
134
+ - `core_v1.9.0_001_AddUserRoles`
135
+ - `extensions_v1.2.0_001_AddCustomFields`
136
+
137
+ **FORBIDDEN:** Manual name calculation. Always use MCP.
138
+ </naming_convention>
139
+
140
+ <safety_rules>
141
+ 1. **Backup MANDATORY** for destructive operations
142
+ 2. **Production BLOCKED** - Never run on production
143
+ 3. **1 migration per feature** - Recreate, don't accumulate
144
+ 4. **Snapshot + Migrations** - Always recover BOTH from parent
145
+ 5. **MCP for naming** - Never hardcode migration names
146
+ </safety_rules>
147
+
148
+ <execution_rules>
149
+ - **Load one step at a time** - Progressive loading
150
+ - **State persists** - Variables carry across steps
151
+ - **Follow next_step** - Each step defines next
152
+ - **MCP validation** - Use SmartStack tools
153
+ - **Safety > Correctness > Speed**
154
+ </execution_rules>
155
+
156
+ <success_criteria>
157
+ - DbContext correctly detected
158
+ - Migrations created with MCP naming
159
+ - Database operations succeed
160
+ - Parent migrations preserved (for squash/rebase)
161
+ - Build passes after changes
162
+ </success_criteria>