@atlashub/smartstack-cli 1.16.0 → 1.17.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 +74897 -1477
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/templates/agents/efcore/rebase-snapshot.md +32 -12
- package/templates/agents/efcore/squash.md +14 -4
- package/templates/commands/efcore/_shared.md +117 -0
- package/templates/commands/efcore/db-deploy.md +32 -4
- package/templates/commands/efcore/db-reset.md +38 -2
- package/templates/commands/efcore/db-status.md +24 -6
- package/templates/commands/efcore/migration.md +57 -9
- package/templates/commands/efcore/rebase-snapshot.md +56 -3
- package/templates/commands/efcore/squash.md +72 -17
- package/templates/skills/gitflow/steps/step-commit.md +25 -20
- package/templates/skills/gitflow/steps/step-start.md +9 -0
- package/templates/skills/review-code/SKILL.md +77 -0
- package/templates/skills/review-code/references/smartstack-conventions.md +302 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlashub/smartstack-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "SmartStack Claude Code automation toolkit - GitFlow, APEX, EF Core migrations, prompts and more",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SmartStack",
|
|
@@ -70,19 +70,23 @@
|
|
|
70
70
|
"health": "node dist/index.js doctor --json"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
+
"bcryptjs": "^2.4.3",
|
|
73
74
|
"chalk": "^5.3.0",
|
|
74
75
|
"cli-table3": "^0.6.3",
|
|
75
76
|
"commander": "^12.0.0",
|
|
76
77
|
"fs-extra": "^11.2.0",
|
|
77
78
|
"inquirer": "^9.2.12",
|
|
78
79
|
"jsonwebtoken": "^9.0.3",
|
|
80
|
+
"mssql": "^11.0.1",
|
|
79
81
|
"ora": "^8.0.1",
|
|
80
82
|
"zod": "^3.22.4"
|
|
81
83
|
},
|
|
82
84
|
"devDependencies": {
|
|
85
|
+
"@types/bcryptjs": "^2.4.6",
|
|
83
86
|
"@types/fs-extra": "^11.0.4",
|
|
84
87
|
"@types/inquirer": "^9.0.7",
|
|
85
88
|
"@types/jsonwebtoken": "^9.0.10",
|
|
89
|
+
"@types/mssql": "^9.1.5",
|
|
86
90
|
"@types/node": "^20.10.6",
|
|
87
91
|
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
|
88
92
|
"@typescript-eslint/parser": "^6.18.0",
|
|
@@ -21,35 +21,55 @@ Rebases ModelSnapshot on develop to resolve conflicts.
|
|
|
21
21
|
## Key Commands
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
+
# Détection projet et DbContext
|
|
25
|
+
detect_efcore_project # → $DBCONTEXT, $DBCONTEXT_TYPE, $SCHEMA
|
|
26
|
+
determine_base_branch # → $BASE_BRANCH, $BRANCH_TYPE
|
|
27
|
+
|
|
24
28
|
# Backup
|
|
25
29
|
BACKUP_DIR=".claude/gitflow/backup/migrations/rebase_$(date +%Y%m%d_%H%M%S)"
|
|
26
30
|
mkdir -p "$BACKUP_DIR"
|
|
27
31
|
cp Migrations/*.cs "$BACKUP_DIR/"
|
|
28
32
|
|
|
29
|
-
# Reset snapshot to develop
|
|
30
|
-
git
|
|
33
|
+
# Reset snapshot to parent branch (develop ou main selon contexte)
|
|
34
|
+
git fetch origin "$BASE_BRANCH"
|
|
35
|
+
git checkout "origin/$BASE_BRANCH" -- Migrations/*ModelSnapshot.cs
|
|
36
|
+
|
|
37
|
+
# Récupérer les migrations de la branche parente
|
|
38
|
+
BASE_MIGS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- Migrations/ | grep "\.cs$" | grep -v "Designer\|Snapshot")
|
|
39
|
+
for base_mig in $BASE_MIGS; do
|
|
40
|
+
base_name=$(basename "${base_mig%.cs}")
|
|
41
|
+
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.cs" 2>/dev/null || true
|
|
42
|
+
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.Designer.cs" 2>/dev/null || true
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
# Delete branch migrations only
|
|
46
|
+
rm -f Migrations/*${BRANCH_TYPE}_*.cs
|
|
47
|
+
rm -f Migrations/*${BRANCH_TYPE}_*.Designer.cs
|
|
31
48
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
# Regenerate with MCP naming - OBLIGATOIRE
|
|
50
|
+
mcp__smartstack__suggest_migration({ description: "...", context: DBCONTEXT_TYPE })
|
|
51
|
+
# Résultat: core_v1.7.0_001_UserAuthConsolidated
|
|
35
52
|
|
|
36
|
-
|
|
37
|
-
dotnet ef migrations add Feature_1_7_0_Consolidated
|
|
53
|
+
dotnet ef migrations add "$MIGRATION_NAME" --context "$DBCONTEXT"
|
|
38
54
|
|
|
39
55
|
# Validate
|
|
40
56
|
dotnet build
|
|
41
57
|
```
|
|
42
58
|
|
|
43
|
-
## Migration Naming
|
|
59
|
+
## Migration Naming (via MCP)
|
|
60
|
+
|
|
61
|
+
**OBLIGATOIRE : Utiliser le MCP pour le nommage**
|
|
44
62
|
|
|
45
63
|
```
|
|
46
|
-
{
|
|
64
|
+
{context}_v{version}_{sequence}_{Description}
|
|
47
65
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
core_v1.7.0_001_UserAuthConsolidated
|
|
67
|
+
core_v1.6.2_001_LoginFixFix
|
|
68
|
+
core_v1.7.0_001_ReleaseInitial
|
|
51
69
|
```
|
|
52
70
|
|
|
71
|
+
> **INTERDIT :** Pattern ancien `Feature_1_7_0_UserAuth_Consolidated`
|
|
72
|
+
|
|
53
73
|
## Safety Checks
|
|
54
74
|
|
|
55
75
|
- [ ] Clean working directory
|
|
@@ -40,24 +40,34 @@ main → BLOQUÉ (jamais squash)
|
|
|
40
40
|
determine_base_branch # → BASE_BRANCH, BRANCH_TYPE
|
|
41
41
|
|
|
42
42
|
# Identifier migrations propres à la branche
|
|
43
|
-
BASE_MIGS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- Migrations/)
|
|
43
|
+
BASE_MIGS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- Migrations/ | grep "\.cs$" | grep -v "Designer\|Snapshot")
|
|
44
44
|
LOCAL_MIGS=$(find Migrations -name "*.cs" | grep -v Designer | grep -v Snapshot)
|
|
45
45
|
|
|
46
46
|
# Backup
|
|
47
47
|
BACKUP_DIR=".claude/gitflow/backup/migrations/squash_$(date +%Y%m%d_%H%M%S)"
|
|
48
48
|
mkdir -p "$BACKUP_DIR" && cp Migrations/*.cs "$BACKUP_DIR/"
|
|
49
49
|
|
|
50
|
-
# CRUCIAL: Récupérer snapshot
|
|
50
|
+
# CRUCIAL: Récupérer snapshot ET migrations de la branche parente
|
|
51
51
|
git fetch origin "$BASE_BRANCH"
|
|
52
52
|
git checkout "origin/$BASE_BRANCH" -- Migrations/*ModelSnapshot.cs
|
|
53
53
|
|
|
54
|
+
# Récupérer les migrations de la branche parente (pour ne pas les perdre)
|
|
55
|
+
for base_mig in $BASE_MIGS; do
|
|
56
|
+
base_name=$(basename "${base_mig%.cs}")
|
|
57
|
+
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.cs" 2>/dev/null || true
|
|
58
|
+
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.Designer.cs" 2>/dev/null || true
|
|
59
|
+
done
|
|
60
|
+
|
|
54
61
|
# Supprimer migrations de la branche uniquement
|
|
55
62
|
for mig in $BRANCH_ONLY_MIGRATIONS; do
|
|
56
63
|
rm -f "Migrations/${mig}"*
|
|
57
64
|
done
|
|
58
65
|
|
|
59
|
-
# Créer migration consolidée
|
|
60
|
-
|
|
66
|
+
# Créer migration consolidée - UTILISER MCP OBLIGATOIRE
|
|
67
|
+
mcp__smartstack__suggest_migration({ description: "...", context: "core" })
|
|
68
|
+
# Résultat: core_v1.0.0_001_Description
|
|
69
|
+
|
|
70
|
+
dotnet ef migrations add "$MIGRATION_NAME_FROM_MCP"
|
|
61
71
|
|
|
62
72
|
# Valider
|
|
63
73
|
dotnet build && dotnet ef migrations script --idempotent > /dev/null
|
|
@@ -16,6 +16,94 @@ detect_efcore_project() {
|
|
|
16
16
|
STARTUP_PROJECT=$(find . -name "*.Api.csproj" -o -name "*Web.csproj" | head -1)
|
|
17
17
|
INFRA_PROJECT=$(find . -name "*Infrastructure.csproj" | head -1)
|
|
18
18
|
[ -z "$INFRA_PROJECT" ] && INFRA_PROJECT="$CSPROJ"
|
|
19
|
+
|
|
20
|
+
# Appeler la détection du DbContext
|
|
21
|
+
detect_dbcontext
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Détection DbContext (Core vs Extensions)
|
|
28
|
+
|
|
29
|
+
SmartStack utilise **deux DbContext séparés** avec des historiques de migration distincts :
|
|
30
|
+
|
|
31
|
+
| Context | DbContext | Schema | History Table |
|
|
32
|
+
|---------|-----------|--------|---------------|
|
|
33
|
+
| `core` | `CoreDbContext` | `core` | `core.__EFMigrationsHistory` |
|
|
34
|
+
| `extensions` | `ExtensionsDbContext` | `extensions` | `extensions.__EFMigrationsHistory` |
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
detect_dbcontext() {
|
|
38
|
+
# 1. Vérifier si SmartStack.Domain existe → CoreDbContext
|
|
39
|
+
if find . -type d -name "SmartStack.Domain" | grep -q .; then
|
|
40
|
+
DBCONTEXT="CoreDbContext"
|
|
41
|
+
DBCONTEXT_TYPE="core"
|
|
42
|
+
SCHEMA="core"
|
|
43
|
+
echo "DbContext détecté: CoreDbContext (SmartStack.Domain trouvé)"
|
|
44
|
+
return
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# 2. Vérifier si projet client avec NuGet SmartStack → ExtensionsDbContext
|
|
48
|
+
if find . -name "*.csproj" -exec grep -l "SmartStack\." {} \; | grep -qv "SmartStack\."; then
|
|
49
|
+
DBCONTEXT="ExtensionsDbContext"
|
|
50
|
+
DBCONTEXT_TYPE="extensions"
|
|
51
|
+
SCHEMA="extensions"
|
|
52
|
+
echo "DbContext détecté: ExtensionsDbContext (Client avec NuGet SmartStack)"
|
|
53
|
+
return
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# 3. Vérifier les DbContext présents dans le code
|
|
57
|
+
CORE_CTX=$(find . -name "*.cs" -exec grep -l "CoreDbContext" {} \; 2>/dev/null | head -1)
|
|
58
|
+
EXT_CTX=$(find . -name "*.cs" -exec grep -l "ExtensionsDbContext" {} \; 2>/dev/null | head -1)
|
|
59
|
+
|
|
60
|
+
if [ -n "$CORE_CTX" ] && [ -z "$EXT_CTX" ]; then
|
|
61
|
+
DBCONTEXT="CoreDbContext"
|
|
62
|
+
DBCONTEXT_TYPE="core"
|
|
63
|
+
SCHEMA="core"
|
|
64
|
+
elif [ -z "$CORE_CTX" ] && [ -n "$EXT_CTX" ]; then
|
|
65
|
+
DBCONTEXT="ExtensionsDbContext"
|
|
66
|
+
DBCONTEXT_TYPE="extensions"
|
|
67
|
+
SCHEMA="extensions"
|
|
68
|
+
else
|
|
69
|
+
# 4. Les deux existent ou aucun trouvé → demander à l'utilisateur
|
|
70
|
+
DBCONTEXT=""
|
|
71
|
+
DBCONTEXT_TYPE=""
|
|
72
|
+
SCHEMA=""
|
|
73
|
+
echo "⚠️ DbContext non détecté automatiquement"
|
|
74
|
+
echo "→ Utiliser AskUserQuestion pour demander à l'utilisateur"
|
|
75
|
+
fi
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Variables exportées :**
|
|
80
|
+
|
|
81
|
+
| Variable | Valeurs possibles | Description |
|
|
82
|
+
|----------|-------------------|-------------|
|
|
83
|
+
| `$DBCONTEXT` | `CoreDbContext` / `ExtensionsDbContext` | Nom du DbContext |
|
|
84
|
+
| `$DBCONTEXT_TYPE` | `core` / `extensions` | Type pour le MCP |
|
|
85
|
+
| `$SCHEMA` | `core` / `extensions` | Schéma de base de données |
|
|
86
|
+
|
|
87
|
+
**Si détection échoue, demander à l'utilisateur :**
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
AskUserQuestion({
|
|
91
|
+
questions: [{
|
|
92
|
+
question: "Quel DbContext utiliser pour cette migration ?",
|
|
93
|
+
header: "DbContext",
|
|
94
|
+
options: [
|
|
95
|
+
{ label: "CoreDbContext", description: "Entités SmartStack (User, Role, Navigation...)" },
|
|
96
|
+
{ label: "ExtensionsDbContext", description: "Entités client spécifiques" }
|
|
97
|
+
],
|
|
98
|
+
multiSelect: false
|
|
99
|
+
}]
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
// Puis définir les variables selon la réponse
|
|
103
|
+
if (answer === "CoreDbContext") {
|
|
104
|
+
DBCONTEXT="CoreDbContext"; DBCONTEXT_TYPE="core"; SCHEMA="core";
|
|
105
|
+
} else {
|
|
106
|
+
DBCONTEXT="ExtensionsDbContext"; DBCONTEXT_TYPE="extensions"; SCHEMA="extensions";
|
|
19
107
|
}
|
|
20
108
|
```
|
|
21
109
|
|
|
@@ -155,6 +243,8 @@ determine_base_branch() {
|
|
|
155
243
|
|
|
156
244
|
## Convention Nommage Migration
|
|
157
245
|
|
|
246
|
+
**OBLIGATOIRE : Utiliser le MCP pour le nommage**
|
|
247
|
+
|
|
158
248
|
Pattern: `{context}_v{version}_{sequence}_{Description}`
|
|
159
249
|
|
|
160
250
|
| Contexte | Version | Séquence | Description | Exemple |
|
|
@@ -162,6 +252,33 @@ Pattern: `{context}_v{version}_{sequence}_{Description}`
|
|
|
162
252
|
| core | 1.2.0 | 001 | AddUserRoles | `core_v1.2.0_001_AddUserRoles` |
|
|
163
253
|
| extensions | 1.3.0 | 001 | AddCustomFields | `extensions_v1.3.0_001_AddCustomFields` |
|
|
164
254
|
|
|
255
|
+
**Appel MCP OBLIGATOIRE :**
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
// TOUJOURS appeler le MCP pour obtenir le nom conforme
|
|
259
|
+
mcp__smartstack__suggest_migration({
|
|
260
|
+
description: "Add User Roles", // Description courte
|
|
261
|
+
context: DBCONTEXT_TYPE // "core" ou "extensions" (de detect_dbcontext)
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
// Résultat: core_v1.2.0_001_AddUserRoles
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Création migration avec le nom MCP :**
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# $MIGRATION_NAME = résultat du MCP
|
|
271
|
+
# $DBCONTEXT = CoreDbContext ou ExtensionsDbContext (de detect_dbcontext)
|
|
272
|
+
|
|
273
|
+
dotnet ef migrations add "$MIGRATION_NAME" \
|
|
274
|
+
--context "$DBCONTEXT" \
|
|
275
|
+
--project "$INFRA_PROJECT" \
|
|
276
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
277
|
+
-o Persistence/Migrations
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
> **INTERDIT :** Calculer le nom de migration manuellement. Toujours déléguer au MCP.
|
|
281
|
+
|
|
165
282
|
---
|
|
166
283
|
|
|
167
284
|
## Règle d'Or: 1 Migration par Feature
|
|
@@ -21,10 +21,28 @@ Afficher: fichiers disponibles, environnement sélectionné, connexion cible.
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
## STEP 1: Détecter Projet
|
|
24
|
+
## STEP 1: Détecter Projet et DbContext
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
detect_efcore_project
|
|
27
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
28
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Si DbContext non détecté automatiquement :**
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
AskUserQuestion({
|
|
35
|
+
questions: [{
|
|
36
|
+
question: "Quel DbContext déployer ?",
|
|
37
|
+
header: "DbContext",
|
|
38
|
+
options: [
|
|
39
|
+
{ label: "CoreDbContext", description: "Migrations du schéma core" },
|
|
40
|
+
{ label: "ExtensionsDbContext", description: "Migrations du schéma extensions" },
|
|
41
|
+
{ label: "Les deux", description: "Déployer core puis extensions" }
|
|
42
|
+
],
|
|
43
|
+
multiSelect: false
|
|
44
|
+
}]
|
|
45
|
+
})
|
|
28
46
|
```
|
|
29
47
|
|
|
30
48
|
---
|
|
@@ -32,7 +50,11 @@ detect_efcore_project
|
|
|
32
50
|
## STEP 2: Vérifier Migrations Pending
|
|
33
51
|
|
|
34
52
|
```bash
|
|
35
|
-
PENDING_COUNT=$(dotnet ef migrations list
|
|
53
|
+
PENDING_COUNT=$(dotnet ef migrations list \
|
|
54
|
+
--context "$DBCONTEXT" \
|
|
55
|
+
--project "$INFRA_PROJECT" \
|
|
56
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
57
|
+
--json | grep -c '"applied": false')
|
|
36
58
|
```
|
|
37
59
|
|
|
38
60
|
---
|
|
@@ -40,9 +62,15 @@ PENDING_COUNT=$(dotnet ef migrations list --json | grep -c '"applied": false')
|
|
|
40
62
|
## STEP 3: Appliquer
|
|
41
63
|
|
|
42
64
|
```bash
|
|
43
|
-
dotnet ef database update
|
|
65
|
+
dotnet ef database update \
|
|
66
|
+
--context "$DBCONTEXT" \
|
|
67
|
+
--project "$INFRA_PROJECT" \
|
|
68
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
69
|
+
--verbose
|
|
44
70
|
```
|
|
45
71
|
|
|
72
|
+
> **Note :** Si "Les deux" sélectionné, exécuter pour CoreDbContext puis ExtensionsDbContext.
|
|
73
|
+
|
|
46
74
|
---
|
|
47
75
|
|
|
48
76
|
## Résumé
|
|
@@ -81,18 +81,54 @@ backup_database # Fonction de _shared.md
|
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
84
|
+
## STEP 2.5: Détection DbContext
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
88
|
+
echo "DbContext: $DBCONTEXT"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Si DbContext non détecté ou plusieurs contextes :**
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
AskUserQuestion({
|
|
95
|
+
questions: [{
|
|
96
|
+
question: "Quel DbContext reset ? (ou 'both' pour les deux)",
|
|
97
|
+
header: "DbContext",
|
|
98
|
+
options: [
|
|
99
|
+
{ label: "CoreDbContext", description: "Reset schéma core uniquement" },
|
|
100
|
+
{ label: "ExtensionsDbContext", description: "Reset schéma extensions uniquement" },
|
|
101
|
+
{ label: "Les deux", description: "Reset complet (core + extensions)" }
|
|
102
|
+
],
|
|
103
|
+
multiSelect: false
|
|
104
|
+
}]
|
|
105
|
+
})
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
84
110
|
## STEP 3: Drop Database
|
|
85
111
|
|
|
86
112
|
```bash
|
|
87
|
-
dotnet ef database drop
|
|
113
|
+
dotnet ef database drop \
|
|
114
|
+
--context "$DBCONTEXT" \
|
|
115
|
+
--project "$INFRA_PROJECT" \
|
|
116
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
117
|
+
--force
|
|
88
118
|
```
|
|
89
119
|
|
|
120
|
+
> **Note :** Si "Les deux" sélectionné, exécuter pour CoreDbContext puis ExtensionsDbContext.
|
|
121
|
+
|
|
90
122
|
---
|
|
91
123
|
|
|
92
124
|
## STEP 4: Recreate + Apply
|
|
93
125
|
|
|
94
126
|
```bash
|
|
95
|
-
dotnet ef database update
|
|
127
|
+
dotnet ef database update \
|
|
128
|
+
--context "$DBCONTEXT" \
|
|
129
|
+
--project "$INFRA_PROJECT" \
|
|
130
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
131
|
+
--verbose
|
|
96
132
|
```
|
|
97
133
|
|
|
98
134
|
---
|
|
@@ -12,13 +12,18 @@ model: haiku
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
## STEP 1: Détecter Configuration
|
|
15
|
+
## STEP 1: Détecter Configuration et DbContext
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
detect_efcore_project
|
|
18
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
19
19
|
detect_environment
|
|
20
|
+
|
|
21
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
22
|
+
echo "Schema: $SCHEMA"
|
|
20
23
|
```
|
|
21
24
|
|
|
25
|
+
**Si DbContext non détecté :** Afficher le status des DEUX contextes.
|
|
26
|
+
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
## STEP 2: Invoquer MCP
|
|
@@ -26,7 +31,10 @@ detect_environment
|
|
|
26
31
|
```json
|
|
27
32
|
{
|
|
28
33
|
"tool": "mcp__smartstack__check_migrations",
|
|
29
|
-
"parameters": {
|
|
34
|
+
"parameters": {
|
|
35
|
+
"branch": "<current_branch>",
|
|
36
|
+
"projectPath": "<auto-detect>"
|
|
37
|
+
}
|
|
30
38
|
}
|
|
31
39
|
```
|
|
32
40
|
|
|
@@ -37,7 +45,10 @@ Extraire: `migrations[]`, `conflicts[]`
|
|
|
37
45
|
## STEP 3: Tester Connexion
|
|
38
46
|
|
|
39
47
|
```bash
|
|
40
|
-
CONNECTION_OK=$(dotnet ef database list
|
|
48
|
+
CONNECTION_OK=$(dotnet ef database list \
|
|
49
|
+
--context "$DBCONTEXT" \
|
|
50
|
+
--project "$INFRA_PROJECT" \
|
|
51
|
+
--startup-project "$STARTUP_PROJECT" 2>&1)
|
|
41
52
|
```
|
|
42
53
|
|
|
43
54
|
---
|
|
@@ -45,8 +56,15 @@ CONNECTION_OK=$(dotnet ef database list 2>&1)
|
|
|
45
56
|
## STEP 4: Compter Migrations
|
|
46
57
|
|
|
47
58
|
```bash
|
|
48
|
-
APPLIED=$(dotnet ef migrations list
|
|
49
|
-
|
|
59
|
+
APPLIED=$(dotnet ef migrations list \
|
|
60
|
+
--context "$DBCONTEXT" \
|
|
61
|
+
--project "$INFRA_PROJECT" \
|
|
62
|
+
--startup-project "$STARTUP_PROJECT" | grep -v "(Pending)" | wc -l)
|
|
63
|
+
|
|
64
|
+
PENDING=$(dotnet ef migrations list \
|
|
65
|
+
--context "$DBCONTEXT" \
|
|
66
|
+
--project "$INFRA_PROJECT" \
|
|
67
|
+
--startup-project "$STARTUP_PROJECT" | grep "(Pending)" | wc -l)
|
|
50
68
|
```
|
|
51
69
|
|
|
52
70
|
---
|
|
@@ -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:
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
74
|
-
|
|
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
|