@polymorphism-tech/morph-spec 2.3.0 → 3.0.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 (166) hide show
  1. package/CLAUDE.md +446 -1730
  2. package/README.md +515 -516
  3. package/bin/morph-spec.js +366 -294
  4. package/bin/task-manager.js +429 -368
  5. package/bin/validate.js +369 -268
  6. package/content/.claude/commands/morph-apply.md +221 -158
  7. package/content/.claude/commands/morph-deploy.md +529 -0
  8. package/content/.claude/commands/morph-preflight.md +227 -0
  9. package/content/.claude/commands/morph-proposal.md +122 -101
  10. package/content/.claude/commands/morph-status.md +86 -86
  11. package/content/.claude/commands/morph-troubleshoot.md +122 -0
  12. package/content/.claude/skills/infra/azure-deploy-specialist.md +699 -0
  13. package/content/.claude/skills/level-0-meta/README.md +7 -0
  14. package/content/.claude/skills/level-0-meta/code-review.md +226 -0
  15. package/content/.claude/skills/level-0-meta/morph-checklist.md +117 -0
  16. package/content/.claude/skills/level-0-meta/simulation-checklist.md +77 -0
  17. package/content/.claude/skills/level-1-workflows/README.md +7 -0
  18. package/content/.claude/skills/level-1-workflows/morph-replicate.md +213 -0
  19. package/content/.claude/{commands/morph-clarify.md → skills/level-1-workflows/phase-clarify.md} +131 -184
  20. package/content/.claude/{commands/morph-design.md → skills/level-1-workflows/phase-design.md} +213 -275
  21. package/content/.claude/skills/level-1-workflows/phase-setup.md +106 -0
  22. package/content/.claude/skills/level-1-workflows/phase-tasks.md +164 -0
  23. package/content/.claude/{commands/morph-uiux.md → skills/level-1-workflows/phase-uiux.md} +169 -211
  24. package/content/.claude/skills/level-2-domains/README.md +14 -0
  25. package/content/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +192 -0
  26. package/content/.claude/skills/{specialists → level-2-domains/architecture}/po-pm-advisor.md +197 -197
  27. package/content/.claude/skills/level-2-domains/architecture/standards-architect.md +156 -0
  28. package/content/.claude/skills/level-2-domains/backend/dotnet-senior.md +287 -0
  29. package/content/.claude/skills/level-2-domains/backend/ef-modeler.md +113 -0
  30. package/content/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +126 -0
  31. package/content/.claude/skills/level-2-domains/backend/ms-agent-expert.md +109 -0
  32. package/content/.claude/skills/level-2-domains/frontend/blazor-builder.md +210 -0
  33. package/content/.claude/skills/level-2-domains/frontend/nextjs-expert.md +154 -0
  34. package/content/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +191 -0
  35. package/content/.claude/skills/{specialists → level-2-domains/infrastructure}/azure-architect.md +142 -142
  36. package/content/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +126 -0
  37. package/content/.claude/skills/level-2-domains/infrastructure/container-specialist.md +131 -0
  38. package/content/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +119 -0
  39. package/content/.claude/skills/level-2-domains/integrations/asaas-financial.md +130 -0
  40. package/content/.claude/skills/level-2-domains/integrations/azure-identity.md +142 -0
  41. package/content/.claude/skills/level-2-domains/integrations/clerk-auth.md +108 -0
  42. package/content/.claude/skills/level-2-domains/integrations/resend-email.md +119 -0
  43. package/content/.claude/skills/level-2-domains/quality/code-analyzer.md +235 -0
  44. package/content/.claude/skills/level-2-domains/quality/testing-specialist.md +126 -0
  45. package/content/.claude/skills/level-3-technologies/README.md +7 -0
  46. package/content/.claude/skills/level-4-patterns/README.md +7 -0
  47. package/content/.claude/skills/specialists/prompt-engineer.md +189 -0
  48. package/content/.claude/skills/specialists/seo-growth-hacker.md +320 -0
  49. package/content/.morph/config/agents.json +762 -242
  50. package/content/.morph/config/config.template.json +122 -108
  51. package/content/.morph/docs/workflows/design-impl.md +37 -0
  52. package/content/.morph/docs/workflows/enforcement-pipeline.md +668 -0
  53. package/content/.morph/docs/workflows/fast-track.md +29 -0
  54. package/content/.morph/docs/workflows/full-morph.md +76 -0
  55. package/content/.morph/docs/workflows/standard.md +44 -0
  56. package/content/.morph/docs/workflows/ui-refresh.md +39 -0
  57. package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
  58. package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
  59. package/content/.morph/examples/scheduled-reports/spec.md +267 -0
  60. package/content/.morph/hooks/README.md +348 -239
  61. package/content/.morph/hooks/pre-commit-agents.sh +24 -24
  62. package/content/.morph/hooks/task-completed.js +73 -0
  63. package/content/.morph/hooks/teammate-idle.js +68 -0
  64. package/content/.morph/schemas/tasks.schema.json +220 -0
  65. package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
  66. package/content/.morph/standards/agent-framework-production.md +410 -0
  67. package/content/.morph/standards/agent-framework-setup.md +413 -453
  68. package/content/.morph/standards/agent-framework-workflows.md +349 -0
  69. package/content/.morph/standards/agent-teams-workflow.md +474 -0
  70. package/content/.morph/standards/architecture.md +325 -325
  71. package/content/.morph/standards/azure.md +605 -379
  72. package/content/.morph/standards/dotnet10-migration.md +520 -494
  73. package/content/.morph/templates/CONTEXT-FEATURE.md +276 -0
  74. package/content/.morph/templates/CONTEXT.md +170 -0
  75. package/content/.morph/templates/agent.cs +163 -172
  76. package/content/.morph/templates/clarify-questions.md +159 -0
  77. package/content/.morph/templates/contracts/Commands.cs +74 -0
  78. package/content/.morph/templates/contracts/Entities.cs +25 -0
  79. package/content/.morph/templates/contracts/Queries.cs +74 -0
  80. package/content/.morph/templates/contracts/README.md +74 -0
  81. package/content/.morph/templates/decisions.md +123 -106
  82. package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -0
  83. package/content/.morph/templates/infra/deploy-checklist.md +426 -0
  84. package/content/.morph/templates/proposal.md +141 -155
  85. package/content/.morph/templates/recap.md +94 -105
  86. package/content/.morph/templates/simulation.md +353 -0
  87. package/content/.morph/templates/spec.md +149 -148
  88. package/content/.morph/templates/state.template.json +222 -222
  89. package/content/.morph/templates/tasks.md +257 -235
  90. package/content/.morph/templates/ui-components.md +362 -276
  91. package/content/CLAUDE.md +150 -442
  92. package/detectors/structure-detector.js +245 -250
  93. package/docs/README.md +144 -149
  94. package/docs/getting-started.md +301 -302
  95. package/docs/installation.md +361 -361
  96. package/docs/validation-checklist.md +265 -266
  97. package/package.json +80 -80
  98. package/src/commands/advance-phase.js +266 -0
  99. package/src/commands/analyze-blazor-concurrency.js +193 -0
  100. package/src/commands/deploy.js +780 -0
  101. package/src/commands/detect-agents.js +167 -0
  102. package/src/commands/doctor.js +356 -280
  103. package/src/commands/generate-context.js +40 -0
  104. package/src/commands/init.js +258 -245
  105. package/src/commands/lint-fluent.js +352 -0
  106. package/src/commands/rollback-phase.js +185 -0
  107. package/src/commands/session-summary.js +291 -0
  108. package/src/commands/task.js +78 -75
  109. package/src/commands/troubleshoot.js +222 -0
  110. package/src/commands/update.js +192 -159
  111. package/src/commands/validate-blazor-state.js +210 -0
  112. package/src/commands/validate-blazor.js +156 -0
  113. package/src/commands/validate-css.js +84 -0
  114. package/src/commands/validate-phase.js +221 -0
  115. package/src/lib/blazor-concurrency-analyzer.js +288 -0
  116. package/src/lib/blazor-state-validator.js +291 -0
  117. package/src/lib/blazor-validator.js +374 -0
  118. package/src/lib/complexity-analyzer.js +441 -292
  119. package/src/lib/context-generator.js +513 -0
  120. package/src/lib/continuous-validator.js +421 -440
  121. package/src/lib/css-validator.js +352 -0
  122. package/src/lib/decision-constraint-loader.js +109 -0
  123. package/src/lib/design-system-detector.js +187 -0
  124. package/src/lib/design-system-scaffolder.js +299 -0
  125. package/src/lib/hook-executor.js +256 -0
  126. package/src/lib/recap-generator.js +205 -0
  127. package/src/lib/spec-validator.js +258 -0
  128. package/src/lib/standards-context-injector.js +287 -0
  129. package/src/lib/state-manager.js +397 -340
  130. package/src/lib/team-orchestrator.js +322 -0
  131. package/src/lib/troubleshoot-grep.js +194 -0
  132. package/src/lib/troubleshoot-index.js +144 -0
  133. package/src/lib/validation-runner.js +283 -0
  134. package/src/lib/validators/contract-compliance-validator.js +273 -0
  135. package/src/lib/validators/design-system-validator.js +231 -0
  136. package/src/utils/file-copier.js +187 -139
  137. package/content/.claude/commands/morph-costs.md +0 -206
  138. package/content/.claude/commands/morph-setup.md +0 -100
  139. package/content/.claude/commands/morph-tasks.md +0 -319
  140. package/content/.claude/skills/infra/bicep-architect.md +0 -419
  141. package/content/.claude/skills/infra/container-specialist.md +0 -437
  142. package/content/.claude/skills/infra/devops-engineer.md +0 -405
  143. package/content/.claude/skills/integrations/asaas-financial.md +0 -333
  144. package/content/.claude/skills/integrations/azure-identity.md +0 -309
  145. package/content/.claude/skills/integrations/clerk-auth.md +0 -290
  146. package/content/.claude/skills/specialists/ai-system-architect.md +0 -604
  147. package/content/.claude/skills/specialists/cost-guardian.md +0 -110
  148. package/content/.claude/skills/specialists/ef-modeler.md +0 -211
  149. package/content/.claude/skills/specialists/hangfire-orchestrator.md +0 -255
  150. package/content/.claude/skills/specialists/ms-agent-expert.md +0 -263
  151. package/content/.claude/skills/specialists/standards-architect.md +0 -78
  152. package/content/.claude/skills/specialists/ui-ux-designer.md +0 -1100
  153. package/content/.claude/skills/stacks/dotnet-blazor.md +0 -606
  154. package/content/.claude/skills/stacks/dotnet-nextjs.md +0 -402
  155. package/content/.claude/skills/stacks/shopify.md +0 -445
  156. package/content/.morph/config/azure-pricing.json +0 -70
  157. package/content/.morph/config/azure-pricing.schema.json +0 -50
  158. package/content/.morph/hooks/pre-commit-costs.sh +0 -91
  159. package/docs/api/cost-calculator.js.html +0 -513
  160. package/docs/api/design-system-generator.js.html +0 -382
  161. package/docs/api/global.html +0 -5263
  162. package/docs/api/index.html +0 -96
  163. package/docs/api/state-manager.js.html +0 -423
  164. package/src/commands/cost.js +0 -181
  165. package/src/commands/update-pricing.js +0 -206
  166. package/src/lib/cost-calculator.js +0 -429
@@ -1,105 +1,94 @@
1
- # Feature Recap: {{FEATURE_NAME_TITLE}}
2
-
3
- ## 📋 Summary
4
-
5
- | Field | Value |
6
- |-------|-------|
7
- | **Feature ID** | {feature-id} |
8
- | **Completed** | {{DATE}} |
9
- | **Total Tasks** | {X} |
10
- | **Time Spent** | {X}h |
11
- | **Agents Used** | {list} |
12
-
13
- ---
14
-
15
- ## ✅ What Was Delivered
16
-
17
- ### Functionality
18
- - {Funcionalidade 1 entregue}
19
- - {Funcionalidade 2 entregue}
20
- - {Funcionalidade 3 entregue}
21
-
22
- ### Files Created
23
- ```
24
- {lista de arquivos criados}
25
- ```
26
-
27
- ### Files Modified
28
- ```
29
- {lista de arquivos modificados}
30
- ```
31
-
32
- ---
33
-
34
- ## 🏗️ Architecture Decisions
35
-
36
- | Decision | Rationale |
37
- |----------|-----------|
38
- | {Decisão 1} | {Motivo} |
39
- | {Decisão 2} | {Motivo} |
40
-
41
- See full ADRs in `decisions.md`
42
-
43
- ---
44
-
45
- ## 🧪 Test Coverage
46
-
47
- | Type | Files | Coverage |
48
- |------|-------|----------|
49
- | Unit Tests | {X} | {X}% |
50
- | Integration Tests | {X} | {X}% |
51
-
52
- ---
53
-
54
- ## 💰 Cost Impact
55
-
56
- | Resource | Before | After | Delta |
57
- |----------|--------|-------|-------|
58
- | Azure SQL | $0 | $0 | $0 |
59
- | Container Apps | $X | $X | +$X |
60
- | Azure OpenAI | $X | $X | +$X |
61
- | **Total** | | | **+$X/month** |
62
-
63
- ---
64
-
65
- ## 📝 Lessons Learned
66
-
67
- ### What Went Well
68
- - {Ponto positivo 1}
69
- - {Ponto positivo 2}
70
-
71
- ### What Could Be Improved
72
- - {Ponto de melhoria 1}
73
- - {Ponto de melhoria 2}
74
-
75
- ### Recommendations for Future
76
- - {Recomendação 1}
77
- - {Recomendação 2}
78
-
79
- ---
80
-
81
- ## 🔗 Related Resources
82
-
83
- - **Proposal:** `proposal.md`
84
- - **Spec:** `spec.md`
85
- - **Contracts:** `contracts.cs`
86
- - **Tasks:** `tasks.md`
87
- - **Decisions:** `decisions.md`
88
- - **Azure DevOps Epic:** {link}
89
- - **PR:** {link}
90
-
91
- ---
92
-
93
- ## 📊 Metrics
94
-
95
- | Metric | Value |
96
- |--------|-------|
97
- | Tasks Completed | {X}/{X} |
98
- | Checkpoints Passed | {X} |
99
- | Code Reviews | {X} |
100
- | Bugs Found | {X} |
101
- | Bugs Fixed | {X} |
102
-
103
- ---
104
-
105
- *Generated by MORPH Framework on {{DATE}}*
1
+ # Feature Recap: {{FEATURE_NAME_TITLE}}
2
+
3
+ ## 📋 Summary
4
+
5
+ | Field | Value |
6
+ |-------|-------|
7
+ | **Feature ID** | {feature-id} |
8
+ | **Completed** | {{DATE}} |
9
+ | **Total Tasks** | {X} |
10
+ | **Time Spent** | {X}h |
11
+ | **Agents Used** | {list} |
12
+
13
+ ---
14
+
15
+ ## ✅ What Was Delivered
16
+
17
+ ### Functionality
18
+ - {Funcionalidade 1 entregue}
19
+ - {Funcionalidade 2 entregue}
20
+ - {Funcionalidade 3 entregue}
21
+
22
+ ### Files Created
23
+ ```
24
+ {lista de arquivos criados}
25
+ ```
26
+
27
+ ### Files Modified
28
+ ```
29
+ {lista de arquivos modificados}
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 🏗️ Architecture Decisions
35
+
36
+ | Decision | Rationale |
37
+ |----------|-----------|
38
+ | {Decisão 1} | {Motivo} |
39
+ | {Decisão 2} | {Motivo} |
40
+
41
+ See full ADRs in `decisions.md`
42
+
43
+ ---
44
+
45
+ ## 🧪 Test Coverage
46
+
47
+ | Type | Files | Coverage |
48
+ |------|-------|----------|
49
+ | Unit Tests | {X} | {X}% |
50
+ | Integration Tests | {X} | {X}% |
51
+
52
+ ---
53
+
54
+ ## 📝 Lessons Learned
55
+
56
+ ### What Went Well
57
+ - {Ponto positivo 1}
58
+ - {Ponto positivo 2}
59
+
60
+ ### What Could Be Improved
61
+ - {Ponto de melhoria 1}
62
+ - {Ponto de melhoria 2}
63
+
64
+ ### Recommendations for Future
65
+ - {Recomendação 1}
66
+ - {Recomendação 2}
67
+
68
+ ---
69
+
70
+ ## 🔗 Related Resources
71
+
72
+ - **Proposal:** `proposal.md`
73
+ - **Spec:** `spec.md`
74
+ - **Contracts:** `contracts.cs`
75
+ - **Tasks:** `tasks.md`
76
+ - **Decisions:** `decisions.md`
77
+ - **Azure DevOps Epic:** {link}
78
+ - **PR:** {link}
79
+
80
+ ---
81
+
82
+ ## 📊 Metrics
83
+
84
+ | Metric | Value |
85
+ |--------|-------|
86
+ | Tasks Completed | {X}/{X} |
87
+ | Checkpoints Passed | {X} |
88
+ | Code Reviews | {X} |
89
+ | Bugs Found | {X} |
90
+ | Bugs Fixed | {X} |
91
+
92
+ ---
93
+
94
+ *Generated by MORPH Framework on {{DATE}}*
@@ -0,0 +1,353 @@
1
+ # Template: Simulacao de Servicos Externos
2
+
3
+ > Template para configurar modo de simulacao em projetos .NET
4
+
5
+ ## Configuracao
6
+
7
+ ### appsettings.Development.json
8
+
9
+ ```json
10
+ {
11
+ "Simulation": {
12
+ "Enabled": true,
13
+ "ImageDelayMs": 500,
14
+ "EmailDelayMs": 100,
15
+ "PaymentDelayMs": 200,
16
+ "PlaceholderImageUrl": "https://picsum.photos/1024/1024"
17
+ }
18
+ }
19
+ ```
20
+
21
+ ### SimulationOptions.cs
22
+
23
+ ```csharp
24
+ namespace {Namespace}.Infrastructure.Options;
25
+
26
+ public class SimulationOptions
27
+ {
28
+ public bool Enabled { get; set; }
29
+ public int ImageDelayMs { get; set; } = 500;
30
+ public int EmailDelayMs { get; set; } = 100;
31
+ public int PaymentDelayMs { get; set; } = 200;
32
+ public string PlaceholderImageUrl { get; set; } = "https://picsum.photos/1024/1024";
33
+ }
34
+ ```
35
+
36
+ ---
37
+
38
+ ## DI Condicional
39
+
40
+ ### Program.cs
41
+
42
+ ```csharp
43
+ // Configurar options
44
+ builder.Services.Configure<SimulationOptions>(
45
+ builder.Configuration.GetSection("Simulation"));
46
+
47
+ // Registrar clientes baseado em modo
48
+ var simulationEnabled = builder.Configuration.GetValue<bool>("Simulation:Enabled");
49
+
50
+ if (simulationEnabled)
51
+ {
52
+ builder.Services.AddSimulationClients();
53
+ builder.Services.AddSingleton<IStartupFilter, SimulationWarningStartupFilter>();
54
+ }
55
+ else
56
+ {
57
+ builder.Services.AddProductionClients(builder.Configuration);
58
+ }
59
+ ```
60
+
61
+ ### ServiceCollectionExtensions.cs
62
+
63
+ ```csharp
64
+ namespace {Namespace}.Infrastructure.Extensions;
65
+
66
+ public static class ServiceCollectionExtensions
67
+ {
68
+ public static IServiceCollection AddSimulationClients(this IServiceCollection services)
69
+ {
70
+ // ========================================
71
+ // STATEFUL (mantem dados) → SINGLETON
72
+ // ========================================
73
+ services.AddSingleton<IReplicateClient, FakeReplicateClient>();
74
+ services.AddSingleton<IPaymentClient, FakePaymentClient>();
75
+
76
+ // ========================================
77
+ // STATELESS → SCOPED
78
+ // ========================================
79
+ services.AddScoped<IEmailClient, FakeEmailClient>();
80
+
81
+ // ========================================
82
+ // DEPENDENCIAS TRANSITIVAS - NAO ESQUECER!
83
+ // ========================================
84
+ services.AddHttpClient("FakeImageDownloader");
85
+ services.AddScoped<IImageDownloader>(sp =>
86
+ {
87
+ var httpClientFactory = sp.GetRequiredService<IHttpClientFactory>();
88
+ var httpClient = httpClientFactory.CreateClient("FakeImageDownloader");
89
+ var logger = sp.GetRequiredService<ILogger<FakeImageDownloader>>();
90
+ var options = sp.GetRequiredService<IOptions<SimulationOptions>>();
91
+ return new FakeImageDownloader(httpClient, logger, options);
92
+ });
93
+
94
+ return services;
95
+ }
96
+
97
+ public static IServiceCollection AddProductionClients(
98
+ this IServiceCollection services,
99
+ IConfiguration configuration)
100
+ {
101
+ // Clientes reais com HttpClient tipado
102
+ services.AddHttpClient<IReplicateClient, ReplicateClient>();
103
+ services.AddHttpClient<IPaymentClient, AsaasClient>();
104
+ services.AddHttpClient<IEmailClient, ResendClient>();
105
+ services.AddHttpClient<IImageDownloader, HttpImageDownloader>();
106
+
107
+ return services;
108
+ }
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Exemplos de Fake Clients
115
+
116
+ ### FakeReplicateClient (Stateful → Singleton)
117
+
118
+ ```csharp
119
+ public class FakeReplicateClient : IReplicateClient
120
+ {
121
+ // Stateful - REQUER Singleton
122
+ private readonly Dictionary<string, FakePrediction> _predictions = new();
123
+ private readonly ILogger<FakeReplicateClient> _logger;
124
+ private readonly SimulationOptions _options;
125
+
126
+ public FakeReplicateClient(
127
+ ILogger<FakeReplicateClient> logger,
128
+ IOptions<SimulationOptions> options)
129
+ {
130
+ _logger = logger;
131
+ _options = options.Value;
132
+ }
133
+
134
+ public Task<string> CreatePredictionAsync(CreatePredictionRequest request, CancellationToken ct)
135
+ {
136
+ var id = Guid.NewGuid().ToString();
137
+ _predictions[id] = new FakePrediction
138
+ {
139
+ Id = id,
140
+ Status = "processing",
141
+ Prompt = request.Input.Prompt,
142
+ CreatedAt = DateTime.UtcNow
143
+ };
144
+
145
+ _logger.LogInformation(
146
+ "[SIMULATED] Created prediction {Id} with prompt: {Prompt}",
147
+ id, request.Input.Prompt?.Substring(0, Math.Min(50, request.Input.Prompt.Length)));
148
+
149
+ return Task.FromResult(id);
150
+ }
151
+
152
+ public async Task<PredictionResult> WaitForPredictionAsync(string id, CancellationToken ct)
153
+ {
154
+ if (!_predictions.TryGetValue(id, out var prediction))
155
+ throw new InvalidOperationException($"Prediction {id} not found");
156
+
157
+ // Simular delay de processamento
158
+ await Task.Delay(_options.ImageDelayMs, ct);
159
+
160
+ var style = ExtractStyleFromPrompt(prediction.Prompt);
161
+
162
+ _logger.LogInformation(
163
+ "[SIMULATED] Prediction {Id} completed. Style: {Style}",
164
+ id, style);
165
+
166
+ return new PredictionResult
167
+ {
168
+ Id = id,
169
+ Status = "succeeded",
170
+ Output = _options.PlaceholderImageUrl
171
+ };
172
+ }
173
+
174
+ private static string ExtractStyleFromPrompt(string? prompt)
175
+ {
176
+ if (string.IsNullOrEmpty(prompt)) return "Default";
177
+
178
+ var lowerPrompt = prompt.ToLowerInvariant();
179
+
180
+ // IMPORTANTE: Atualizar conforme prompts REAIS do projeto
181
+ if (lowerPrompt.Contains("movie poster")) return "MoviePoster";
182
+ if (lowerPrompt.Contains("impressionist")) return "Impressionist";
183
+ if (lowerPrompt.Contains("baroque")) return "Baroque";
184
+ if (lowerPrompt.Contains("watercolor")) return "Watercolor";
185
+
186
+ return "Default";
187
+ }
188
+
189
+ private class FakePrediction
190
+ {
191
+ public string Id { get; init; } = "";
192
+ public string Status { get; set; } = "";
193
+ public string? Prompt { get; init; }
194
+ public DateTime CreatedAt { get; init; }
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### FakeEmailClient (Stateless → Scoped)
200
+
201
+ ```csharp
202
+ public class FakeEmailClient : IEmailClient
203
+ {
204
+ private readonly ILogger<FakeEmailClient> _logger;
205
+ private readonly SimulationOptions _options;
206
+
207
+ public FakeEmailClient(
208
+ ILogger<FakeEmailClient> logger,
209
+ IOptions<SimulationOptions> options)
210
+ {
211
+ _logger = logger;
212
+ _options = options.Value;
213
+ }
214
+
215
+ public async Task<string?> SendEmailAsync(
216
+ string to,
217
+ string subject,
218
+ string htmlBody,
219
+ IReadOnlyList<EmailAttachment>? attachments = null,
220
+ CancellationToken ct = default)
221
+ {
222
+ await Task.Delay(_options.EmailDelayMs, ct);
223
+
224
+ var attachmentCount = attachments?.Count ?? 0;
225
+
226
+ _logger.LogInformation(
227
+ "[SIMULATED] Email sent to {To}. Subject: {Subject}. Attachments: {Count}",
228
+ to, subject, attachmentCount);
229
+
230
+ return $"fake-message-{Guid.NewGuid():N}";
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### FakeImageDownloader (Stateless → Scoped)
236
+
237
+ ```csharp
238
+ public class FakeImageDownloader : IImageDownloader
239
+ {
240
+ private readonly HttpClient _httpClient;
241
+ private readonly ILogger<FakeImageDownloader> _logger;
242
+ private readonly SimulationOptions _options;
243
+
244
+ public FakeImageDownloader(
245
+ HttpClient httpClient,
246
+ ILogger<FakeImageDownloader> logger,
247
+ IOptions<SimulationOptions> options)
248
+ {
249
+ _httpClient = httpClient;
250
+ _logger = logger;
251
+ _options = options.Value;
252
+ }
253
+
254
+ public async Task<byte[]> DownloadAsync(string url, CancellationToken ct)
255
+ {
256
+ _logger.LogInformation(
257
+ "[SIMULATED] Downloading image from placeholder instead of {Url}",
258
+ url);
259
+
260
+ // Baixa imagem real do placeholder
261
+ var response = await _httpClient.GetAsync(_options.PlaceholderImageUrl, ct);
262
+ response.EnsureSuccessStatusCode();
263
+
264
+ return await response.Content.ReadAsByteArrayAsync(ct);
265
+ }
266
+ }
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Startup Warning
272
+
273
+ ```csharp
274
+ public class SimulationWarningStartupFilter : IStartupFilter
275
+ {
276
+ private readonly ILogger<SimulationWarningStartupFilter> _logger;
277
+
278
+ public SimulationWarningStartupFilter(ILogger<SimulationWarningStartupFilter> logger)
279
+ {
280
+ _logger = logger;
281
+ }
282
+
283
+ public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
284
+ {
285
+ _logger.LogWarning(
286
+ "⚠️ SIMULATION MODE ENABLED - External services are being simulated!");
287
+
288
+ return next;
289
+ }
290
+ }
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Dependency Trace Template
296
+
297
+ Antes de implementar, preencher este trace:
298
+
299
+ ```markdown
300
+ ## Dependency Trace para Simulacao
301
+
302
+ ### Feature: {Nome da Feature}
303
+
304
+ ### Fluxo Principal:
305
+ 1. Controller/Page chama {ServiceA}
306
+ 2. {ServiceA} chama {IExternalClient}
307
+ 3. {IExternalClient} retorna dados
308
+ 4. {ServiceA} chama {IDependenciaTransitiva} ← NAO ESQUECER!
309
+
310
+ ### Servicos a Mockar:
311
+ | Interface | Fake | Lifetime | Motivo |
312
+ |-----------|------|----------|--------|
313
+ | IReplicateClient | FakeReplicateClient | Singleton | Stateful (Dictionary) |
314
+ | IEmailClient | FakeEmailClient | Scoped | Stateless |
315
+ | IImageDownloader | FakeImageDownloader | Scoped | Stateless |
316
+
317
+ ### Checklist:
318
+ - [ ] Todas as interfaces mapeadas
319
+ - [ ] Lifetimes definidos corretamente
320
+ - [ ] Dependencias transitivas identificadas
321
+ - [ ] Assinaturas de metodos verificadas
322
+ - [ ] Prompts/payloads atuais lidos (se IA)
323
+ ```
324
+
325
+ ---
326
+
327
+ ## Checklist Rapido
328
+
329
+ ```markdown
330
+ ### Pre-Implementacao:
331
+ - [ ] Listar TODAS as interfaces envolvidas no fluxo
332
+ - [ ] Verificar dependencias transitivas (DI graph)
333
+ - [ ] Ler assinaturas COMPLETAS das interfaces
334
+ - [ ] Verificar lifetimes necessarios (Singleton vs Scoped)
335
+
336
+ ### Para mocks de IA:
337
+ - [ ] Ler prompts/payloads ATUAIS do codigo
338
+ - [ ] Verificar formato de response da API real
339
+ - [ ] Testar com dados reais primeiro (1 chamada) antes de mockar
340
+
341
+ ### Para mocks de Email:
342
+ - [ ] Verificar se ha attachments/inline images
343
+ - [ ] Testar renderizacao do template separadamente
344
+
345
+ ### Pos-Implementacao:
346
+ - [ ] Build passa: `dotnet build`
347
+ - [ ] DI valido: `dotnet run` sem erros
348
+ - [ ] Fluxo funciona em modo simulacao
349
+ ```
350
+
351
+ ---
352
+
353
+ *MORPH-SPEC Simulation Template*