@atlashub/smartstack-cli 4.74.0 → 4.76.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 +152 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +14 -3
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-reader.md +17 -15
- package/templates/agents/ba-writer.md +49 -51
- package/templates/skills/apex/SKILL.md +2 -2
- package/templates/skills/apex/_shared.md +1 -1
- package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
- package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
- package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
- package/templates/skills/apex/references/core-seed-data.md +20 -18
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/apex/references/post-checks.md +23 -3
- package/templates/skills/apex/references/smartstack-api.md +4 -4
- package/templates/skills/apex/references/smartstack-frontend.md +54 -8
- package/templates/skills/apex/references/smartstack-layers.md +6 -6
- package/templates/skills/apex/steps/step-00-init.md +75 -1
- package/templates/skills/apex/steps/step-03-execute.md +16 -4
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +65 -6
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +226 -4
- package/templates/skills/apex/steps/step-04-examine.md +163 -0
- package/templates/skills/apex-verify/SKILL.md +110 -0
- package/templates/skills/apex-verify/references/audit-rules.md +50 -0
- package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
- package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
- package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
- package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
- package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
- package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/application/templates-frontend.md +2 -2
- package/templates/skills/business-analyse/SKILL.md +17 -3
- package/templates/skills/business-analyse/_shared.md +64 -0
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
- package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
- package/templates/skills/business-analyse/questionnaire.md +86 -9
- package/templates/skills/business-analyse/references/03-json-schemas.md +221 -0
- package/templates/skills/business-analyse/references/03-post-check-validation.md +208 -0
- package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
- package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
- package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
- package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
- package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
- package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
- package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
- package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
- package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
- package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
- package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
- package/templates/skills/business-analyse/references/portal-classification.md +52 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
- package/templates/skills/business-analyse/references/validation-checklist.md +35 -6
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +50 -6
- package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
- package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
- package/templates/skills/business-analyse/steps/step-03-specify.md +810 -229
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +509 -278
- package/templates/skills/business-analyse-design/SKILL.md +10 -0
- package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
- package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
- package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
- package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
- package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
- package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
- package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
- package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
- package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
- package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
- package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
- package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
- package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +211 -0
- package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
- package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
- package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
- package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
- package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
- package/templates/skills/business-analyse-html/SKILL.md +10 -0
- package/templates/skills/business-analyse-html/html/ba-interactive.html +504 -97
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +79 -2
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +94 -36
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +162 -0
- package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
- package/templates/skills/business-analyse-html/html/src/template.html +2 -0
- package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +143 -0
- package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
- package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
- package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
- package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
- package/templates/skills/business-analyse-html/references/data-build.md +24 -1
- package/templates/skills/business-analyse-html/references/data-mapping.md +119 -17
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +18 -555
- package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
- package/templates/skills/business-analyse-quick/SKILL.md +807 -0
- package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
- package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
- package/templates/skills/business-analyse-review/SKILL.md +10 -0
- package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
- package/templates/skills/business-analyse-status/SKILL.md +8 -0
- package/templates/skills/dev-start/SKILL.md +143 -307
- package/templates/skills/efcore/SKILL.md +13 -0
- package/templates/skills/sketch/SKILL.md +15 -153
- package/templates/skills/ui-components/SKILL.md +1 -1
- package/templates/skills/ui-components/patterns/data-table.md +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Usage:** Structured questions for step-01-cadrage and step-03-specify
|
|
4
4
|
> **Standard:** BABOK v3 - Elicitation Techniques (Interactive analysis)
|
|
5
5
|
> **Model:** OPUS with ULTRATHINK
|
|
6
|
-
> **Total:** ~
|
|
6
|
+
> **Total:** ~15 targeted questions across 4 active questionnaire files
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -32,10 +32,55 @@
|
|
|
32
32
|
|
|
33
33
|
## Questionnaire Files (v2)
|
|
34
34
|
|
|
35
|
+
### Classification des questions
|
|
36
|
+
|
|
37
|
+
| Marqueur | Signification |
|
|
38
|
+
|----------|---------------|
|
|
39
|
+
| **OBLIGATOIRE** | DOIT etre posee dans tous les cas |
|
|
40
|
+
| **CONDITIONNEL** | Posee uniquement si la condition est remplie |
|
|
41
|
+
| **RELANCE** | Posee si la reponse precedente est vague |
|
|
42
|
+
|
|
43
|
+
#### Questionnaire 01 (cadrage)
|
|
44
|
+
- Q1.1 : OBLIGATOIRE
|
|
45
|
+
- Q1.4 : CONDITIONNEL (si problem_type = "replace" ou "automate" — pas pour systemes neufs)
|
|
46
|
+
- Q1.8 : OBLIGATOIRE
|
|
47
|
+
|
|
48
|
+
#### Questionnaire 02 (cadrage)
|
|
49
|
+
- Q2.1 : OBLIGATOIRE
|
|
50
|
+
- Q2.5 : OBLIGATOIRE
|
|
51
|
+
- Q2.9 : OBLIGATOIRE
|
|
52
|
+
- Q2.10 : OBLIGATOIRE
|
|
53
|
+
- Q2.11 : OBLIGATOIRE
|
|
54
|
+
- Q2.15 : OBLIGATOIRE
|
|
55
|
+
- Q2.19 : CONDITIONNEL (si brief mentionne un systeme externe ou integration)
|
|
56
|
+
- Q2.20 : CONDITIONNEL (si brief mentionne migration ou import de donnees)
|
|
57
|
+
|
|
58
|
+
> **Questions SUPPRIMEES (v3) :**
|
|
59
|
+
> - Q2.12 (lister features) : redondant — l'IA detecte les modules depuis le brief, la reformulation (phase 2) sert de validation
|
|
60
|
+
> - Q2.13 (classifier vital/important/optionnel) : inutile — SmartStack construit tous les modules, la classification ne change rien au code genere
|
|
61
|
+
> - Q2.16-Q2.18 (parcours, decisions, erreurs) : **deplaces vers step-03** — alimentent directement les use cases, evite la duplication
|
|
62
|
+
|
|
63
|
+
#### Questionnaire 03 (specification, par module)
|
|
64
|
+
- Q3.1 : OBLIGATOIRE
|
|
65
|
+
- Q3.2 : OBLIGATOIRE
|
|
66
|
+
- Q3.3 : OBLIGATOIRE
|
|
67
|
+
- Q3.5 : OBLIGATOIRE
|
|
68
|
+
- Q3.7 : OBLIGATOIRE
|
|
69
|
+
- Q3.8 : CONDITIONNEL (si entites avec relations temporelles)
|
|
70
|
+
- Q3.9 : OBLIGATOIRE
|
|
71
|
+
- Q3.10 : CONDITIONNEL (premier module uniquement, reutilise ensuite)
|
|
72
|
+
- Q3.11-Q3.13 : CONDITIONNEL (couvert par /business-analyse-design)
|
|
73
|
+
- Q3.14-Q3.16 : CONDITIONNEL (si dashboard mentionne dans cadrage)
|
|
74
|
+
- Q3.17 : OBLIGATOIRE
|
|
75
|
+
- Q3.19 : OBLIGATOIRE
|
|
76
|
+
- Q3.20 : OBLIGATOIRE
|
|
77
|
+
- Q3.21 : OBLIGATOIRE
|
|
78
|
+
- Q3.22 : CONDITIONNEL (si Q3.21 = oui)
|
|
79
|
+
|
|
35
80
|
| File | Questions | Phase | Focus |
|
|
36
81
|
|------|-----------|-------|-------|
|
|
37
|
-
| `questionnaire/01-context.md` | 3 | step-01-cadrage | Business process, friction points
|
|
38
|
-
| `questionnaire/02-stakeholders-scope.md` |
|
|
82
|
+
| `questionnaire/01-context.md` | 2-3 | step-01-cadrage | Business process, vision (+ friction points si remplacement) |
|
|
83
|
+
| `questionnaire/02-stakeholders-scope.md` | 6-8 | step-01-cadrage | User profiles, access levels, exclusions (+ integrations/import si pertinent) |
|
|
39
84
|
| `questionnaire/03-data-ui.md` | ~15 | step-03-specify (per module) | Data entities, UI expectations, dashboards |
|
|
40
85
|
| `questionnaire/04-risks-metrics.md` | — | NOT USED | Risks/metrics out of BA scope |
|
|
41
86
|
| `questionnaire/05-cross-module.md` | ~8 | step-03-specify (conditional) | Cross-module dependencies, integration impact |
|
|
@@ -51,13 +96,23 @@
|
|
|
51
96
|
| step-01-cadrage | 01-context, 02-stakeholders-scope |
|
|
52
97
|
| step-03-specify (par module) | 03-data-ui, conditionnellement 05-cross-module |
|
|
53
98
|
|
|
54
|
-
### Phase de cadrage (step-01)
|
|
99
|
+
### Phase de cadrage (step-01) — 3 batches
|
|
100
|
+
|
|
101
|
+
> **Principe vibe coding :** L'utilisateur decrit son besoin, l'IA deduit et propose. Les questions servent a CONFIRMER et APPROFONDIR, pas a interroger.
|
|
102
|
+
|
|
103
|
+
**Batch 1 — Contexte & Vision** (Q1.1, Q1.8, + Q1.4 si remplacement) :
|
|
104
|
+
- Processus metier, vision cible, frictions (si applicable)
|
|
55
105
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
106
|
+
**Batch 2 — Utilisateurs & Acces** (Q2.1, Q2.5, Q2.9-Q2.11) :
|
|
107
|
+
- Profils, taches, restrictions, droits, validations
|
|
108
|
+
|
|
109
|
+
**Batch 3 — Perimetre & Limites** (Q2.15, + Q2.19/Q2.20 si pertinent) :
|
|
110
|
+
- Exclusions, integrations (conditionnel), import (conditionnel)
|
|
111
|
+
|
|
112
|
+
**Regles :**
|
|
113
|
+
1. **Adapter :** Sauter les questions non pertinentes selon le contexte
|
|
114
|
+
2. **Approfondir :** Poser des questions de relance sur les reponses vagues
|
|
115
|
+
3. **Challenger :** Ne pas accepter "on verra plus tard" sur les fonctionnalites indispensables
|
|
61
116
|
|
|
62
117
|
### Phase de specification (step-03)
|
|
63
118
|
|
|
@@ -72,6 +127,28 @@ Pour chaque réponse vague, utiliser :
|
|
|
72
127
|
- "Que se passe-t-il si cette règle n'est pas respectée ?"
|
|
73
128
|
- "Qui est impacté par cette décision ?"
|
|
74
129
|
|
|
130
|
+
### Mode Auto-déduction (step-03)
|
|
131
|
+
|
|
132
|
+
> **Par défaut, step-03 utilise l'auto-déduction avec confirmation groupée.**
|
|
133
|
+
> L'IA propose entités, règles, UCs et permissions basées sur le cadrage + recherche domaine,
|
|
134
|
+
> puis demande une confirmation par lot au lieu de poser chaque question individuellement.
|
|
135
|
+
|
|
136
|
+
| Mode | Déclencheur | Comportement |
|
|
137
|
+
|------|------------|-------------|
|
|
138
|
+
| **Auto-déduction** (défaut) | Cadrage complet + domaine clair | Proposition → confirmation groupée → questions ciblées si ambigu |
|
|
139
|
+
| **Interactif** | Cadrage incomplet ou domaine inconnu | Questions individuelles Q3.1-Q3.22 |
|
|
140
|
+
|
|
141
|
+
**Workflow auto-déduction :**
|
|
142
|
+
1. L'IA construit la proposition à partir du cadrage + recherche domaine (A-bis)
|
|
143
|
+
2. Présente le LOT complet : "Voici ce que je propose. Corrections ?"
|
|
144
|
+
3. Le client valide, corrige ou demande des détails
|
|
145
|
+
4. Les questions détaillées ne sont posées QUE pour les points ambigus
|
|
146
|
+
|
|
147
|
+
**Traçabilité :** Le mode utilisé est tracé dans `config.json` : `specificationMode: "auto-deduction" | "interactive"`
|
|
148
|
+
|
|
149
|
+
> **IMPORTANT :** L'auto-déduction ne dispense PAS de la validation client.
|
|
150
|
+
> Chaque lot (entités, règles, UCs, permissions) DOIT être confirmé avant écriture.
|
|
151
|
+
|
|
75
152
|
### Filtre de pertinence
|
|
76
153
|
|
|
77
154
|
Chaque question conservée passe ce test :
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# JSON Schemas (step-03-specify)
|
|
2
|
+
|
|
3
|
+
## Entity Schema Format
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"name": "Employee",
|
|
8
|
+
"description": "Représente un employé de l'entreprise",
|
|
9
|
+
"personRoleConfig": { "variant": "mandatory", "userFields": ["firstName", "lastName", "email"] },
|
|
10
|
+
"attributes": [
|
|
11
|
+
{ "name": "code", "type": "string", "required": true, "unique": true, "searchable": true, "description": "Identifiant unique auto-généré" },
|
|
12
|
+
{ "name": "userId", "type": "string", "required": true, "unique": true, "description": "FK vers auth_Users (ASP.NET Identity — type string, NOT guid)" },
|
|
13
|
+
{ "name": "departmentId", "type": "guid", "required": true, "description": "Département d'affectation" },
|
|
14
|
+
{ "name": "hireDate", "type": "date", "required": true, "searchable": true, "description": "Date d'embauche" },
|
|
15
|
+
{ "name": "position", "type": "string", "searchable": true, "description": "Poste occupé" },
|
|
16
|
+
{ "name": "status", "type": "enum", "options": ["Active", "Inactive", "OnLeave", "Terminated"], "defaultValue": "Active", "searchable": true, "description": "Statut de l'employé" }
|
|
17
|
+
],
|
|
18
|
+
"versionedAttributes": [
|
|
19
|
+
{ "entity": "Salary", "attributes": ["grossAmount", "netAmount", "effectiveDate", "currency"], "reason": "Historique salarial versionné" }
|
|
20
|
+
],
|
|
21
|
+
"estimatedVolume": { "monthly": 50, "total2y": 1200 },
|
|
22
|
+
"searchableFields": ["code", "position", "status"],
|
|
23
|
+
"defaultFilters": ["status"],
|
|
24
|
+
"relationships": [
|
|
25
|
+
{ "target": "Department", "type": "ManyToOne", "description": "Appartient à un département" },
|
|
26
|
+
{ "target": "Contract", "type": "OneToMany", "description": "Possède plusieurs contrats" },
|
|
27
|
+
{ "target": "Salary", "type": "OneToMany", "description": "Historique de salaires versionnés" }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Attribute flags (OPTIONAL, default: false):**
|
|
33
|
+
- `unique: true` — attribute has uniqueness constraint (e.g., `code`, `userId`)
|
|
34
|
+
- `searchable: true` — attribute appears in search/filter results (e.g., `code`, `status`, `position`)
|
|
35
|
+
- `computed: true` — attribute value is calculated (e.g., `subtotal`, `total`). **MUST** have a corresponding `BR-CALC` rule with `formula` field
|
|
36
|
+
|
|
37
|
+
Omit flags when `false` (default). Include explicitly when `true`.
|
|
38
|
+
|
|
39
|
+
## Business Rules Schema Format
|
|
40
|
+
|
|
41
|
+
> **Source of truth:** `schemas/sections/analysis-schema.json` property `businessRules`.
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"id": "BR-VAL-EMPLOYEES-001",
|
|
46
|
+
"name": "Validation date embauche",
|
|
47
|
+
"category": "validation",
|
|
48
|
+
"sectionCode": "list",
|
|
49
|
+
"statement": "La date d'embauche ne peut pas être dans le futur",
|
|
50
|
+
"severity": "blocking",
|
|
51
|
+
"entities": ["Employee"],
|
|
52
|
+
"examples": [{ "input": "hireDate = 2027-01-01", "expected": "Erreur : date dans le futur" }],
|
|
53
|
+
"domainSpecific": false
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Categories: `validation`, `calculation`, `workflow`, `security`, `data`, `notification`
|
|
58
|
+
|
|
59
|
+
**Mandatory requirements:**
|
|
60
|
+
- Each enum attribute MUST have a `defaultValue`
|
|
61
|
+
- Each bounded numeric attribute MUST have `validation.min/max`
|
|
62
|
+
- FK attributes to Identity (userId) MUST use type `string` (ASP.NET Identity convention)
|
|
63
|
+
- Each attribute marked "computed" in entities.json MUST have a rule with `category: "calculation"` and `formula` field
|
|
64
|
+
|
|
65
|
+
**Calculation rule example:**
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"id": "BR-CALC-INV-003",
|
|
69
|
+
"name": "Calcul reste à payer",
|
|
70
|
+
"category": "calculation",
|
|
71
|
+
"sectionCode": "detail",
|
|
72
|
+
"statement": "Le reste à payer = total - montant payé",
|
|
73
|
+
"severity": "blocking",
|
|
74
|
+
"formula": "remainingAmount = total - paidAmount",
|
|
75
|
+
"entities": ["Invoice"],
|
|
76
|
+
"examples": [{ "input": "total=1000, paidAmount=300", "expected": "remainingAmount = 700" }],
|
|
77
|
+
"domainSpecific": false
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**MANDATORY enrichment fields (added in v2):**
|
|
82
|
+
- `severity` : `"blocking"` | `"warning"` | `"info"` — impact level of the rule
|
|
83
|
+
- `sectionCode` : section where this rule applies (e.g., `"list"`, `"approve"`)
|
|
84
|
+
- `examples[]` : structured as `{input: string, expected: string}` — at least 1 per rule
|
|
85
|
+
```json
|
|
86
|
+
"examples": [{ "input": "debut=15/03 fin=12/03", "expected": "Erreur : date de fin avant date de debut" }]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**RECOMMENDED enrichment fields:**
|
|
90
|
+
- `conditions[]` : structured IF conditions — `{entity, field, operator, value}`
|
|
91
|
+
```json
|
|
92
|
+
"conditions": [{ "entity": "Absence", "field": "duration", "operator": ">", "value": 3 }]
|
|
93
|
+
```
|
|
94
|
+
- `consequences[]` : side effects when rule fires — `{type, target, description}`
|
|
95
|
+
```json
|
|
96
|
+
"consequences": [{ "type": "notification", "target": "RH Manager", "description": "Certificat medical requis" }]
|
|
97
|
+
```
|
|
98
|
+
- `formula` : for BR-CALC rules (e.g., `"remaining = entitled + carried - taken"`)
|
|
99
|
+
- `domainSpecific` : `true` if from domain research, `false` if generic CRUD validation
|
|
100
|
+
|
|
101
|
+
## Use Cases Schema Format
|
|
102
|
+
|
|
103
|
+
**CANONICAL FORMAT (MANDATORY):** The usecases.json file MUST use these exact keys:
|
|
104
|
+
- Root key: `"useCases"` (camelCase, NOT "usecases")
|
|
105
|
+
- Actor field: `"primaryActor"` (NOT "actor")
|
|
106
|
+
- Steps field: `"mainScenario"` (string[], NOT "steps" with objects)
|
|
107
|
+
- Alternatives: `"alternativeScenarios"` (object[] with `{name, steps}`, NOT "alternative" as flat string)
|
|
108
|
+
- This matches specification-schema.json. Deviation causes normalization overhead in 4+ downstream skills.
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"useCases": [
|
|
113
|
+
{
|
|
114
|
+
"id": "UC-EMPLOYEES-001",
|
|
115
|
+
"name": "Créer un employé",
|
|
116
|
+
"sectionCode": "list",
|
|
117
|
+
"primaryActor": "Responsable RH",
|
|
118
|
+
"preconditions": ["L'utilisateur a la permission HumanResources.Employees.Create"],
|
|
119
|
+
"mainScenario": [
|
|
120
|
+
"L'utilisateur ouvre la page de création",
|
|
121
|
+
"Il remplit les champs obligatoires (nom, département, date embauche)",
|
|
122
|
+
"Il valide le formulaire",
|
|
123
|
+
"Le système vérifie les règles métier (BR-VAL-EMPLOYEES-001)",
|
|
124
|
+
"Le système crée l'employé et affiche la fiche"
|
|
125
|
+
],
|
|
126
|
+
"alternativeScenarios": [
|
|
127
|
+
{
|
|
128
|
+
"name": "Données invalides",
|
|
129
|
+
"steps": ["Le système affiche les erreurs de validation", "L'utilisateur corrige et re-soumet"]
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"businessRules": ["BR-VAL-EMPLOYEES-001"],
|
|
133
|
+
"result": "L'employé est créé avec le statut 'Actif'"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**MANDATORY enrichment fields (activated in v2):**
|
|
140
|
+
- `postconditions[]` : effects AFTER the UC completes (schema field exists, now mandatory)
|
|
141
|
+
```json
|
|
142
|
+
"postconditions": ["Absence.status = Approved", "AbsenceBalance.taken += duration", "Notification envoyee"]
|
|
143
|
+
```
|
|
144
|
+
- `errorScenarios[]` : error paths — MANDATORY for workflow UCs (schema field exists, now mandatory)
|
|
145
|
+
```json
|
|
146
|
+
"errorScenarios": [{ "name": "Solde insuffisant", "steps": ["Systeme affiche le solde restant", "Soumission bloquee"] }]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Minimum requirements:**
|
|
150
|
+
- Workflow UCs: `mainScenario[]` >= 5 steps, `errorScenarios[]` >= 1, `postconditions[]` required
|
|
151
|
+
- CRUD UCs: `mainScenario[]` >= 3 steps, `postconditions[]` required
|
|
152
|
+
|
|
153
|
+
## Permissions Schema Format
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"roles": ["RH Admin", "Manager", "Employee"],
|
|
158
|
+
"matrix": [
|
|
159
|
+
{ "role": "RH Admin", "permissions": ["Read", "Create", "Update", "Delete", "Export"] },
|
|
160
|
+
{ "role": "Manager", "permissions": ["Read", "Export"] },
|
|
161
|
+
{ "role": "Employee", "permissions": ["Read"] }
|
|
162
|
+
],
|
|
163
|
+
"permissionPaths": [
|
|
164
|
+
"HumanResources.Employees.Read",
|
|
165
|
+
"HumanResources.Employees.Create",
|
|
166
|
+
"HumanResources.Employees.Update",
|
|
167
|
+
"HumanResources.Employees.Delete",
|
|
168
|
+
"HumanResources.Employees.Export"
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Auto-detection rules:**
|
|
174
|
+
- If the cadrage mentions "export", "Excel", "CSV", or "télécharger" → automatically add `.export` permission and an export use case (UC-{PREFIX}-EXPORT)
|
|
175
|
+
- If the cadrage mentions "import", "importer", "upload" → automatically add `.import` permission and an import use case (UC-{PREFIX}-IMPORT)
|
|
176
|
+
|
|
177
|
+
## LifeCycle Schema Format
|
|
178
|
+
|
|
179
|
+
> Source: `specification-schema.json` `lifeCycles[]`
|
|
180
|
+
> **MANDATORY** for each entity with a status enum attribute.
|
|
181
|
+
> Generated in step-03 section F-bis. Consumed by Mermaid diagram generation (step-04) and code generation (handoff/develop).
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"entity": "EntityName",
|
|
186
|
+
"field": "status",
|
|
187
|
+
"initialState": "Draft",
|
|
188
|
+
"states": [
|
|
189
|
+
{
|
|
190
|
+
"id": "Draft",
|
|
191
|
+
"displayName": "Brouillon",
|
|
192
|
+
"color": "gray",
|
|
193
|
+
"allowedTransitions": ["Submitted"],
|
|
194
|
+
"isTerminal": false
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"transitions": [
|
|
198
|
+
{
|
|
199
|
+
"from": "Draft",
|
|
200
|
+
"to": "Submitted",
|
|
201
|
+
"action": "submit",
|
|
202
|
+
"permission": "App.Module.Action",
|
|
203
|
+
"guards": ["BR-VAL-XXX"],
|
|
204
|
+
"effects": [
|
|
205
|
+
{ "type": "notification", "target": "Manager", "template": "entity-submitted" },
|
|
206
|
+
{ "type": "field-update", "target": "Entity.field", "template": "= value" }
|
|
207
|
+
],
|
|
208
|
+
"confirm": false
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Generation rules:**
|
|
215
|
+
- Extract states from entity's status enum `options[]`
|
|
216
|
+
- Extract transitions from BR-WF-* rules
|
|
217
|
+
- Link `guards[]` to BR-VAL-* rules that must pass before transition
|
|
218
|
+
- Link `effects[]` to BR-NOTIF-* and BR-CALC-* triggered by the transition
|
|
219
|
+
- Link `permission` from permissions.json for each transition action
|
|
220
|
+
- Set `color` based on state semantic: gray=draft, blue=active, green=success, red=error, yellow=warning
|
|
221
|
+
- Set `isTerminal: true` for states with no allowed transitions
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# POST-CHECK Validation (step-03-specify)
|
|
2
|
+
|
|
3
|
+
Before advancing to step 04, run these validations for EACH module:
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
const errors = [];
|
|
7
|
+
const warnings = [];
|
|
8
|
+
|
|
9
|
+
for (const mod of modules) {
|
|
10
|
+
// mod.dir = resolveModuleDir(applicationCode, mod.code)
|
|
11
|
+
// e.g., docs/projet-rh/v1.0/human-resources/employees/
|
|
12
|
+
const ent = READ(mod.dir + '/entities.json')?.entities || [];
|
|
13
|
+
const ucs = READ(mod.dir + '/usecases.json')?.useCases || [];
|
|
14
|
+
const brs = READ(mod.dir + '/rules.json')?.rules || [];
|
|
15
|
+
const perms = READ(mod.dir + '/permissions.json');
|
|
16
|
+
const sections = mod.anticipatedSections || [];
|
|
17
|
+
const sectionCodes = new Set(sections.map(s => s.code));
|
|
18
|
+
|
|
19
|
+
// Mandatory checks (BLOCKING)
|
|
20
|
+
if (ent.length === 0) errors.push(mod.code + ": 0 entities");
|
|
21
|
+
if (ucs.length === 0) errors.push(mod.code + ": 0 use cases");
|
|
22
|
+
if (brs.length === 0) errors.push(mod.code + ": 0 business rules");
|
|
23
|
+
if (!perms?.permissionPaths?.length) errors.push(mod.code + ": no permissions");
|
|
24
|
+
|
|
25
|
+
// sectionCode validation
|
|
26
|
+
for (const uc of ucs) {
|
|
27
|
+
if (!uc.sectionCode) errors.push(mod.code + ": UC '" + uc.id + "' missing sectionCode");
|
|
28
|
+
else if (!sectionCodes.has(uc.sectionCode)) errors.push(mod.code + ": UC '" + uc.id + "' sectionCode '" + uc.sectionCode + "' not in anticipatedSections");
|
|
29
|
+
}
|
|
30
|
+
for (const br of brs) {
|
|
31
|
+
if (!br.sectionCode) errors.push(mod.code + ": BR '" + br.id + "' missing sectionCode");
|
|
32
|
+
else if (!sectionCodes.has(br.sectionCode)) errors.push(mod.code + ": BR '" + br.id + "' sectionCode '" + br.sectionCode + "' not in anticipatedSections");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Entity attribute checks
|
|
36
|
+
for (const e of ent) {
|
|
37
|
+
for (const a of (e.attributes || [])) {
|
|
38
|
+
if (!a.type) warnings.push(mod.code + ": entity " + e.name + " attr '" + a.name + "' missing type");
|
|
39
|
+
if (a.type === 'enum' && !a.defaultValue) errors.push(mod.code + ": enum attr '" + a.name + "' missing defaultValue");
|
|
40
|
+
// FK naming convention: must end with "Id"
|
|
41
|
+
if ((a.type === 'guid' || a.type === 'string') && a.foreignKey && !a.name.endsWith('Id'))
|
|
42
|
+
warnings.push(mod.code + ": entity " + e.name + " FK attr '" + a.name + "' should end with 'Id'");
|
|
43
|
+
}
|
|
44
|
+
// Person Extension Pattern check
|
|
45
|
+
const personFields = ['firstName', 'lastName', 'email', 'phoneNumber', 'phone'];
|
|
46
|
+
const foundPersonFields = (e.attributes || []).filter(a => personFields.includes(a.name));
|
|
47
|
+
if (foundPersonFields.length >= 3 && !e.personRoleConfig) {
|
|
48
|
+
errors.push(mod.code + ": entity '" + e.name + "' has " + foundPersonFields.length +
|
|
49
|
+
" person fields (" + foundPersonFields.map(f => f.name).join(", ") +
|
|
50
|
+
") but no personRoleConfig — use Person Extension Pattern (entity-architecture-decision.md section 0). " +
|
|
51
|
+
"Person fields (firstName, lastName, email) belong on auth_Users, not on the domain entity.");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Canonical usecases key check
|
|
56
|
+
const rawUCFile = READ(mod.dir + '/usecases.json');
|
|
57
|
+
if (rawUCFile && !rawUCFile.useCases && rawUCFile.usecases) {
|
|
58
|
+
errors.push(mod.code + ": usecases.json uses 'usecases' key instead of canonical 'useCases' — fix before proceeding");
|
|
59
|
+
}
|
|
60
|
+
// Check steps serialization format
|
|
61
|
+
for (const uc of ucs) {
|
|
62
|
+
if (uc.steps && Array.isArray(uc.steps) && uc.steps.length > 0 && typeof uc.steps[0] === 'object') {
|
|
63
|
+
errors.push(mod.code + ": UC '" + uc.id + "' uses steps[] with objects — must use mainScenario[] with strings");
|
|
64
|
+
}
|
|
65
|
+
if (uc.actor && !uc.primaryActor) {
|
|
66
|
+
warnings.push(mod.code + ": UC '" + uc.id + "' uses 'actor' instead of canonical 'primaryActor'");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Cross-reference checks
|
|
71
|
+
for (const uc of ucs) {
|
|
72
|
+
for (const brRef of (uc.businessRules || [])) {
|
|
73
|
+
if (!brs.find(br => br.id === brRef)) warnings.push(mod.code + ": UC '" + uc.id + "' references non-existent BR '" + brRef + "'");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Section permission checks
|
|
78
|
+
for (const section of sections) {
|
|
79
|
+
if (section.sectionType === 'view') {
|
|
80
|
+
const viewPerms = (perms?.permissionPaths || []).filter(p => p.includes('.' + section.code + '.'));
|
|
81
|
+
if (viewPerms.length > 0) errors.push(mod.code + ": view section '" + section.code + "' has " + viewPerms.length + " permissions (should inherit)");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Quality gate: UC count (C6 — BLOCKING if < 4, WARNING if < 6)
|
|
86
|
+
if (ucs.length > 0 && ucs.length < 4) {
|
|
87
|
+
errors.push(mod.code + ": only " + ucs.length + " use cases (minimum: 4)");
|
|
88
|
+
} else if (ucs.length > 0 && ucs.length < 6) {
|
|
89
|
+
warnings.push(mod.code + ": only " + ucs.length + " use cases (recommended: >= 6)");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Quality gate: Permission path count (C7 — WARNING if < 5)
|
|
93
|
+
const permPaths = perms?.permissionPaths || [];
|
|
94
|
+
if (permPaths.length > 0 && permPaths.length < 5) {
|
|
95
|
+
warnings.push(mod.code + ": only " + permPaths.length + " permission paths (recommended: >= 5 — check for missing Export/Import)");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Quality gate: Entity count (C9 — WARNING if single entity)
|
|
99
|
+
if (ent.length === 1) {
|
|
100
|
+
warnings.push(mod.code + ": single entity module — verify this is intentional (config/lookup OK)");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Quality gate: BR-CALC must have formula (C13 — BLOCKING)
|
|
104
|
+
for (const br of brs) {
|
|
105
|
+
if ((br.category === 'calculation' || (br.id && br.id.includes('CALC'))) && !br.formula) {
|
|
106
|
+
errors.push(mod.code + ": BR '" + br.id + "' is a calculation rule but missing 'formula' field");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Quality gate: Computed attributes must have BR-CALC (C11 — BLOCKING)
|
|
111
|
+
for (const e of ent) {
|
|
112
|
+
for (const a of (e.attributes || [])) {
|
|
113
|
+
if (a.computed === true) {
|
|
114
|
+
const hasBRCalc = brs.some(br =>
|
|
115
|
+
(br.category === 'calculation' || (br.id && br.id.includes('CALC'))) &&
|
|
116
|
+
(br.entities || []).includes(e.name)
|
|
117
|
+
);
|
|
118
|
+
if (!hasBRCalc) errors.push(mod.code + ": " + e.name + ".'" + a.name + "' is computed:true but no BR-CALC references " + e.name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Quality gate: Versioned attributes detection (C15 — WARNING)
|
|
124
|
+
for (const e of ent) {
|
|
125
|
+
for (const a of (e.attributes || [])) {
|
|
126
|
+
if (['salary', 'rate', 'grade', 'price', 'tarif'].some(k => a.name.toLowerCase().includes(k))) {
|
|
127
|
+
if (!e.versionedAttributes?.length)
|
|
128
|
+
warnings.push(mod.code + ": " + e.name + ".'" + a.name + "' may need versioning but no versionedAttributes defined");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ── Business Rules Schema Conformity (C16-C21) ──────────────────────
|
|
134
|
+
|
|
135
|
+
// Quality gate: BR schema field conformity (C16 — BLOCKING)
|
|
136
|
+
for (const br of brs) {
|
|
137
|
+
if (!br.id) errors.push(mod.code + ": BR missing 'id' field");
|
|
138
|
+
else if (!/^BR-(VAL|CALC|WF|SEC|DATA|NOTIF)-[A-Z]{2,4}-\d{3}$/.test(br.id))
|
|
139
|
+
errors.push(mod.code + ": BR '" + br.id + "' does not match ID pattern BR-{CAT}-{MOD}-{NNN}");
|
|
140
|
+
if (!br.name) errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'name'");
|
|
141
|
+
if (!br.category) errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'category'");
|
|
142
|
+
if (!br.statement) errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'statement'");
|
|
143
|
+
if (!br.severity) errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'severity'");
|
|
144
|
+
if (!br.entities || br.entities.length === 0)
|
|
145
|
+
errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'entities[]'");
|
|
146
|
+
// Reject deprecated field names (common drift from sub-agent schema ignorance)
|
|
147
|
+
if (br.code && !br.id) errors.push(mod.code + ": BR uses 'code' instead of canonical 'id'");
|
|
148
|
+
if (br.label && !br.name) errors.push(mod.code + ": BR uses 'label' instead of canonical 'name'");
|
|
149
|
+
if (br.description && !br.statement) errors.push(mod.code + ": BR uses 'description' instead of canonical 'statement'");
|
|
150
|
+
if (br.rule && !br.statement) errors.push(mod.code + ": BR uses 'rule' instead of canonical 'statement'");
|
|
151
|
+
if (br.type && !br.category) errors.push(mod.code + ": BR uses 'type' instead of canonical 'category'");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Quality gate: BR examples format (C17 — BLOCKING)
|
|
155
|
+
for (const br of brs) {
|
|
156
|
+
if (!br.examples || br.examples.length === 0)
|
|
157
|
+
errors.push(mod.code + ": BR '" + (br.id||'?') + "' missing 'examples[]' (min 1 required)");
|
|
158
|
+
if (br.example && !br.examples)
|
|
159
|
+
errors.push(mod.code + ": BR '" + (br.id||'?') + "' uses deprecated 'example' string — use 'examples[]' array of {input, expected}");
|
|
160
|
+
if (br.examples) {
|
|
161
|
+
for (const ex of br.examples) {
|
|
162
|
+
if (typeof ex === 'string')
|
|
163
|
+
errors.push(mod.code + ": BR '" + (br.id||'?') + "' has string in examples[] — must be {input, expected}");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Quality gate: BR count minimum (C18 — BLOCKING if < 4)
|
|
169
|
+
if (brs.length > 0 && brs.length < 4) {
|
|
170
|
+
errors.push(mod.code + ": only " + brs.length + " business rules (minimum: 4)");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Quality gate: Domain-specific ratio (C19 — WARNING if < 2)
|
|
174
|
+
const domainBRs = brs.filter(br => br.domainSpecific === true);
|
|
175
|
+
if (brs.length >= 4 && domainBRs.length < 2) {
|
|
176
|
+
warnings.push(mod.code + ": only " + domainBRs.length + " domain-specific rules out of " + brs.length +
|
|
177
|
+
" (minimum: 2 — see _shared.md rule 3)");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Quality gate: domainSpecific flag presence (C20 — WARNING)
|
|
181
|
+
const brsMissingFlag = brs.filter(br => typeof br.domainSpecific === 'undefined');
|
|
182
|
+
if (brsMissingFlag.length > 0) {
|
|
183
|
+
warnings.push(mod.code + ": " + brsMissingFlag.length + "/" + brs.length +
|
|
184
|
+
" BRs missing 'domainSpecific' flag");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Quality gate: Structured conditions for conditional rules (C21 — WARNING)
|
|
188
|
+
const conditionalBRs = brs.filter(br =>
|
|
189
|
+
br.category === 'workflow' || br.category === 'security' ||
|
|
190
|
+
(br.statement && /\b(IF|Si |si |Quand |quand |Lorsqu)/i.test(br.statement)));
|
|
191
|
+
const brsWithConditions = conditionalBRs.filter(br => br.conditions && br.conditions.length > 0);
|
|
192
|
+
if (conditionalBRs.length > 2 && brsWithConditions.length < 2) {
|
|
193
|
+
warnings.push(mod.code + ": " + brsWithConditions.length + "/" + conditionalBRs.length +
|
|
194
|
+
" conditional BRs have structured conditions[] (recommended: >= 2)");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (errors.length > 0) {
|
|
199
|
+
Display("POST-CHECK FAILED (" + errors.length + " errors):");
|
|
200
|
+
errors.forEach(e => Display(" ✗ " + e));
|
|
201
|
+
BLOCKING_ERROR("Fix all errors before advancing to step 04");
|
|
202
|
+
}
|
|
203
|
+
if (warnings.length > 0) {
|
|
204
|
+
Display("POST-CHECK warnings (" + warnings.length + "):");
|
|
205
|
+
warnings.forEach(w => Display(" ⚠ " + w));
|
|
206
|
+
}
|
|
207
|
+
Display("POST-CHECK PASS: " + modules.length + " modules validated");
|
|
208
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# SmartStack Entity Convention Guards (step-03-specify)
|
|
2
|
+
|
|
3
|
+
Before finalizing each entity, apply these rules:
|
|
4
|
+
|
|
5
|
+
## B-bis-1. Person Extension Pattern
|
|
6
|
+
|
|
7
|
+
(ref: `entity-architecture-decision.md` section 0)
|
|
8
|
+
|
|
9
|
+
IF the entity matches a person role (Employee, Customer, Manager, Consultant, etc.):
|
|
10
|
+
- **DO NOT** add firstName, lastName, email, phoneNumber as direct attributes
|
|
11
|
+
- **DO** add `userId` (type: `string`, FK to auth_Users — ASP.NET Identity uses string IDs)
|
|
12
|
+
- **DO** add `personRoleConfig` metadata with variant (mandatory/optional)
|
|
13
|
+
- Personal fields come from User, not from the domain entity
|
|
14
|
+
|
|
15
|
+
## B-bis-2. Versioned Sensitive Data
|
|
16
|
+
|
|
17
|
+
IF the entity has attributes that change over time with audit requirements (salary, rate, grade):
|
|
18
|
+
- **DO NOT** put them directly on the entity as single fields
|
|
19
|
+
- **DO** extract into a versioned satellite table (e.g., Employee → Salary with effectiveDate)
|
|
20
|
+
- Mark with `"versionedAttributes"` in entity spec
|
|
21
|
+
|
|
22
|
+
## B-bis-3. SmartStack Socle Entities (NEVER redefine)
|
|
23
|
+
|
|
24
|
+
- Users/Identity → `auth_Users` (managed by SmartStack Identity)
|
|
25
|
+
- Tenants → `tenant_Tenants` (managed by SmartStack Core)
|
|
26
|
+
- Departments → `ref_Departments` or `rh_Departments` (check if exists in target DB)
|
|
27
|
+
|
|
28
|
+
## B-bis-4. Foreign Key Conventions
|
|
29
|
+
|
|
30
|
+
- All FK attributes MUST end with `Id` suffix (e.g., `departmentId`, `userId`)
|
|
31
|
+
- FK to Identity users MUST use type `string` (ASP.NET Identity convention, NOT guid)
|
|
32
|
+
- FK to domain entities MUST use type `guid`
|