@atlashub/smartstack-cli 4.75.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.
Files changed (54) hide show
  1. package/dist/index.js +87 -41
  2. package/dist/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/skills/apex/SKILL.md +2 -2
  5. package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
  6. package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
  7. package/templates/skills/apex/references/core-seed-data.md +20 -18
  8. package/templates/skills/apex/references/post-checks.md +18 -1
  9. package/templates/skills/apex/references/smartstack-api.md +4 -4
  10. package/templates/skills/apex/references/smartstack-frontend.md +1 -1
  11. package/templates/skills/apex/references/smartstack-layers.md +6 -6
  12. package/templates/skills/apex/steps/step-00-init.md +1 -1
  13. package/templates/skills/apex/steps/step-03b-layer1-seed.md +26 -0
  14. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +124 -2
  15. package/templates/skills/apex/steps/step-04-examine.md +163 -0
  16. package/templates/skills/apex-verify/SKILL.md +110 -0
  17. package/templates/skills/apex-verify/references/audit-rules.md +50 -0
  18. package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
  19. package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
  20. package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
  21. package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
  22. package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
  23. package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
  24. package/templates/skills/application/templates-frontend.md +2 -2
  25. package/templates/skills/business-analyse/SKILL.md +3 -3
  26. package/templates/skills/business-analyse/_shared.md +37 -0
  27. package/templates/skills/business-analyse/references/03-json-schemas.md +11 -3
  28. package/templates/skills/business-analyse/references/03-post-check-validation.md +64 -0
  29. package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
  30. package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
  31. package/templates/skills/business-analyse/references/validation-checklist.md +5 -5
  32. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +15 -4
  33. package/templates/skills/business-analyse/steps/step-03-specify.md +162 -4
  34. package/templates/skills/business-analyse/steps/step-04-consolidate.md +211 -1
  35. package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +3 -0
  36. package/templates/skills/business-analyse-html/html/ba-interactive.html +198 -16
  37. package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +64 -0
  38. package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
  39. package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
  40. package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +6 -3
  41. package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +46 -0
  42. package/templates/skills/business-analyse-html/references/02-feature-data-building.md +4 -2
  43. package/templates/skills/business-analyse-html/references/data-build.md +2 -0
  44. package/templates/skills/business-analyse-html/references/data-mapping.md +88 -21
  45. package/templates/skills/business-analyse-html/steps/step-02-build-data.md +6 -0
  46. package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
  47. package/templates/skills/business-analyse-quick/SKILL.md +807 -0
  48. package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
  49. package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
  50. package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
  51. package/templates/skills/dev-start/SKILL.md +7 -7
  52. package/templates/skills/sketch/SKILL.md +15 -153
  53. package/templates/skills/ui-components/SKILL.md +1 -1
  54. package/templates/skills/ui-components/patterns/data-table.md +1 -1
@@ -168,6 +168,168 @@ for (const providerFile of providerFiles) {
168
168
 
169
169
  ---
170
170
 
171
+ ## 6d. PRD Compliance Verification (delegate mode only)
172
+
173
+ > **Run ONLY when `delegate_mode` is true AND companion spec files exist.**
174
+ > This checks that generated code matches PRD specifications — not just technical quality.
175
+ > The PRD companion files are the AUTHORITATIVE source for columns, actions, labels, and permissions.
176
+
177
+ ```javascript
178
+ if (delegate_mode) {
179
+ const specsDir = path.dirname(delegate_prd_path);
180
+ const prd = readJSON(delegate_prd_path);
181
+
182
+ const screensPath = path.join(specsDir, prd.specificationFiles?.screens);
183
+ const permsPath = path.join(specsDir, prd.specificationFiles?.permissions);
184
+ const screens = fileExists(screensPath) ? readJSON(screensPath) : null;
185
+ const perms = fileExists(permsPath) ? readJSON(permsPath) : null;
186
+
187
+ if (screens) {
188
+ // ──── PC-1 (BLOCKING): Column Completeness ────
189
+ // Every column defined in screens.json SmartTable resources MUST exist in the generated ListPage.
190
+ for (const section of screens.sections) {
191
+ for (const resource of (section.resources || [])) {
192
+ if (resource.type !== 'SmartTable' || !resource.columns) continue;
193
+ const entityName = resource.entity;
194
+ // Find the corresponding ListPage
195
+ const listPages = Glob(`src/pages/**/${entityName}*ListPage.tsx`);
196
+ if (listPages.length === 0) {
197
+ BLOCKING(`PC-1: No ListPage found for entity ${entityName} (section: ${section.code})`);
198
+ continue;
199
+ }
200
+ const pageContent = readFile(listPages[0]);
201
+ const missingCols = [];
202
+ for (const col of resource.columns) {
203
+ // Check for the column field name in the page content
204
+ if (!pageContent.includes(col.field)) {
205
+ missingCols.push(`${col.field} (${col.format})`);
206
+ }
207
+ }
208
+ if (missingCols.length > 0) {
209
+ BLOCKING(`PC-1: ${listPages[0]} missing ${missingCols.length}/${resource.columns.length} columns: ${missingCols.join(', ')}. ` +
210
+ `Fix: re-invoke Skill("ui-components") with the PRD SPECIFICATION block containing ALL columns.`);
211
+ }
212
+ }
213
+ }
214
+
215
+ // ──── PC-2 (BLOCKING): Action Button Completeness ────
216
+ // Actions defined in screens.json MUST have corresponding handlers in the generated pages.
217
+ for (const section of screens.sections) {
218
+ for (const resource of (section.resources || [])) {
219
+ if (!resource.actions || resource.actions.length === 0) continue;
220
+ const entityName = resource.entity;
221
+ const pages = Glob(`src/pages/**/${entityName}*Page.tsx`);
222
+ const allContent = pages.map(p => readFile(p)).join('\n');
223
+
224
+ for (const action of resource.actions) {
225
+ let found = false;
226
+ switch (action) {
227
+ case 'create': found = allContent.includes('navigate') && allContent.includes('create'); break;
228
+ case 'edit': found = allContent.includes('edit') || allContent.includes('Edit'); break;
229
+ case 'delete': found = allContent.includes('delete') || allContent.includes('Delete'); break;
230
+ case 'approve': found = allContent.includes('approve') || allContent.includes('Approve'); break;
231
+ case 'reject': found = allContent.includes('reject') || allContent.includes('Reject'); break;
232
+ case 'export': found = allContent.includes('export') || allContent.includes('Export'); break;
233
+ default: found = allContent.toLowerCase().includes(action.toLowerCase());
234
+ }
235
+ if (!found) {
236
+ BLOCKING(`PC-2: ${entityName} pages missing action handler for '${action}' (section: ${section.code}). ` +
237
+ `Fix: add ${action} button/handler to the relevant page.`);
238
+ }
239
+ }
240
+ }
241
+ }
242
+
243
+ // ──── PC-3 (WARNING): I18n Label Accent Accuracy ────
244
+ // French/German/Italian labels MUST have proper UTF-8 accents.
245
+ const ACCENT_PATTERNS_FR = {
246
+ 'Employes': 'Employés', 'Departement': 'Département', 'Departements': 'Départements',
247
+ 'Prenom': 'Prénom', 'Numero': 'Numéro', 'Societe': 'Société',
248
+ 'Categorie': 'Catégorie', 'Securite': 'Sécurité', 'Conge': 'Congé', 'Conges': 'Congés',
249
+ 'Generalites': 'Généralités', 'Resume': 'Résumé', 'Echeance': 'Échéance'
250
+ };
251
+ const i18nFiles = Glob(`src/**/i18n/locales/fr/*.json`);
252
+ for (const file of i18nFiles) {
253
+ const content = readFile(file);
254
+ for (const [ascii, accented] of Object.entries(ACCENT_PATTERNS_FR)) {
255
+ if (content.includes(`"${ascii}"`) || content.includes(`"${ascii} `)) {
256
+ WARNING(`PC-3: ${file} contains ASCII-only '${ascii}' — should be '${accented}'. Fix the accent.`);
257
+ }
258
+ }
259
+ }
260
+
261
+ // ──── PC-5 (WARNING): Section Page Completeness ────
262
+ // Every primary/functional section in screens.json should have a corresponding page.
263
+ for (const section of screens.sections) {
264
+ if (!['primary', 'functional'].includes(section.sectionType)) continue;
265
+ const sectionCode = section.code;
266
+ const resources = section.resources || [];
267
+ const entityNames = resources.map(r => r.entity).filter(Boolean);
268
+
269
+ // Check if any page exists for this section's entities
270
+ let pageFound = false;
271
+ for (const entity of entityNames) {
272
+ const pages = Glob(`src/pages/**/${entity}*Page.tsx`);
273
+ if (pages.length > 0) { pageFound = true; break; }
274
+ }
275
+ // Also check by section code (e.g., CalendarPage, ApprovePage)
276
+ if (!pageFound) {
277
+ const sectionPages = Glob(`src/pages/**/*${sectionCode}*Page.tsx`);
278
+ pageFound = sectionPages.length > 0;
279
+ }
280
+ if (!pageFound) {
281
+ WARNING(`PC-5: Section '${sectionCode}' (${section.sectionType}) defined in screens.json ` +
282
+ `but no corresponding page found. Consider generating it.`);
283
+ }
284
+ }
285
+ }
286
+
287
+ if (perms) {
288
+ // ──── PC-4 (BLOCKING): Permission Seed Data Completeness ────
289
+ // All permissionPaths from permissions.json MUST be seeded in PermissionsSeedData.
290
+ const permSeedFiles = Glob(`**/PermissionsSeedData.cs`);
291
+ const permClassFiles = Glob(`**/Permissions.cs`);
292
+ const allPermContent = [...permSeedFiles, ...permClassFiles].map(f => readFile(f)).join('\n');
293
+
294
+ for (const path of perms.permissionPaths) {
295
+ // Check for the permission path (may be stored as kebab-case or segments)
296
+ const segments = path.split('.');
297
+ const lastSegment = segments[segments.length - 1].toLowerCase();
298
+ if (!allPermContent.toLowerCase().includes(lastSegment)) {
299
+ BLOCKING(`PC-4: Permission path '${path}' not found in seed data. ` +
300
+ `Fix: add to PermissionsSeedData.cs and Permissions.cs constants.`);
301
+ }
302
+ }
303
+
304
+ // Verify roles from permissions.json exist in RolesSeedData
305
+ const roleSeedFiles = Glob(`**/RolesSeedData.cs`);
306
+ const allRoleContent = roleSeedFiles.map(f => readFile(f)).join('\n');
307
+ for (const role of perms.roles) {
308
+ if (!allRoleContent.includes(role.role)) {
309
+ WARNING(`PC-4b: Role '${role.role}' from permissions.json not found in RolesSeedData.cs.`);
310
+ }
311
+ }
312
+ }
313
+
314
+ // ──── PC-6 (WARNING): I18n Namespace Registration ────
315
+ // This overlaps with GATE PG-4 but cross-checks against screens.json sections.
316
+ const i18nConfig = Glob(`src/**/i18n/config.ts`)[0] || Glob(`src/**/i18n/index.ts`)[0];
317
+ if (i18nConfig && screens) {
318
+ const configContent = readFile(i18nConfig);
319
+ const moduleCode = prd.project?.module;
320
+ if (moduleCode && !configContent.includes(moduleCode)) {
321
+ WARNING(`PC-6: Module namespace '${moduleCode}' not registered in ${i18nConfig}. ` +
322
+ `Translation keys will render as raw strings.`);
323
+ }
324
+ }
325
+ }
326
+ ```
327
+
328
+ > **If ANY BLOCKING check fails:** Return to step-03d to fix the specific issue, then re-run section 6d.
329
+ > BLOCKING failures indicate the generated code does NOT match the PRD specification.
330
+
331
+ ---
332
+
171
333
  ## 7. Acceptance Criteria POST-CHECK
172
334
 
173
335
  For each AC from step-01:
@@ -210,6 +372,7 @@ AC1: {criterion} → PASS / FAIL (evidence)
210
372
  | Navigation translations (4 langs) | PASS / N/A |
211
373
  | Inline tests | PASS / N/A |
212
374
  | POST-CHECKs | PASS / N/A |
375
+ | PRD Compliance (delegate) | PASS / N/A |
213
376
  | Acceptance criteria | {X}/{Y} PASS |
214
377
 
215
378
  ---
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: apex-verify
3
+ description: |
4
+ Audit a generated SmartStack APEX application for common generation issues.
5
+ Use this skill when:
6
+ - Verifying a generated app has no missing CRUD pages or buttons
7
+ - Checking navigation seed data for reserved section codes in menu
8
+ - Auditing permission coverage (controllers vs Permissions.cs vs seed data)
9
+ - Validating route alignment (frontend vs backend vs seed)
10
+ - After /apex or /business-analyse-develop completes
11
+ argument-hint: "[--scope=all|nav|crud|perm|route] [--fix]"
12
+ model: sonnet
13
+ allowed-tools: "Read, Grep, Glob, Bash, ToolSearch"
14
+ entry_point: steps/step-00-init.md
15
+ ---
16
+
17
+ <objective>
18
+ Audit a SmartStack application generated by /apex or /business-analyse-develop for common post-generation issues:
19
+
20
+ 1. **Navigation** — Reserved section codes (detail, create, edit) seeded as visible menu items
21
+ 2. **CRUD** — Missing page types, missing "New" buttons on list pages, incomplete componentRegistry
22
+ 3. **Permissions** — Cross-reference controllers, Permissions.cs, PermissionsSeedData, RolesSeedData
23
+ 4. **Routes** — Alignment between seed data routes, PageRegistry keys, and controller NavRoutes
24
+
25
+ The audit is **read-only** by default. Use `--fix` to display actionable fix commands.
26
+ </objective>
27
+
28
+ <quick_start>
29
+
30
+ ```bash
31
+ /apex-verify # Full audit (all 4 categories)
32
+ /apex-verify --scope=nav # Navigation menu audit only
33
+ /apex-verify --scope=crud # CRUD completeness audit only
34
+ /apex-verify --scope=perm # Permission cross-reference only
35
+ /apex-verify --scope=route # Route alignment only
36
+ /apex-verify --fix # Full audit + fix suggestions
37
+ ```
38
+
39
+ </quick_start>
40
+
41
+ <parameters>
42
+
43
+ <flags>
44
+ | Flag | Description |
45
+ |------|-------------|
46
+ | `--scope=all` | Audit all 4 categories (default) |
47
+ | `--scope=nav` | Navigation audit only (reserved section codes) |
48
+ | `--scope=crud` | CRUD completeness only (pages, buttons, registry) |
49
+ | `--scope=perm` | Permission cross-reference only |
50
+ | `--scope=route` | Route alignment only |
51
+ | `--fix` | Display actionable fix commands for each finding |
52
+ </flags>
53
+ </parameters>
54
+
55
+ <workflow>
56
+ 1. **Initialize** — Detect project structure, locate seed data, controllers, pages
57
+ 2. **Navigation Audit** — Check for reserved section codes seeded as menu items
58
+ 3. **CRUD Audit** — Verify 4 page types per section, create buttons, componentRegistry
59
+ 4. **Permission Audit** — Cross-reference controllers, Permissions.cs, seed data, roles
60
+ 5. **Route Audit** — Verify frontend/backend/seed alignment
61
+ 6. **Report** — Consolidated findings with severity and fix suggestions
62
+ </workflow>
63
+
64
+ <state_variables>
65
+ | Variable | Type | Description |
66
+ |----------|------|-------------|
67
+ | `{scope}` | string | all, nav, crud, perm, route |
68
+ | `{fix_mode}` | boolean | Display fix commands |
69
+ | `{api_root}` | string | Path to backend src/ |
70
+ | `{web_root}` | string | Path to frontend web/ |
71
+ | `{seed_files}` | string[] | All *NavigationSeedData.cs files |
72
+ | `{controller_files}` | string[] | All *Controller.cs files |
73
+ | `{page_files}` | string[] | All *.tsx page files |
74
+ | `{registry_file}` | string | componentRegistry.generated.ts path |
75
+ | `{permissions_file}` | string | Permissions.cs path |
76
+ | `{findings}` | object[] | All findings with ID, severity, message, fix |
77
+ </state_variables>
78
+
79
+ <entry_point>
80
+
81
+ **FIRST ACTION:** Load `steps/step-00-init.md`
82
+
83
+ </entry_point>
84
+
85
+ <step_files>
86
+ | Step | File | Purpose |
87
+ |------|------|---------|
88
+ | 00 | `steps/step-00-init.md` | Parse flags, detect project structure, resolve paths |
89
+ | 01 | `steps/step-01-nav-audit.md` | Audit navigation seed data for reserved section codes |
90
+ | 02 | `steps/step-02-crud-audit.md` | Audit CRUD completeness (pages, buttons, registry) |
91
+ | 03 | `steps/step-03-perm-audit.md` | Audit permissions cross-reference |
92
+ | 04 | `steps/step-04-route-audit.md` | Audit route alignment |
93
+ | 05 | `steps/step-05-report.md` | Generate consolidated report |
94
+ </step_files>
95
+
96
+ <execution_rules>
97
+ - **Read-only** — This skill NEVER modifies code (unless --fix is used, and even then only displays commands)
98
+ - **Evidence-based** — Every finding must reference a specific file:line
99
+ - **Comprehensive** — Check ALL files, not a sample
100
+ - **Actionable** — Every finding must include a fix suggestion
101
+ - **Scoped** — Only run audits matching {scope}
102
+ - **SmartStack-aware** — Respect SmartStack conventions (PageRegistry, DynamicRouter, NavRoute, SeedData patterns)
103
+ </execution_rules>
104
+
105
+ <success_criteria>
106
+ - All applicable audits completed with zero false positives
107
+ - Each finding has: ID, severity (BLOCKING/CRITICAL/WARNING), file:line, description, fix
108
+ - Consolidated report with category totals
109
+ - Executive summary with pass/fail per category
110
+ </success_criteria>
@@ -0,0 +1,50 @@
1
+ # Audit Rules Reference
2
+
3
+ > Complete codification of all audit rules used by /apex-verify.
4
+ > Each rule has a unique ID, severity, description, detection method, and fix pattern.
5
+
6
+ ---
7
+
8
+ ## Navigation Rules (NAV-xxx)
9
+
10
+ | ID | Severity | Description | Detection | Fix |
11
+ |----|----------|-------------|-----------|-----|
12
+ | NAV-001 | BLOCKING | Reserved section code (detail/create/edit) seeded as visible menu item | Grep NavigationSeedData for `Code = "detail"` / `"create"` / `"edit"` without `IsActive = false` | Remove section from seed data, or set `IsActive = false` |
13
+ | NAV-002 | BLOCKING | Section code contains "-detail" seeded as menu item | Grep for codes matching `*-detail` pattern | Remove section entry — detail is resolved as /:id under parent section |
14
+ | NAV-003 | BLOCKING | Route contains forbidden segment (/detail/, /create/, /edit/) | Grep seed data routes for `/detail/`, `/create/`, `/edit/` segments | Use convention routes: /:id, /create, /:id/edit (no explicit segments) |
15
+ | NAV-004 | WARNING | Reserved section code with IsActive = false | Code is reserved but hidden from menu | Acceptable — remove if unnecessary |
16
+ | NAV-005 | WARNING | Section code not in kebab-case | Regex check: `^[a-z][a-z0-9]*(-[a-z0-9]+)*$` | Rename to kebab-case |
17
+
18
+ ## CRUD Rules (CRUD-xxx)
19
+
20
+ | ID | Severity | Description | Detection | Fix |
21
+ |----|----------|-------------|-----------|-----|
22
+ | CRUD-001 | BLOCKING | ListPage missing for entity | Glob for `*ListPage.tsx` matching entity | Generate via `/ui-components` |
23
+ | CRUD-002 | BLOCKING | DetailPage missing for entity | Glob for `*DetailPage.tsx` matching entity | Generate via `/ui-components` |
24
+ | CRUD-003 | BLOCKING | Create/Edit page missing for entity | Glob for `*CreatePage.tsx`, `*EditPage.tsx`, `*FormPage.tsx` | Generate via `/ui-components` |
25
+ | CRUD-004 | BLOCKING | ListPage has no Create/New button | Grep for `navigate.*create` or `Link.*create` | Add navigate('create') button in page header |
26
+ | CRUD-005 | BLOCKING | Page exists but not registered in componentRegistry | Read registry, check for matching key | Add `PageRegistry.register()` call or run `scaffold_routes` |
27
+ | CRUD-006 | WARNING | Registry entry has no matching page file | Read registry, check file existence | Remove orphan registry entry or create the page |
28
+ | CRUD-007 | WARNING | Form page has no submit handler | Grep for `onSubmit`, `handleSubmit`, `api.create`, `api.post` | Implement form submission logic |
29
+
30
+ ## Permission Rules (PERM-xxx)
31
+
32
+ | ID | Severity | Description | Detection | Fix |
33
+ |----|----------|-------------|-----------|-----|
34
+ | PERM-001 | BLOCKING | Controller uses permission not defined in Permissions.cs | Cross-ref `[RequirePermission]` vs `Permissions.cs` | Add missing constant to Permissions.cs |
35
+ | PERM-002 | BLOCKING | Permissions.cs constant not seeded in PermissionsSeedData | Cross-ref Permissions.cs paths vs seed data | Add `HasData()` entry in PermissionsSeedData |
36
+ | PERM-003 | CRITICAL | Seeded permission has no role mapping | Cross-ref seed data vs RolesSeedData | Add role-permission mapping in RolesSeedData |
37
+ | PERM-004 | CRITICAL | Admin role missing wildcard for module | Check admin role has `*.module.*` wildcard | Add wildcard permission for admin role |
38
+ | PERM-005 | WARNING | Permission path segments not in kebab-case | Regex check on permission paths | Rename to kebab-case |
39
+ | PERM-006 | WARNING | Viewer role has write permission | Check viewer role permissions | Remove write permissions from viewer role |
40
+ | PERM-007 | WARNING | Permission defined but unused by any controller | Cross-ref Permissions.cs vs controllers | Remove dead permission or add controller usage |
41
+
42
+ ## Route Rules (ROUTE-xxx)
43
+
44
+ | ID | Severity | Description | Detection | Fix |
45
+ |----|----------|-------------|-----------|-----|
46
+ | ROUTE-001 | BLOCKING | Seed data route has no matching PageRegistry entry | Cross-ref seed routes vs registry keys | Add PageRegistry.register() or run scaffold_routes |
47
+ | ROUTE-002 | WARNING | Controller NavRoute has no matching seed data entry | Cross-ref NavRoute attrs vs seed routes | Add navigation seed data entry |
48
+ | ROUTE-003 | BLOCKING | PageRegistry references non-existent page file | Read registry imports, check file existence | Create page or fix import path |
49
+ | ROUTE-004 | WARNING | Orphan page — exists on disk but not registered | Cross-ref page files vs registry | Register page or delete orphan |
50
+ | ROUTE-005 | WARNING | Implicit route (detail/create/edit) not resolvable | Check registry + DynamicRouter conventions | Register in componentRegistry |
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: step-00-init
3
+ description: Parse flags, detect project structure, resolve paths for APEX verification
4
+ next_step: steps/step-01-nav-audit.md
5
+ ---
6
+
7
+ # Step 0: Initialization
8
+
9
+ ## MANDATORY EXECUTION RULES:
10
+ - NEVER skip project detection
11
+ - ALWAYS resolve actual filesystem paths before proceeding
12
+ - YOU ARE AN INITIALIZER, not a scanner
13
+
14
+ ## YOUR TASK:
15
+ Parse the flags, detect the SmartStack project structure, and locate all files needed for auditing.
16
+
17
+ ---
18
+
19
+ ## EXECUTION SEQUENCE:
20
+
21
+ ### 1. Parse Input
22
+
23
+ ```
24
+ Arguments from $ARGUMENTS:
25
+ --scope=nav -> {scope} = "nav"
26
+ --scope=crud -> {scope} = "crud"
27
+ --scope=perm -> {scope} = "perm"
28
+ --scope=route -> {scope} = "route"
29
+ --scope=all -> {scope} = "all" (default)
30
+ --fix -> {fix_mode} = true (default: false)
31
+
32
+ No arguments -> {scope} = "all", {fix_mode} = false
33
+ ```
34
+
35
+ ### 2. Detect Project Structure
36
+
37
+ Use Glob to locate all required files:
38
+
39
+ ```
40
+ Backend paths:
41
+ {api_root} = src/*/Api/ or src/*.Api/
42
+ Verify: *.sln exists at project root
43
+
44
+ Frontend paths:
45
+ {web_root} = web/*/src/ or web/*-web/src/
46
+ Verify: package.json exists in web/*/
47
+
48
+ Key files to locate:
49
+ {seed_files}:
50
+ Glob "**/Seeding/Data/**/*NavigationSeedData.cs"
51
+ Glob "**/Seeding/Data/**/*NavigationModuleSeedData.cs"
52
+
53
+ {controller_files}:
54
+ Glob "**/Controllers/**/*Controller.cs"
55
+
56
+ {page_files}:
57
+ Glob "web/**/src/pages/**/*Page.tsx"
58
+
59
+ {registry_file}:
60
+ Glob "**/componentRegistry.generated.ts" or "**/componentRegistry*.ts"
61
+
62
+ {permissions_file}:
63
+ Glob "**/Authorization/Permissions.cs" or "**/Common/Authorization/Permissions.cs"
64
+
65
+ {perm_seed_files}:
66
+ Glob "**/Seeding/Data/**/*PermissionsSeedData.cs"
67
+ Glob "**/Seeding/Data/**/*SeedDataProvider.cs"
68
+
69
+ {role_seed_files}:
70
+ Glob "**/Seeding/Data/**/*RolesSeedData.cs"
71
+ ```
72
+
73
+ ### 3. Validate Paths
74
+
75
+ For each required file set:
76
+ - If empty: record as CRITICAL warning (cannot audit that category)
77
+ - If found: record paths for next steps
78
+
79
+ ### 4. Show Summary and Proceed
80
+
81
+ Display:
82
+
83
+ ```
84
+ APEX Verification — Initialization
85
+ ====================================
86
+
87
+ | Setting | Value |
88
+ |---------|-------|
89
+ | Scope | {scope} |
90
+ | Fix mode | {fix_mode} |
91
+
92
+ Project Structure:
93
+ | Category | Files Found |
94
+ |----------|-------------|
95
+ | Navigation seed data | {count} files |
96
+ | Controllers | {count} files |
97
+ | Frontend pages | {count} files |
98
+ | Component registry | {found/MISSING} |
99
+ | Permissions.cs | {found/MISSING} |
100
+ | Permission seed data | {count} files |
101
+ | Role seed data | {count} files |
102
+
103
+ -> Proceeding to audits...
104
+ ```
105
+
106
+ ---
107
+
108
+ ## SUCCESS METRICS:
109
+ - Scope and flags correctly parsed
110
+ - All filesystem paths resolved and validated
111
+ - Summary displayed with file counts
112
+ - Ready for audit steps
113
+
114
+ ## NEXT STEP:
115
+ Based on {scope}:
116
+ - `all` or `nav` → proceed to `./step-01-nav-audit.md`
117
+ - `crud` → skip to `./step-02-crud-audit.md`
118
+ - `perm` → skip to `./step-03-perm-audit.md`
119
+ - `route` → skip to `./step-04-route-audit.md`
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: step-01-nav-audit
3
+ description: Audit navigation seed data for reserved section codes appearing as menu items
4
+ next_step: steps/step-02-crud-audit.md
5
+ ---
6
+
7
+ # Step 1: Navigation Audit
8
+
9
+ ## YOUR TASK:
10
+ Scan all navigation seed data files for sections with reserved codes that should NOT appear as sidebar menu items.
11
+
12
+ ## RESERVED SECTION CODES:
13
+ ```
14
+ RESERVED = ["detail", "create", "edit"]
15
+ ```
16
+ These are internal route targets (/:id, /create, /:id/edit), NOT sidebar menu items.
17
+ Any section with one of these codes — or containing "detail" (e.g., "department-detail") — must NOT be a visible menu entry.
18
+
19
+ ---
20
+
21
+ ## EXECUTION SEQUENCE:
22
+
23
+ ### 1. Scan Navigation Seed Data
24
+
25
+ For each file in {seed_files}:
26
+
27
+ **1a. Extract all section entries**
28
+
29
+ Use Grep to find section definitions. Two patterns to check:
30
+
31
+ Pattern A — SectionData record array:
32
+ ```csharp
33
+ new("detail", "/path/:id", "icon", 4, (...))
34
+ ```
35
+ → Grep for `new\s*\("([^"]+)"` in SectionData arrays
36
+
37
+ Pattern B — NavigationSectionSeedEntry objects:
38
+ ```csharp
39
+ Code = "detail",
40
+ ```
41
+ → Grep for `Code\s*=\s*"([^"]+)"`
42
+
43
+ **1b. Check each section code against RESERVED list**
44
+
45
+ For each extracted section code:
46
+ - If code == "detail" OR code == "create" OR code == "edit" → **BLOCKING finding**
47
+ - If code contains "-detail" (e.g., "department-detail") → **BLOCKING finding**
48
+ - Check if `IsActive = false` is set nearby (within 10 lines) — if so, downgrade to WARNING (it's hidden but still seeded, which is acceptable)
49
+
50
+ ### 2. Check Route Patterns
51
+
52
+ For each section route in seed data:
53
+ - Route ending with `/:id` that is NOT the "list" section's detail route → WARNING (may be a separate detail section that should be merged)
54
+ - Route containing `/detail/` or `/create/` or `/edit/` as segments → **BLOCKING** (forbidden patterns per SmartStack convention)
55
+
56
+ ### 3. Record Findings
57
+
58
+ For each issue found, create a finding:
59
+
60
+ ```
61
+ {
62
+ id: "NAV-001", // Sequential per category
63
+ severity: "BLOCKING",
64
+ category: "Navigation",
65
+ file: "EmployeesNavigationSeedData.cs",
66
+ line: 25,
67
+ message: "Reserved section code 'detail' is seeded as a visible menu item",
68
+ fix: "Remove this section entry from the Sections[] array. Detail routes are resolved by DynamicRouter convention (/:id under list section)."
69
+ }
70
+ ```
71
+
72
+ ### Finding IDs:
73
+
74
+ | ID | Severity | Rule |
75
+ |----|----------|------|
76
+ | NAV-001 | BLOCKING | Reserved section code (detail/create/edit) seeded as menu item |
77
+ | NAV-002 | BLOCKING | Section code contains "-detail" (e.g., department-detail) seeded as menu item |
78
+ | NAV-003 | BLOCKING | Route contains forbidden segment (/detail/, /create/, /edit/) |
79
+ | NAV-004 | WARNING | Reserved section code with IsActive = false (acceptable but unnecessary) |
80
+ | NAV-005 | WARNING | Section code not in kebab-case |
81
+
82
+ ---
83
+
84
+ ## SUCCESS METRICS:
85
+ - All NavigationSeedData files scanned
86
+ - Every section code checked against reserved list
87
+ - Every route checked for forbidden patterns
88
+ - Findings recorded with file:line evidence
89
+
90
+ ## NEXT STEP:
91
+ If {scope} is `all` or `crud` → proceed to `./step-02-crud-audit.md`
92
+ If {scope} is `nav` → skip to `./step-05-report.md`
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: step-02-crud-audit
3
+ description: Audit CRUD completeness - 4 page types per section, create buttons, componentRegistry
4
+ next_step: steps/step-03-perm-audit.md
5
+ ---
6
+
7
+ # Step 2: CRUD Audit
8
+
9
+ ## YOUR TASK:
10
+ Verify that every section in the application has complete CRUD support: 4 page types, create button on list pages, and proper componentRegistry registration.
11
+
12
+ ---
13
+
14
+ ## EXECUTION SEQUENCE:
15
+
16
+ ### 1. Identify Sections to Audit
17
+
18
+ From {seed_files}, extract all section codes that represent CRUD entities.
19
+
20
+ **Exclude from audit:**
21
+ - Sections with code: "dashboard", "calendar", "import-export", "approve", "balances" (these are specialized views, not CRUD entities)
22
+ - Sections with reserved codes: "detail", "create", "edit" (these shouldn't exist as sections)
23
+
24
+ **Include in audit:**
25
+ - "list" sections → audit as the main entity section
26
+ - "departments", "absence-types", or any other entity section → audit for CRUD completeness
27
+
28
+ For each auditable section, determine the entity name:
29
+ - Section code → PascalCase entity name (e.g., "departments" → "Department", "absence-types" → "AbsenceType")
30
+
31
+ ### 2. Check 4 Page Types per Section
32
+
33
+ For each entity, search in {page_files} for:
34
+
35
+ ```
36
+ Required page types (at least 3 naming conventions per type):
37
+ ListPage: {Entity}ListPage.tsx OR {Entity}sPage.tsx OR {Entities}Page.tsx
38
+ DetailPage: {Entity}DetailPage.tsx OR {Entity}Page.tsx
39
+ CreatePage: Create{Entity}Page.tsx OR {Entity}CreatePage.tsx OR {Entity}FormPage.tsx
40
+ EditPage: Edit{Entity}Page.tsx OR {Entity}EditPage.tsx OR {Entity}FormPage.tsx (shared)
41
+ ```
42
+
43
+ Note: Create and Edit may share a single `{Entity}FormPage.tsx` — this is acceptable.
44
+
45
+ **Findings:**
46
+
47
+ | ID | Severity | Rule |
48
+ |----|----------|------|
49
+ | CRUD-001 | BLOCKING | ListPage missing for entity |
50
+ | CRUD-002 | BLOCKING | DetailPage missing for entity |
51
+ | CRUD-003 | BLOCKING | Create/Edit page missing for entity (no CreatePage, EditPage, or FormPage) |
52
+
53
+ ### 3. Check Create Button on List Pages
54
+
55
+ For each ListPage found:
56
+
57
+ Grep for navigate patterns:
58
+ ```
59
+ navigate('create')
60
+ navigate(`create`)
61
+ navigate('new')
62
+ navigate(`${basePath}/create`)
63
+ navigate(`create`)
64
+ ```
65
+
66
+ Also check for link patterns:
67
+ ```
68
+ <Link to="create"
69
+ to={`create`}
70
+ to="new"
71
+ ```
72
+
73
+ If NONE found → **BLOCKING finding** (users cannot access create form)
74
+
75
+ | ID | Severity | Rule |
76
+ |----|----------|------|
77
+ | CRUD-004 | BLOCKING | ListPage has no Create/New button (no navigate to create route) |
78
+
79
+ ### 4. Check componentRegistry Registration
80
+
81
+ Read {registry_file} and extract all `PageRegistry.register()` calls.
82
+
83
+ For each entity section:
84
+ - Check for list page registration: key matching `*.{section}` or `*.{module}.{section}`
85
+ - Check for detail page registration: key matching `*.{section}.detail` or the `:id` route
86
+ - Check for create page registration: key matching `*.{section}.create`
87
+ - Check for edit page registration: key matching `*.{section}.edit`
88
+
89
+ | ID | Severity | Rule |
90
+ |----|----------|------|
91
+ | CRUD-005 | BLOCKING | Page exists on disk but NOT registered in componentRegistry |
92
+ | CRUD-006 | WARNING | componentRegistry entry has no matching page file on disk |
93
+
94
+ ### 5. Check Form Submit Handlers
95
+
96
+ For each Create/Edit/Form page:
97
+
98
+ Grep for submit patterns:
99
+ ```
100
+ onSubmit
101
+ handleSubmit
102
+ api.create(
103
+ api.post(
104
+ api.update(
105
+ api.put(
106
+ apiClient.post(
107
+ apiClient.put(
108
+ ```
109
+
110
+ If NONE found → WARNING (form exists but may not submit data)
111
+
112
+ | ID | Severity | Rule |
113
+ |----|----------|------|
114
+ | CRUD-007 | WARNING | Form page has no visible submit handler |
115
+
116
+ ---
117
+
118
+ ## SUCCESS METRICS:
119
+ - All entity sections identified from seed data
120
+ - 4 page types checked per entity
121
+ - Create button presence verified on all list pages
122
+ - componentRegistry cross-referenced with page files
123
+ - Form submit handlers checked
124
+
125
+ ## NEXT STEP:
126
+ If {scope} is `all` or `perm` → proceed to `./step-03-perm-audit.md`
127
+ If {scope} is `crud` → skip to `./step-05-report.md`