@atlashub/smartstack-cli 3.43.0 → 3.45.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 (47) hide show
  1. package/dist/mcp-entry.mjs +201 -22
  2. package/dist/mcp-entry.mjs.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/agents/efcore/conflicts.md +22 -2
  5. package/templates/agents/efcore/migration.md +11 -0
  6. package/templates/agents/efcore/rebase-snapshot.md +7 -0
  7. package/templates/agents/efcore/scan.md +24 -2
  8. package/templates/agents/efcore/squash.md +7 -0
  9. package/templates/agents/gitflow/init.md +195 -12
  10. package/templates/skills/apex/SKILL.md +14 -9
  11. package/templates/skills/apex/_shared.md +3 -0
  12. package/templates/skills/apex/references/analysis-methods.md +1 -1
  13. package/templates/skills/apex/references/challenge-questions.md +21 -0
  14. package/templates/skills/apex/references/core-seed-data.md +59 -104
  15. package/templates/skills/apex/references/post-checks.md +289 -225
  16. package/templates/skills/apex/references/smartstack-api.md +33 -35
  17. package/templates/skills/apex/references/smartstack-frontend.md +99 -3
  18. package/templates/skills/apex/references/smartstack-layers.md +145 -23
  19. package/templates/skills/apex/steps/step-00-init.md +2 -2
  20. package/templates/skills/apex/steps/step-01-analyze.md +1 -0
  21. package/templates/skills/apex/steps/step-02-plan.md +4 -3
  22. package/templates/skills/apex/steps/step-03-execute.md +24 -24
  23. package/templates/skills/apex/steps/step-04-examine.md +64 -24
  24. package/templates/skills/apex/steps/step-05-deep-review.md +1 -1
  25. package/templates/skills/apex/steps/step-08-run-tests.md +21 -13
  26. package/templates/skills/application/references/application-roles-template.md +10 -15
  27. package/templates/skills/application/references/backend-entity-seeding.md +6 -5
  28. package/templates/skills/application/references/backend-seeding-and-dto-output.md +1 -1
  29. package/templates/skills/application/references/nav-fallback-procedure.md +14 -17
  30. package/templates/skills/application/references/provider-template.md +5 -5
  31. package/templates/skills/application/references/roles-client-project-handling.md +1 -1
  32. package/templates/skills/application/references/roles-fallback-procedure.md +10 -15
  33. package/templates/skills/application/steps/step-01-navigation.md +1 -1
  34. package/templates/skills/application/steps/step-02-permissions.md +3 -3
  35. package/templates/skills/application/steps/step-03b-provider.md +1 -0
  36. package/templates/skills/application/templates-seed.md +41 -47
  37. package/templates/skills/business-analyse/references/team-orchestration.md +2 -2
  38. package/templates/skills/controller/steps/step-04-perms.md +1 -1
  39. package/templates/skills/efcore/references/troubleshooting.md +2 -2
  40. package/templates/skills/efcore/steps/rebase-snapshot/step-00-init.md +2 -2
  41. package/templates/skills/efcore/steps/squash/step-00-init.md +2 -2
  42. package/templates/skills/apex/references/examine-build-validation.md +0 -82
  43. package/templates/skills/apex/references/execution-frontend-gates.md +0 -177
  44. package/templates/skills/apex/references/execution-frontend-patterns.md +0 -105
  45. package/templates/skills/apex/references/execution-layer1-rules.md +0 -96
  46. package/templates/skills/apex/references/initialization-challenge-flow.md +0 -110
  47. package/templates/skills/apex/references/planning-layer-mapping.md +0 -151
@@ -11,6 +11,11 @@
11
11
 
12
12
  ## 1. Parameter Extraction
13
13
 
14
+ > **IMPORTANT — `navRoute` in seed data = permission root (2 segments: `app.module`).**
15
+ > This matches the controller `[NavRoute]` attribute for module-level controllers (also 2 segments: `app.module`).
16
+ > The seed data `navRoute` serves as the base for module-level permissions (`navRoute.read`, `navRoute.create`).
17
+ > Section-level permissions extend it: `navRoute.{sectionCode}.read`.
18
+
14
19
  Extract navigation hierarchy from the task's `_seedDataMeta` (populated by guardrail 1e):
15
20
 
16
21
  ```javascript
@@ -26,7 +31,8 @@ const permissions = coreSeedData.permissions || [];
26
31
  const rolePerms = coreSeedData.rolePermissions || [];
27
32
 
28
33
  // Derived context (from guardrail or PRD)
29
- const navRoute = meta.navRoute; // e.g. "human-resources.projects"
34
+ // NOTE: navRoute here = permission root (2 segments), same as module-level controller NavRoute
35
+ const navRoute = meta.navRoute; // e.g. "human-resources.projects" (permission root)
30
36
  const appCode = meta.appCode; // e.g. "human-resources"
31
37
  const moduleCode = task.module; // e.g. "projects"
32
38
 
@@ -41,7 +47,7 @@ if (!navRoute) {
41
47
 
42
48
  | Variable | Example | Source |
43
49
  |----------|---------|--------|
44
- | `navRoute` | `human-resources.projects` | `_seedDataMeta.navRoute` |
50
+ | `navRoute` | `human-resources.projects` (permission root, 2 segments) | `_seedDataMeta.navRoute` |
45
51
  | `appCode` | `human-resources` | `_seedDataMeta.appCode` |
46
52
  | `moduleCode` | `projects` | `task.module` |
47
53
  | `navModules[]` | `[{code, label, icon, route, translations}]` | `coreSeedData.navigationModules` |
@@ -73,12 +79,9 @@ From `seedDataCore.navigationApplications[0]` in feature.json (generated by BA s
73
79
 
74
80
  ### GUID Generation Rule
75
81
 
76
-
77
82
  ```csharp
78
- // Deterministic GUID for APPLICATION
79
- public static readonly Guid ApplicationId =
80
- GenerateDeterministicGuid("navigation-application-{appCode}");
81
- // Example: GenerateDeterministicGuid("navigation-application-human-resources")
83
+ // Random GUID idempotence handled by Code-based lookups
84
+ public static readonly Guid ApplicationId = Guid.NewGuid();
82
85
  ```
83
86
 
84
87
  ### Template
@@ -95,9 +98,8 @@ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
95
98
  /// </summary>
96
99
  public static class NavigationApplicationSeedData
97
100
  {
98
- // Deterministic GUID for this application
99
- public static readonly Guid ApplicationId =
100
- GenerateDeterministicGuid("navigation-application-{appCode}");
101
+ // Random GUID — resolved by Code at runtime for idempotence
102
+ public static readonly Guid ApplicationId = Guid.NewGuid();
101
103
 
102
104
  /// <summary>
103
105
  /// Returns navigation application entry for seeding into core.nav_Applications.
@@ -161,12 +163,8 @@ public static class NavigationApplicationSeedData
161
163
  };
162
164
  }
163
165
 
164
- private static Guid GenerateDeterministicGuid(string seed)
165
- {
166
- using var sha256 = System.Security.Cryptography.SHA256.Create();
167
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(seed));
168
- return new Guid(hash.Take(16).ToArray());
169
- }
166
+ // No deterministic GUID generation — all IDs are random via Guid.NewGuid()
167
+ // Idempotence is handled by Code-based lookups at runtime
170
168
 
171
169
  /// <summary>
172
170
  /// Converts PascalCase route segments to kebab-case for web URLs.
@@ -222,17 +220,8 @@ public class NavigationApplicationSeedEntry
222
220
  ### GUID Generation Rule
223
221
 
224
222
  ```csharp
225
- // NEVER use Guid.NewGuid() — ALWAYS deterministic
226
- private static Guid GenerateDeterministicGuid(string seed)
227
- {
228
- using var sha256 = System.Security.Cryptography.SHA256.Create();
229
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(seed));
230
- return new Guid(hash.Take(16).ToArray());
231
- }
232
-
233
- // Usage: GUIDs are derived from the navigation path
234
- public static readonly Guid ModuleId = GenerateDeterministicGuid("navigation-module-{navRoute}");
235
- // Example: GenerateDeterministicGuid("navigation-module-human-resources.projects")
223
+ // ALWAYS use Guid.NewGuid() — avoids conflicts between projects/tenants/environments
224
+ public static readonly Guid ModuleId = Guid.NewGuid();
236
225
  ```
237
226
 
238
227
  ### Template
@@ -248,9 +237,8 @@ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{ModulePascal}
248
237
  /// </summary>
249
238
  public static class {ModulePascal}NavigationSeedData
250
239
  {
251
- // Deterministic GUID for this module
252
- public static readonly Guid {ModulePascal}ModuleId =
253
- GenerateDeterministicGuid("navigation-module-{navRoute}");
240
+ // Random GUID — resolved by Code at runtime for idempotence
241
+ public static readonly Guid {ModulePascal}ModuleId = Guid.NewGuid();
254
242
 
255
243
  /// <summary>
256
244
  /// Returns navigation module entry for seeding into core.nav_Modules.
@@ -315,12 +303,7 @@ public static class {ModulePascal}NavigationSeedData
315
303
  };
316
304
  }
317
305
 
318
- private static Guid GenerateDeterministicGuid(string seed)
319
- {
320
- using var sha256 = System.Security.Cryptography.SHA256.Create();
321
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(seed));
322
- return new Guid(hash.Take(16).ToArray());
323
- }
306
+ // No deterministic GUID generation — all IDs are random via Guid.NewGuid()
324
307
 
325
308
  /// <summary>
326
309
  /// Converts PascalCase route segments to kebab-case for web URLs.
@@ -390,15 +373,11 @@ public class NavigationTranslationSeedEntry
390
373
  ### GUID Generation Rules
391
374
 
392
375
  ```csharp
393
- // Section GUID: deterministic from navRoute + section code
394
- public static readonly Guid {SectionPascal}SectionId =
395
- GenerateDeterministicGuid("navigation-section-{navRoute}.{sectionCode}");
396
- // Example: GenerateDeterministicGuid("navigation-section-human-resources.employees.list")
397
-
398
- // Resource GUID: deterministic from navRoute + section code + resource code
399
- public static readonly Guid {ResourcePascal}ResourceId =
400
- GenerateDeterministicGuid("navigation-resource-{navRoute}.{sectionCode}.{resourceCode}");
401
- // Example: GenerateDeterministicGuid("navigation-resource-human-resources.employees.list.employees-grid")
376
+ // Section GUID: random
377
+ public static readonly Guid {SectionPascal}SectionId = Guid.NewGuid();
378
+
379
+ // Resource GUID: random
380
+ public static readonly Guid {ResourcePascal}ResourceId = Guid.NewGuid();
402
381
  ```
403
382
 
404
383
  ### Section Methods (add to {ModulePascal}NavigationSeedData.cs)
@@ -413,9 +392,8 @@ public static readonly Guid {ResourcePascal}ResourceId =
413
392
  ```csharp
414
393
  // --- Add AFTER GetTranslationEntries() in {ModulePascal}NavigationSeedData.cs ---
415
394
 
416
- // Deterministic GUIDs for sections
417
- public static readonly Guid {Section1Pascal}SectionId =
418
- GenerateDeterministicGuid("navigation-section-{navRoute}.{section1Code}");
395
+ // Random GUIDs for sections
396
+ public static readonly Guid {Section1Pascal}SectionId = Guid.NewGuid();
419
397
  // Repeat for each section...
420
398
 
421
399
  /// <summary>
@@ -504,9 +482,8 @@ public static IEnumerable<NavigationTranslationSeedEntry> GetSectionTranslationE
504
482
  ```csharp
505
483
  // --- Add AFTER GetSectionTranslationEntries() ---
506
484
 
507
- // Deterministic GUIDs for resources
508
- public static readonly Guid {Resource1Pascal}ResourceId =
509
- GenerateDeterministicGuid("navigation-resource-{navRoute}.{parentSectionCode}.{resource1Code}");
485
+ // Random GUIDs for resources
486
+ public static readonly Guid {Resource1Pascal}ResourceId = Guid.NewGuid();
510
487
  // Repeat for each resource...
511
488
 
512
489
  /// <summary>
@@ -660,7 +637,7 @@ Args:
660
637
 
661
638
  MCP returns:
662
639
  - `Permissions.cs` nested class (Application layer constants)
663
- - Permission seed entries with deterministic GUIDs
640
+ - Permission seed entries with random GUIDs
664
641
 
665
642
  ### Step B: Write Permissions.cs (Application layer)
666
643
 
@@ -699,12 +676,12 @@ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{ModulePascal}
699
676
  /// </summary>
700
677
  public static class {ModulePascal}PermissionsSeedData
701
678
  {
702
- // Deterministic GUIDs for permissions
703
- public static readonly Guid WildcardPermId = GenerateGuid("{navRoute}.*");
704
- public static readonly Guid ReadPermId = GenerateGuid("{navRoute}.read");
705
- public static readonly Guid CreatePermId = GenerateGuid("{navRoute}.create");
706
- public static readonly Guid UpdatePermId = GenerateGuid("{navRoute}.update");
707
- public static readonly Guid DeletePermId = GenerateGuid("{navRoute}.delete");
679
+ // Random GUIDs for permissions
680
+ public static readonly Guid WildcardPermId = Guid.NewGuid();
681
+ public static readonly Guid ReadPermId = Guid.NewGuid();
682
+ public static readonly Guid CreatePermId = Guid.NewGuid();
683
+ public static readonly Guid UpdatePermId = Guid.NewGuid();
684
+ public static readonly Guid DeletePermId = Guid.NewGuid();
708
685
 
709
686
  public static IEnumerable<PermissionSeedEntry> GetPermissionEntries(Guid moduleId)
710
687
  {
@@ -718,12 +695,8 @@ public static class {ModulePascal}PermissionsSeedData
718
695
  };
719
696
  }
720
697
 
721
- private static Guid GenerateGuid(string path)
722
- {
723
- using var sha256 = System.Security.Cryptography.SHA256.Create();
724
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes($"permission-{path}"));
725
- return new Guid(hash.Take(16).ToArray());
726
- }
698
+ // No deterministic GUID generation — all IDs are random via Guid.NewGuid()
699
+ // Permissions are resolved by Path at runtime, not by fixed GUIDs
727
700
  }
728
701
 
729
702
  public class PermissionSeedEntry
@@ -747,11 +720,11 @@ public class PermissionSeedEntry
747
720
  // --- Add to {ModulePascal}PermissionsSeedData class AFTER module-level permissions ---
748
721
 
749
722
  // Section-level permissions (for each section in navSections[])
750
- public static readonly Guid {SectionPascal}WildcardPermId = GenerateGuid("{navRoute}.{sectionCode}.*");
751
- public static readonly Guid {SectionPascal}ReadPermId = GenerateGuid("{navRoute}.{sectionCode}.read");
752
- public static readonly Guid {SectionPascal}CreatePermId = GenerateGuid("{navRoute}.{sectionCode}.create");
753
- public static readonly Guid {SectionPascal}UpdatePermId = GenerateGuid("{navRoute}.{sectionCode}.update");
754
- public static readonly Guid {SectionPascal}DeletePermId = GenerateGuid("{navRoute}.{sectionCode}.delete");
723
+ public static readonly Guid {SectionPascal}WildcardPermId = Guid.NewGuid();
724
+ public static readonly Guid {SectionPascal}ReadPermId = Guid.NewGuid();
725
+ public static readonly Guid {SectionPascal}CreatePermId = Guid.NewGuid();
726
+ public static readonly Guid {SectionPascal}UpdatePermId = Guid.NewGuid();
727
+ public static readonly Guid {SectionPascal}DeletePermId = Guid.NewGuid();
755
728
  // Repeat for each section...
756
729
 
757
730
  // Add to GetPermissionEntries() — AFTER module-level entries:
@@ -807,22 +780,13 @@ Creates the 4 standard application-scoped roles: Admin, Manager, Contributor, Vi
807
780
 
808
781
  ### GUID Generation Rule
809
782
 
810
- > **WARNING:** These deterministic GUIDs are ONLY used for role creation (if roles don't already exist).
811
- > They MUST NEVER be used for RolePermission mapping always look up roles by Code at runtime.
783
+ > **NOTE:** Role GUIDs are random (`Guid.NewGuid()`). Roles are resolved by Code at runtime.
784
+ > RolePermission mapping MUST look up roles by Code, not by GUID.
812
785
 
813
786
  ```csharp
814
- // Deterministic GUID from application ID + role type
815
- // WARNING: Only for role creation. NEVER use these GUIDs for RolePermission mapping.
816
- // RolePermissions MUST resolve roles by Code at runtime (see SeedRolePermissionsAsync).
817
- private static Guid GenerateRoleGuid(string roleType)
818
- {
819
- using var sha256 = System.Security.Cryptography.SHA256.Create();
820
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes($"role-{ApplicationId}-{roleType}"));
821
- return new Guid(hash.Take(16).ToArray());
822
- }
823
- // FORBIDDEN in RolePermission mapping:
824
- // var roleId = GenerateRoleGuid("admin"); // WRONG — GUID may not match DB
825
- // var roleId = DeterministicGuid("role:admin"); // WRONG — use Code lookup instead
787
+ // All role GUIDs are random ALWAYS resolve roles by Code at runtime
788
+ // FORBIDDEN in RolePermission mapping: hardcoded GUIDs of any kind
789
+ // CORRECT: var role = roles.FirstOrDefault(r => r.Code == "admin");
826
790
  ```
827
791
 
828
792
  ### Template
@@ -839,13 +803,13 @@ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
839
803
  /// </summary>
840
804
  public static class ApplicationRolesSeedData
841
805
  {
842
- // Application ID from NavigationApplicationSeedData (deterministic GUID)
806
+ // Application ID from NavigationApplicationSeedData
843
807
  public static readonly Guid ApplicationId = NavigationApplicationSeedData.ApplicationId;
844
808
 
845
- public static readonly Guid AdminRoleId = GenerateRoleGuid("admin");
846
- public static readonly Guid ManagerRoleId = GenerateRoleGuid("manager");
847
- public static readonly Guid ContributorRoleId = GenerateRoleGuid("contributor");
848
- public static readonly Guid ViewerRoleId = GenerateRoleGuid("viewer");
809
+ public static readonly Guid AdminRoleId = Guid.NewGuid();
810
+ public static readonly Guid ManagerRoleId = Guid.NewGuid();
811
+ public static readonly Guid ContributorRoleId = Guid.NewGuid();
812
+ public static readonly Guid ViewerRoleId = Guid.NewGuid();
849
813
 
850
814
  public static IEnumerable<ApplicationRoleSeedEntry> GetRoleEntries()
851
815
  {
@@ -898,12 +862,8 @@ public static class ApplicationRolesSeedData
898
862
  };
899
863
  }
900
864
 
901
- private static Guid GenerateRoleGuid(string roleType)
902
- {
903
- using var sha256 = System.Security.Cryptography.SHA256.Create();
904
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes($"role-{ApplicationId}-{roleType}"));
905
- return new Guid(hash.Take(16).ToArray());
906
- }
865
+ // No deterministic GUID generation — all IDs are random via Guid.NewGuid()
866
+ // Roles are resolved by Code at runtime
907
867
  }
908
868
 
909
869
  public class ApplicationRoleSeedEntry
@@ -1144,7 +1104,7 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
1144
1104
 
1145
1105
  // --- Resources (idempotent — use ACTUAL section IDs from DB, not deterministic seed IDs) ---
1146
1106
  // CRITICAL: NavigationSection.Create() generates its own ID in DB.
1147
- // The deterministic GUID from GetSectionEntries() is NOT the actual SectionId.
1107
+ // The GUID from GetSectionEntries() is NOT the actual SectionId in DB.
1148
1108
  // We MUST query the real section by Code+ModuleId to get the actual DB ID,
1149
1109
  // otherwise FK_nav_Resources_nav_Sections_SectionId will fail.
1150
1110
  foreach (var secEntry in {Module1Pascal}NavigationSeedData.GetSectionEntries(mod1Entity.Id))
@@ -1226,7 +1186,7 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
1226
1186
  .AnyAsync(rp => rp.Permission!.Path.StartsWith("{appCode}."), ct);
1227
1187
  if (exists) return;
1228
1188
 
1229
- // CRITICAL: Resolve roles by Code from DB — NEVER use deterministic GUIDs.
1189
+ // CRITICAL: Resolve roles by Code from DB — NEVER use hardcoded GUIDs.
1230
1190
  // Application-scoped roles (admin, manager, contributor, viewer) are created by
1231
1191
  // SeedRolesAsync() above. System roles use their own IDs that do NOT match
1232
1192
  // DeterministicGuid("role:admin").
@@ -1334,7 +1294,7 @@ Before marking the task as completed, verify ALL:
1334
1294
  - [ ] `ApplicationRolesSeedData.ApplicationId` references `NavigationApplicationSeedData.ApplicationId` (NO `{ApplicationGuid}` placeholder)
1335
1295
 
1336
1296
  **Module-Level:**
1337
- - [ ] Deterministic GUIDs (NEVER `Guid.NewGuid()`) SHA256 of path
1297
+ - [ ] Random GUIDs via `Guid.NewGuid()` (no deterministic/sequential/fixed values)
1338
1298
  - [ ] 4 languages for each navigation entity (fr, en, it, de)
1339
1299
  - [ ] `ApplicationRolesSeedData.cs` created (once per application)
1340
1300
  - [ ] 4 application roles defined: Admin, Manager, Contributor, Viewer
@@ -1398,7 +1358,7 @@ public class {Module}DevDataSeeder : IDevDataSeeder
1398
1358
  {
1399
1359
  new {EntityType}
1400
1360
  {
1401
- Id = GenerateDeterministicGuid("{entity-type}-{code}"),
1361
+ Id = Guid.NewGuid(),
1402
1362
  Code = "{code}",
1403
1363
  Name = "{name}",
1404
1364
  TenantId = SeedConstants.DefaultTenantId, // MANDATORY
@@ -1410,12 +1370,7 @@ public class {Module}DevDataSeeder : IDevDataSeeder
1410
1370
  await context.SaveChangesAsync(ct);
1411
1371
  }
1412
1372
 
1413
- private static Guid GenerateDeterministicGuid(string seed)
1414
- {
1415
- using var sha256 = System.Security.Cryptography.SHA256.Create();
1416
- var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(seed));
1417
- return new Guid(hash.Take(16).ToArray());
1418
- }
1373
+ // No deterministic GUID generation — all IDs are random via Guid.NewGuid()
1419
1374
  }
1420
1375
  ```
1421
1376