@polymorphism-tech/morph-spec 4.10.9 → 4.11.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 (145) hide show
  1. package/CLAUDE.md +3 -3
  2. package/LICENSE +71 -71
  3. package/README.md +5 -11
  4. package/bin/morph-spec.js +23 -1
  5. package/bin/task-manager.js +5 -5
  6. package/claude-plugin.json +1 -1
  7. package/docs/CHEATSHEET.md +1 -1
  8. package/docs/QUICKSTART.md +2 -8
  9. package/framework/agents/README.md +14 -14
  10. package/framework/agents/architecture/standards-architect.md +159 -159
  11. package/framework/agents/frontend/css-specialist.md +1 -1
  12. package/framework/agents/infrastructure/azure-architect.md +149 -149
  13. package/framework/agents/infrastructure/azure-deploy-specialist.md +4 -4
  14. package/framework/agents/infrastructure/infra-architect.md +48 -48
  15. package/framework/commands/morph-apply.md +18 -18
  16. package/framework/commands/morph-preflight.md +3 -3
  17. package/framework/commands/morph-proposal.md +15 -15
  18. package/framework/commands/morph-status.md +3 -3
  19. package/framework/commands/morph-troubleshoot.md +1 -1
  20. package/framework/hooks/README.md +204 -204
  21. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +2 -2
  22. package/framework/hooks/claude-code/session-start/inject-morph-context.js +1 -1
  23. package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +3 -3
  24. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +2 -2
  25. package/framework/hooks/git/pre-commit/agents.sh +1 -1
  26. package/framework/hooks/shared/phase-utils.js +139 -139
  27. package/framework/rules/csharp-standards.md +13 -13
  28. package/framework/rules/frontend-standards.md +13 -13
  29. package/framework/rules/infrastructure-standards.md +16 -16
  30. package/framework/rules/testing-standards.md +14 -14
  31. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +8 -8
  32. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +3 -3
  33. package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +254 -254
  34. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +1 -1
  35. package/framework/skills/level-0-meta/morph-init/SKILL.md +11 -11
  36. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +3 -3
  37. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +1 -1
  38. package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +4 -4
  39. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +25 -25
  40. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +8 -8
  41. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +7 -7
  42. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +4 -4
  43. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +23 -23
  44. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +1 -1
  45. package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +38 -0
  46. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +29 -29
  47. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -4
  48. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +9 -9
  49. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +17 -17
  50. package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +14 -0
  51. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +12 -12
  52. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +16 -16
  53. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +5 -5
  54. package/framework/standards/STANDARDS.json +2338 -2041
  55. package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -17
  56. package/framework/standards/infrastructure/supabase/supabase-custom-jwt.md +206 -0
  57. package/framework/templates/.idea/morph-templates.xml +92 -0
  58. package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  59. package/framework/templates/README.md +814 -814
  60. package/framework/templates/code/dotnet/contracts/Commands.cs +74 -74
  61. package/framework/templates/code/dotnet/contracts/Entities.cs +25 -25
  62. package/framework/templates/code/dotnet/contracts/Queries.cs +74 -74
  63. package/framework/templates/code/dotnet/contracts/README.md +74 -74
  64. package/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -173
  65. package/framework/templates/code/dotnet/frontend/component.razor +239 -239
  66. package/framework/templates/code/dotnet/jobs/agent.cs +163 -163
  67. package/framework/templates/code/dotnet/jobs/job.cs +171 -171
  68. package/framework/templates/code/dotnet/test.cs +239 -239
  69. package/framework/templates/code/sql/rls-policy.sql +57 -57
  70. package/framework/templates/code/sql/supabase-migration.sql +100 -100
  71. package/framework/templates/code/sql/supabase-migration.template.sql +113 -113
  72. package/framework/templates/code/typescript/contracts.ts +168 -168
  73. package/framework/templates/context/CONTEXT.md +181 -181
  74. package/framework/templates/docs/proposal.md +182 -182
  75. package/framework/templates/docs/user-stories.md +34 -34
  76. package/framework/templates/examples/design-system-examples.md +357 -357
  77. package/framework/templates/examples/spec-examples.md +90 -90
  78. package/framework/templates/feature/decisions.md +187 -187
  79. package/framework/templates/feature/recap.md +146 -146
  80. package/framework/templates/feature/tasks.md +199 -199
  81. package/framework/templates/infrastructure/azure/README.md +286 -286
  82. package/framework/templates/infrastructure/azure/deploy-checklist.md +426 -426
  83. package/framework/templates/infrastructure/azure/parameters.dev.json +29 -29
  84. package/framework/templates/infrastructure/azure/parameters.prod.json +29 -29
  85. package/framework/templates/infrastructure/azure/parameters.staging.json +29 -29
  86. package/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -67
  87. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  88. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  89. package/framework/templates/infrastructure/docker/easypanel.template.json +54 -54
  90. package/framework/workflows/README.md +18 -18
  91. package/framework/workflows/docs/enforcement-pipeline.md +1 -1
  92. package/framework/workflows/docs/full-morph.md +2 -2
  93. package/package.json +1 -1
  94. package/src/commands/agents/dispatch-agents.js +17 -0
  95. package/src/commands/agents/index.js +13 -13
  96. package/src/commands/agents/project-metrics.js +74 -0
  97. package/src/commands/project/doctor.js +3 -4
  98. package/src/commands/project/install-plugin-cmd.js +28 -28
  99. package/src/commands/project/setup-infra-cmd.js +12 -12
  100. package/src/commands/project/status.js +8 -1
  101. package/src/commands/scope/escalate.js +5 -3
  102. package/src/commands/standards/context-budget.js +89 -0
  103. package/src/commands/tasks/index.js +4 -4
  104. package/src/commands/templates/index.js +5 -5
  105. package/src/commands/utils/index.js +3 -3
  106. package/src/commands/validation/index.js +4 -4
  107. package/src/commands/validation/validate-feature.js +32 -3
  108. package/src/core/state/phase-state-machine.js +217 -217
  109. package/src/lib/agents/metrics-aggregator.js +56 -0
  110. package/src/lib/generators/design-system-generator.js +298 -298
  111. package/src/lib/generators/index.js +10 -10
  112. package/src/lib/generators/metadata-extractor.js +387 -387
  113. package/src/lib/stack-filter.js +65 -65
  114. package/src/lib/standards/digest-builder.js +57 -3
  115. package/src/lib/standards/index.js +7 -7
  116. package/src/lib/standards/standards-context-injector.js +302 -302
  117. package/src/lib/validators/architecture/architecture-validator.js +387 -387
  118. package/src/lib/validators/architecture/index.js +7 -7
  119. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +316 -316
  120. package/src/lib/validators/blazor/blazor-state-validator.js +279 -279
  121. package/src/lib/validators/blazor/blazor-validator.js +369 -369
  122. package/src/lib/validators/blazor/index.js +9 -9
  123. package/src/lib/validators/content/content-validator.js +287 -287
  124. package/src/lib/validators/content/index.js +7 -7
  125. package/src/lib/validators/contracts/index.js +7 -7
  126. package/src/lib/validators/css/css-validator.js +352 -352
  127. package/src/lib/validators/css/index.js +7 -7
  128. package/src/lib/validators/design-system/design-system-validator.js +231 -231
  129. package/src/lib/validators/design-system/index.js +7 -7
  130. package/src/lib/validators/nextjs/index.js +6 -6
  131. package/src/lib/validators/nextjs/next-component-validator.js +183 -183
  132. package/src/lib/validators/packages/index.js +7 -7
  133. package/src/lib/validators/packages/package-validator.js +360 -360
  134. package/src/lib/validators/shared/index.js +12 -12
  135. package/src/lib/validators/shared/issue-counter.js +18 -18
  136. package/src/lib/validators/shared/result-formatter.js +124 -124
  137. package/src/lib/validators/ui/index.js +7 -7
  138. package/src/lib/validators/ui/ui-contrast-validator.js +422 -422
  139. package/src/scripts/global-install.js +112 -58
  140. package/src/scripts/install-plugin.js +126 -126
  141. package/src/utils/claude-md-injector.js +90 -90
  142. package/src/utils/file-copier.js +200 -200
  143. package/src/utils/logger.js +32 -32
  144. package/src/utils/skills-installer.js +178 -178
  145. package/src/utils/version-checker.js +169 -175
@@ -1,279 +1,279 @@
1
- /**
2
- * Blazor State Validator
3
- *
4
- * Validates SessionState patterns in Blazor Server applications.
5
- * Ensures proper Persist + Reload pattern implementation.
6
- *
7
- * @module blazor-state-validator
8
- */
9
-
10
- import { countIssues } from '../shared/index.js';
11
-
12
- /**
13
- * @typedef {Object} StateIssue
14
- * @property {'error' | 'warning' | 'info'} type
15
- * @property {string} message
16
- * @property {string} [suggestion]
17
- * @property {string} file
18
- * @property {number} [line]
19
- * @property {string} [code]
20
- */
21
-
22
- // SessionState class patterns
23
- const SESSION_STATE_CLASS_PATTERNS = [
24
- /class\s+SessionState/,
25
- /public\s+class\s+\w*Session\w*State/,
26
- /public\s+class\s+\w*State\w*Session/,
27
- ];
28
-
29
- // LoadFrom method pattern
30
- const LOAD_FROM_PATTERN = /void\s+LoadFrom|LoadFrom\s*\(/;
31
-
32
- // IsLoaded property pattern
33
- const IS_LOADED_PATTERN = /bool\s+IsLoaded|IsLoaded\s*\{/;
34
-
35
- // Session middleware patterns
36
- const SESSION_MIDDLEWARE_PATTERNS = [
37
- /SessionMiddleware/,
38
- /UseSessionTracking/,
39
- /X-Session-Id/,
40
- /SessionId/,
41
- ];
42
-
43
- // OnInitializedAsync with session reload pattern
44
- const ON_INITIALIZED_RELOAD_PATTERN = /OnInitializedAsync.*Session.*LoadFrom|Session\.IsLoaded/s;
45
-
46
- /**
47
- * Validates SessionState class implementation.
48
- *
49
- * @param {string} content - File content
50
- * @param {string} filePath - Path to the file
51
- * @returns {StateIssue[]}
52
- */
53
- export function validateSessionStateClass(content, filePath) {
54
- const issues = [];
55
-
56
- // Check if this is a SessionState class
57
- const isSessionStateClass = SESSION_STATE_CLASS_PATTERNS.some((pattern) =>
58
- pattern.test(content)
59
- );
60
-
61
- if (!isSessionStateClass) {
62
- return issues;
63
- }
64
-
65
- // Check for LoadFrom method
66
- if (!LOAD_FROM_PATTERN.test(content)) {
67
- issues.push({
68
- type: 'error',
69
- message: 'SessionState sem metodo LoadFrom()',
70
- suggestion:
71
- 'Adicione um metodo LoadFrom(entity) para carregar estado do banco. Ver framework/standards/frontend/blazor/state.md',
72
- file: filePath,
73
- });
74
- }
75
-
76
- // Check for IsLoaded property
77
- if (!IS_LOADED_PATTERN.test(content)) {
78
- issues.push({
79
- type: 'warning',
80
- message: 'SessionState sem propriedade IsLoaded',
81
- suggestion:
82
- 'Adicione propriedade IsLoaded para evitar reloads desnecessarios',
83
- file: filePath,
84
- });
85
- }
86
-
87
- // Check for ToEntity method
88
- if (!content.includes('ToEntity')) {
89
- issues.push({
90
- type: 'info',
91
- message: 'SessionState sem metodo ToEntity()',
92
- suggestion:
93
- 'Considere adicionar ToEntity() para facilitar persistencia',
94
- file: filePath,
95
- });
96
- }
97
-
98
- return issues;
99
- }
100
-
101
- /**
102
- * Validates Program.cs for session middleware setup.
103
- *
104
- * @param {string} content - File content
105
- * @param {string} filePath - Path to the file
106
- * @returns {StateIssue[]}
107
- */
108
- export function validateProgramCsSetup(content, filePath) {
109
- const issues = [];
110
-
111
- // Only check Program.cs
112
- if (!filePath.toLowerCase().includes('program.cs')) {
113
- return issues;
114
- }
115
-
116
- // Check if project uses SessionState
117
- if (!content.includes('SessionState') && !content.includes('ISessionRepository')) {
118
- return issues; // Project doesn't seem to use session state
119
- }
120
-
121
- // Check for session middleware
122
- const hasSessionMiddleware = SESSION_MIDDLEWARE_PATTERNS.some((pattern) =>
123
- pattern.test(content)
124
- );
125
-
126
- if (!hasSessionMiddleware) {
127
- issues.push({
128
- type: 'warning',
129
- message: 'SessionMiddleware nao encontrado em Program.cs',
130
- suggestion:
131
- 'Adicione app.UseSessionTracking() antes de UseRouting(). Ver framework/standards/frontend/blazor/state.md',
132
- file: filePath,
133
- });
134
- }
135
-
136
- // Check for IHttpContextAccessor
137
- if (!content.includes('AddHttpContextAccessor')) {
138
- issues.push({
139
- type: 'warning',
140
- message: 'IHttpContextAccessor nao registrado',
141
- suggestion:
142
- 'Adicione builder.Services.AddHttpContextAccessor() para acessar SessionId em componentes',
143
- file: filePath,
144
- });
145
- }
146
-
147
- return issues;
148
- }
149
-
150
- /**
151
- * Validates Blazor pages for session reload pattern.
152
- *
153
- * @param {string} content - File content
154
- * @param {string} filePath - Path to the file
155
- * @returns {StateIssue[]}
156
- */
157
- export function validatePageSessionReload(content, filePath) {
158
- const issues = [];
159
-
160
- // Only check .razor files
161
- if (!filePath.endsWith('.razor')) {
162
- return issues;
163
- }
164
-
165
- // Check if page uses SessionState
166
- const usesSessionState =
167
- content.includes('SessionState') ||
168
- content.includes('@inject SessionState') ||
169
- content.includes('[Inject] SessionState');
170
-
171
- if (!usesSessionState) {
172
- return issues;
173
- }
174
-
175
- // Check for OnInitializedAsync
176
- if (!content.includes('OnInitializedAsync')) {
177
- issues.push({
178
- type: 'warning',
179
- message: 'Pagina usa SessionState mas nao tem OnInitializedAsync',
180
- suggestion:
181
- 'Adicione OnInitializedAsync para verificar e recarregar SessionState',
182
- file: filePath,
183
- });
184
- return issues;
185
- }
186
-
187
- // Check for IsLoaded check or LoadFrom in OnInitializedAsync
188
- if (!content.includes('IsLoaded') && !content.includes('LoadFrom')) {
189
- issues.push({
190
- type: 'warning',
191
- message: 'Pagina usa SessionState sem verificar IsLoaded',
192
- suggestion:
193
- 'Verifique Session.IsLoaded e chame LoadFrom() em OnInitializedAsync se necessario',
194
- file: filePath,
195
- });
196
- }
197
-
198
- return issues;
199
- }
200
-
201
- /**
202
- * Validates session repository implementation.
203
- *
204
- * @param {string} content - File content
205
- * @param {string} filePath - Path to the file
206
- * @returns {StateIssue[]}
207
- */
208
- export function validateSessionRepository(content, filePath) {
209
- const issues = [];
210
-
211
- // Check if this is a session repository
212
- const isSessionRepo =
213
- content.includes('ISessionRepository') ||
214
- content.includes('SessionRepository') ||
215
- content.includes('GetBySessionIdAsync');
216
-
217
- if (!isSessionRepo) {
218
- return issues;
219
- }
220
-
221
- // Check for essential methods
222
- if (!content.includes('GetBySessionIdAsync')) {
223
- issues.push({
224
- type: 'error',
225
- message: 'SessionRepository sem GetBySessionIdAsync',
226
- suggestion: 'Adicione metodo para buscar sessao por ID',
227
- file: filePath,
228
- });
229
- }
230
-
231
- if (!content.includes('SaveAsync') && !content.includes('UpsertAsync')) {
232
- issues.push({
233
- type: 'warning',
234
- message: 'SessionRepository sem metodo de persistencia (SaveAsync/UpsertAsync)',
235
- suggestion: 'Adicione metodo para salvar estado da sessao',
236
- file: filePath,
237
- });
238
- }
239
-
240
- // Check for cleanup method
241
- if (!content.includes('CleanupExpiredAsync') && !content.includes('DeleteExpired')) {
242
- issues.push({
243
- type: 'info',
244
- message: 'SessionRepository sem metodo de limpeza de sessoes expiradas',
245
- suggestion:
246
- 'Considere adicionar CleanupExpiredAsync() para remover sessoes antigas',
247
- file: filePath,
248
- });
249
- }
250
-
251
- return issues;
252
- }
253
-
254
- /**
255
- * Runs all state validations on a file.
256
- *
257
- * @param {string} content - File content
258
- * @param {string} filePath - Path to the file
259
- * @returns {StateIssue[]}
260
- */
261
- export function validateBlazorState(content, filePath) {
262
- const issues = [];
263
-
264
- issues.push(...validateSessionStateClass(content, filePath));
265
- issues.push(...validateProgramCsSetup(content, filePath));
266
- issues.push(...validatePageSessionReload(content, filePath));
267
- issues.push(...validateSessionRepository(content, filePath));
268
-
269
- return issues;
270
- }
271
-
272
- export default {
273
- validateBlazorState,
274
- validateSessionStateClass,
275
- validateProgramCsSetup,
276
- validatePageSessionReload,
277
- validateSessionRepository,
278
- countIssues,
279
- };
1
+ /**
2
+ * Blazor State Validator
3
+ *
4
+ * Validates SessionState patterns in Blazor Server applications.
5
+ * Ensures proper Persist + Reload pattern implementation.
6
+ *
7
+ * @module blazor-state-validator
8
+ */
9
+
10
+ import { countIssues } from '../shared/index.js';
11
+
12
+ /**
13
+ * @typedef {Object} StateIssue
14
+ * @property {'error' | 'warning' | 'info'} type
15
+ * @property {string} message
16
+ * @property {string} [suggestion]
17
+ * @property {string} file
18
+ * @property {number} [line]
19
+ * @property {string} [code]
20
+ */
21
+
22
+ // SessionState class patterns
23
+ const SESSION_STATE_CLASS_PATTERNS = [
24
+ /class\s+SessionState/,
25
+ /public\s+class\s+\w*Session\w*State/,
26
+ /public\s+class\s+\w*State\w*Session/,
27
+ ];
28
+
29
+ // LoadFrom method pattern
30
+ const LOAD_FROM_PATTERN = /void\s+LoadFrom|LoadFrom\s*\(/;
31
+
32
+ // IsLoaded property pattern
33
+ const IS_LOADED_PATTERN = /bool\s+IsLoaded|IsLoaded\s*\{/;
34
+
35
+ // Session middleware patterns
36
+ const SESSION_MIDDLEWARE_PATTERNS = [
37
+ /SessionMiddleware/,
38
+ /UseSessionTracking/,
39
+ /X-Session-Id/,
40
+ /SessionId/,
41
+ ];
42
+
43
+ // OnInitializedAsync with session reload pattern
44
+ const ON_INITIALIZED_RELOAD_PATTERN = /OnInitializedAsync.*Session.*LoadFrom|Session\.IsLoaded/s;
45
+
46
+ /**
47
+ * Validates SessionState class implementation.
48
+ *
49
+ * @param {string} content - File content
50
+ * @param {string} filePath - Path to the file
51
+ * @returns {StateIssue[]}
52
+ */
53
+ export function validateSessionStateClass(content, filePath) {
54
+ const issues = [];
55
+
56
+ // Check if this is a SessionState class
57
+ const isSessionStateClass = SESSION_STATE_CLASS_PATTERNS.some((pattern) =>
58
+ pattern.test(content)
59
+ );
60
+
61
+ if (!isSessionStateClass) {
62
+ return issues;
63
+ }
64
+
65
+ // Check for LoadFrom method
66
+ if (!LOAD_FROM_PATTERN.test(content)) {
67
+ issues.push({
68
+ type: 'error',
69
+ message: 'SessionState sem metodo LoadFrom()',
70
+ suggestion:
71
+ 'Adicione um metodo LoadFrom(entity) para carregar estado do banco. Ver framework/standards/frontend/blazor/state.md',
72
+ file: filePath,
73
+ });
74
+ }
75
+
76
+ // Check for IsLoaded property
77
+ if (!IS_LOADED_PATTERN.test(content)) {
78
+ issues.push({
79
+ type: 'warning',
80
+ message: 'SessionState sem propriedade IsLoaded',
81
+ suggestion:
82
+ 'Adicione propriedade IsLoaded para evitar reloads desnecessarios',
83
+ file: filePath,
84
+ });
85
+ }
86
+
87
+ // Check for ToEntity method
88
+ if (!content.includes('ToEntity')) {
89
+ issues.push({
90
+ type: 'info',
91
+ message: 'SessionState sem metodo ToEntity()',
92
+ suggestion:
93
+ 'Considere adicionar ToEntity() para facilitar persistencia',
94
+ file: filePath,
95
+ });
96
+ }
97
+
98
+ return issues;
99
+ }
100
+
101
+ /**
102
+ * Validates Program.cs for session middleware setup.
103
+ *
104
+ * @param {string} content - File content
105
+ * @param {string} filePath - Path to the file
106
+ * @returns {StateIssue[]}
107
+ */
108
+ export function validateProgramCsSetup(content, filePath) {
109
+ const issues = [];
110
+
111
+ // Only check Program.cs
112
+ if (!filePath.toLowerCase().includes('program.cs')) {
113
+ return issues;
114
+ }
115
+
116
+ // Check if project uses SessionState
117
+ if (!content.includes('SessionState') && !content.includes('ISessionRepository')) {
118
+ return issues; // Project doesn't seem to use session state
119
+ }
120
+
121
+ // Check for session middleware
122
+ const hasSessionMiddleware = SESSION_MIDDLEWARE_PATTERNS.some((pattern) =>
123
+ pattern.test(content)
124
+ );
125
+
126
+ if (!hasSessionMiddleware) {
127
+ issues.push({
128
+ type: 'warning',
129
+ message: 'SessionMiddleware nao encontrado em Program.cs',
130
+ suggestion:
131
+ 'Adicione app.UseSessionTracking() antes de UseRouting(). Ver framework/standards/frontend/blazor/state.md',
132
+ file: filePath,
133
+ });
134
+ }
135
+
136
+ // Check for IHttpContextAccessor
137
+ if (!content.includes('AddHttpContextAccessor')) {
138
+ issues.push({
139
+ type: 'warning',
140
+ message: 'IHttpContextAccessor nao registrado',
141
+ suggestion:
142
+ 'Adicione builder.Services.AddHttpContextAccessor() para acessar SessionId em componentes',
143
+ file: filePath,
144
+ });
145
+ }
146
+
147
+ return issues;
148
+ }
149
+
150
+ /**
151
+ * Validates Blazor pages for session reload pattern.
152
+ *
153
+ * @param {string} content - File content
154
+ * @param {string} filePath - Path to the file
155
+ * @returns {StateIssue[]}
156
+ */
157
+ export function validatePageSessionReload(content, filePath) {
158
+ const issues = [];
159
+
160
+ // Only check .razor files
161
+ if (!filePath.endsWith('.razor')) {
162
+ return issues;
163
+ }
164
+
165
+ // Check if page uses SessionState
166
+ const usesSessionState =
167
+ content.includes('SessionState') ||
168
+ content.includes('@inject SessionState') ||
169
+ content.includes('[Inject] SessionState');
170
+
171
+ if (!usesSessionState) {
172
+ return issues;
173
+ }
174
+
175
+ // Check for OnInitializedAsync
176
+ if (!content.includes('OnInitializedAsync')) {
177
+ issues.push({
178
+ type: 'warning',
179
+ message: 'Pagina usa SessionState mas nao tem OnInitializedAsync',
180
+ suggestion:
181
+ 'Adicione OnInitializedAsync para verificar e recarregar SessionState',
182
+ file: filePath,
183
+ });
184
+ return issues;
185
+ }
186
+
187
+ // Check for IsLoaded check or LoadFrom in OnInitializedAsync
188
+ if (!content.includes('IsLoaded') && !content.includes('LoadFrom')) {
189
+ issues.push({
190
+ type: 'warning',
191
+ message: 'Pagina usa SessionState sem verificar IsLoaded',
192
+ suggestion:
193
+ 'Verifique Session.IsLoaded e chame LoadFrom() em OnInitializedAsync se necessario',
194
+ file: filePath,
195
+ });
196
+ }
197
+
198
+ return issues;
199
+ }
200
+
201
+ /**
202
+ * Validates session repository implementation.
203
+ *
204
+ * @param {string} content - File content
205
+ * @param {string} filePath - Path to the file
206
+ * @returns {StateIssue[]}
207
+ */
208
+ export function validateSessionRepository(content, filePath) {
209
+ const issues = [];
210
+
211
+ // Check if this is a session repository
212
+ const isSessionRepo =
213
+ content.includes('ISessionRepository') ||
214
+ content.includes('SessionRepository') ||
215
+ content.includes('GetBySessionIdAsync');
216
+
217
+ if (!isSessionRepo) {
218
+ return issues;
219
+ }
220
+
221
+ // Check for essential methods
222
+ if (!content.includes('GetBySessionIdAsync')) {
223
+ issues.push({
224
+ type: 'error',
225
+ message: 'SessionRepository sem GetBySessionIdAsync',
226
+ suggestion: 'Adicione metodo para buscar sessao por ID',
227
+ file: filePath,
228
+ });
229
+ }
230
+
231
+ if (!content.includes('SaveAsync') && !content.includes('UpsertAsync')) {
232
+ issues.push({
233
+ type: 'warning',
234
+ message: 'SessionRepository sem metodo de persistencia (SaveAsync/UpsertAsync)',
235
+ suggestion: 'Adicione metodo para salvar estado da sessao',
236
+ file: filePath,
237
+ });
238
+ }
239
+
240
+ // Check for cleanup method
241
+ if (!content.includes('CleanupExpiredAsync') && !content.includes('DeleteExpired')) {
242
+ issues.push({
243
+ type: 'info',
244
+ message: 'SessionRepository sem metodo de limpeza de sessoes expiradas',
245
+ suggestion:
246
+ 'Considere adicionar CleanupExpiredAsync() para remover sessoes antigas',
247
+ file: filePath,
248
+ });
249
+ }
250
+
251
+ return issues;
252
+ }
253
+
254
+ /**
255
+ * Runs all state validations on a file.
256
+ *
257
+ * @param {string} content - File content
258
+ * @param {string} filePath - Path to the file
259
+ * @returns {StateIssue[]}
260
+ */
261
+ export function validateBlazorState(content, filePath) {
262
+ const issues = [];
263
+
264
+ issues.push(...validateSessionStateClass(content, filePath));
265
+ issues.push(...validateProgramCsSetup(content, filePath));
266
+ issues.push(...validatePageSessionReload(content, filePath));
267
+ issues.push(...validateSessionRepository(content, filePath));
268
+
269
+ return issues;
270
+ }
271
+
272
+ export default {
273
+ validateBlazorState,
274
+ validateSessionStateClass,
275
+ validateProgramCsSetup,
276
+ validatePageSessionReload,
277
+ validateSessionRepository,
278
+ countIssues,
279
+ };