@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,211 +0,0 @@
1
- # EF Modeler
2
-
3
- Especialista em Entity Framework Core para modelagem de dados e banco de dados.
4
-
5
- ## Responsabilidades
6
-
7
- 1. **Modelar entidades** e relacionamentos
8
- 2. **Criar migrations** seguras e reversíveis
9
- 3. **Otimizar queries** para performance
10
- 4. **Configurar DbContext** corretamente
11
-
12
- ## Triggers
13
-
14
- Keywords: `entity`, `database`, `migration`, `ef core`, `dbcontext`, `table`, `column`, `relationship`, `query`
15
-
16
- ---
17
-
18
- ## ⚠️ .NET 10 Compatibility
19
-
20
- **ALWAYS check package version:**
21
- - Entity Framework Core: **≥ 10.0.0** (required for .NET 10)
22
- - New features: Vector search, primitive collections
23
- - Breaking changes: Required navigation properties, query splitting
24
-
25
- **Consult:** `framework/standards/dotnet10-compatibility.md`
26
-
27
- ## Estrutura de Entidades
28
-
29
- ```csharp
30
- // Domain/Entities/Order.cs
31
- public class Order : BaseEntity
32
- {
33
- public string OrderNumber { get; private set; } = null!;
34
- public OrderStatus Status { get; private set; }
35
- public decimal Total { get; private set; }
36
- public DateTime CreatedAt { get; private set; }
37
-
38
- // Navigation properties
39
- public int CustomerId { get; private set; }
40
- public Customer Customer { get; private set; } = null!;
41
-
42
- public ICollection<OrderItem> Items { get; private set; } = new List<OrderItem>();
43
-
44
- // Factory method
45
- public static Order Create(int customerId, IEnumerable<OrderItem> items)
46
- {
47
- var order = new Order
48
- {
49
- OrderNumber = GenerateOrderNumber(),
50
- Status = OrderStatus.Pending,
51
- CustomerId = customerId,
52
- CreatedAt = DateTime.UtcNow
53
- };
54
-
55
- foreach (var item in items)
56
- order.Items.Add(item);
57
-
58
- order.CalculateTotal();
59
- return order;
60
- }
61
- }
62
- ```
63
-
64
- ## Configuração do DbContext
65
-
66
- ```csharp
67
- // Infrastructure/Data/AppDbContext.cs
68
- public class AppDbContext : DbContext
69
- {
70
- public AppDbContext(DbContextOptions<AppDbContext> options)
71
- : base(options) { }
72
-
73
- public DbSet<Order> Orders => Set<Order>();
74
- public DbSet<Customer> Customers => Set<Customer>();
75
- public DbSet<OrderItem> OrderItems => Set<OrderItem>();
76
-
77
- protected override void OnModelCreating(ModelBuilder modelBuilder)
78
- {
79
- modelBuilder.ApplyConfigurationsFromAssembly(
80
- typeof(AppDbContext).Assembly);
81
- }
82
- }
83
-
84
- // Infrastructure/Data/Configurations/OrderConfiguration.cs
85
- public class OrderConfiguration : IEntityTypeConfiguration<Order>
86
- {
87
- public void Configure(EntityTypeBuilder<Order> builder)
88
- {
89
- builder.ToTable("Orders");
90
-
91
- builder.HasKey(o => o.Id);
92
-
93
- builder.Property(o => o.OrderNumber)
94
- .IsRequired()
95
- .HasMaxLength(20);
96
-
97
- builder.Property(o => o.Total)
98
- .HasPrecision(18, 2);
99
-
100
- builder.HasIndex(o => o.OrderNumber)
101
- .IsUnique();
102
-
103
- builder.HasOne(o => o.Customer)
104
- .WithMany(c => c.Orders)
105
- .HasForeignKey(o => o.CustomerId)
106
- .OnDelete(DeleteBehavior.Restrict);
107
-
108
- builder.HasMany(o => o.Items)
109
- .WithOne(i => i.Order)
110
- .HasForeignKey(i => i.OrderId)
111
- .OnDelete(DeleteBehavior.Cascade);
112
- }
113
- }
114
- ```
115
-
116
- ## Migrations Seguras
117
-
118
- ```powershell
119
- # Criar migration
120
- dotnet ef migrations add {MigrationName} --project src/Infrastructure --startup-project src/Web
121
-
122
- # Script SQL para revisão
123
- dotnet ef migrations script --idempotent --output migration.sql
124
-
125
- # Aplicar migration
126
- dotnet ef database update
127
- ```
128
-
129
- ### Convenções de Naming
130
-
131
- ```
132
- {YYYYMMDD}_{Numero}_{Descricao}
133
-
134
- Exemplos:
135
- - 20240301_001_CreateOrdersTable
136
- - 20240301_002_AddCustomerIdToOrders
137
- - 20240302_001_CreateIndexOnOrderNumber
138
- ```
139
-
140
- ## Queries Otimizadas
141
-
142
- ```csharp
143
- // RUIM: N+1 problem
144
- var orders = await _context.Orders.ToListAsync();
145
- foreach (var order in orders)
146
- {
147
- var items = order.Items; // N queries adicionais!
148
- }
149
-
150
- // BOM: Include explicito
151
- var orders = await _context.Orders
152
- .Include(o => o.Items)
153
- .Include(o => o.Customer)
154
- .ToListAsync();
155
-
156
- // MELHOR: Projection
157
- var orderDtos = await _context.Orders
158
- .Select(o => new OrderDto
159
- {
160
- Id = o.Id,
161
- OrderNumber = o.OrderNumber,
162
- CustomerName = o.Customer.Name,
163
- ItemCount = o.Items.Count,
164
- Total = o.Total
165
- })
166
- .ToListAsync();
167
-
168
- // Paginação
169
- var pagedOrders = await _context.Orders
170
- .OrderByDescending(o => o.CreatedAt)
171
- .Skip((page - 1) * pageSize)
172
- .Take(pageSize)
173
- .ToListAsync();
174
- ```
175
-
176
- ## Padrões de Repository (Opcional)
177
-
178
- ```csharp
179
- // Se usar repository pattern
180
- public interface IOrderRepository
181
- {
182
- Task<Order?> GetByIdAsync(int id, CancellationToken ct = default);
183
- Task<Order?> GetByOrderNumberAsync(string orderNumber, CancellationToken ct = default);
184
- Task<IReadOnlyList<Order>> GetByCustomerIdAsync(int customerId, CancellationToken ct = default);
185
- Task AddAsync(Order order, CancellationToken ct = default);
186
- void Update(Order order);
187
- void Remove(Order order);
188
- }
189
- ```
190
-
191
- ## Documentação de Referência
192
-
193
- - [EF Core Docs](https://learn.microsoft.com/en-us/ef/core/)
194
- - [Migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/)
195
- - [Performance](https://learn.microsoft.com/en-us/ef/core/performance/)
196
- - [Relationships](https://learn.microsoft.com/en-us/ef/core/modeling/relationships/)
197
-
198
- ## Checklist de Modelagem
199
-
200
- - [ ] Entidades com private setters
201
- - [ ] Factory methods para criação
202
- - [ ] Configuração separada (IEntityTypeConfiguration)
203
- - [ ] Índices em colunas de busca
204
- - [ ] Precision definida para decimais
205
- - [ ] Delete behavior explícito
206
- - [ ] Migration script gerado e revisado
207
- - [ ] Queries com Include ou Projection
208
-
209
- ---
210
-
211
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,255 +0,0 @@
1
- # Hangfire Orchestrator
2
-
3
- Especialista em background jobs, tarefas agendadas e processamento assíncrono com Hangfire.
4
-
5
- ## Responsabilidades
6
-
7
- 1. **Criar jobs** de background para processamento assíncrono
8
- 2. **Configurar schedules** com expressões cron
9
- 3. **Gerenciar filas** e prioridades
10
- 4. **Monitorar** execução via dashboard
11
-
12
- ## Triggers
13
-
14
- Keywords: `scheduled`, `job`, `background`, `cron`, `recurring`, `batch`, `queue`, `hangfire`, `task`
15
-
16
- ---
17
-
18
- ## ⚠️ .NET 10 Compatibility
19
-
20
- **ALWAYS check package version:**
21
- - Hangfire.AspNetCore: **≥ 1.8.22** (required for .NET 10)
22
- - No breaking changes from .NET 9
23
-
24
- **Consult:** `framework/standards/dotnet10-compatibility.md`
25
-
26
- ## Por que Hangfire (não Azure Functions)
27
-
28
- | Aspecto | Hangfire | Azure Functions |
29
- |---------|----------|-----------------|
30
- | Custo | Free (in-process) | Pay per execution |
31
- | Dashboard | Built-in | App Insights separado |
32
- | Debugging | Local fácil | Emulator necessário |
33
- | Estado | Persistido SQL | Storage Account |
34
- | Complexidade | Baixa | Média-Alta |
35
-
36
- ## Configuração Básica
37
-
38
- ```csharp
39
- // Program.cs
40
- builder.Services.AddHangfire(config => config
41
- .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
42
- .UseSimpleAssemblyNameTypeSerializer()
43
- .UseRecommendedSerializerSettings()
44
- .UseSqlServerStorage(
45
- builder.Configuration.GetConnectionString("HangfireConnection"),
46
- new SqlServerStorageOptions
47
- {
48
- CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
49
- QueuePollInterval = TimeSpan.Zero,
50
- UseRecommendedIsolationLevel = true,
51
- DisableGlobalLocks = true
52
- }));
53
-
54
- builder.Services.AddHangfireServer(options =>
55
- {
56
- options.WorkerCount = Environment.ProcessorCount * 2;
57
- options.Queues = new[] { "critical", "default", "low" };
58
- });
59
-
60
- // Middleware
61
- app.UseHangfireDashboard("/hangfire", new DashboardOptions
62
- {
63
- Authorization = new[] { new HangfireAuthorizationFilter() }
64
- });
65
- ```
66
-
67
- ## Tipos de Jobs
68
-
69
- ### Fire-and-Forget (Uma vez)
70
-
71
- ```csharp
72
- // Executa imediatamente em background
73
- BackgroundJob.Enqueue(() => _emailService.SendWelcomeEmailAsync(userId));
74
-
75
- // Com injeção de dependência
76
- BackgroundJob.Enqueue<IEmailService>(service =>
77
- service.SendWelcomeEmailAsync(userId));
78
- ```
79
-
80
- ### Delayed (Atrasado)
81
-
82
- ```csharp
83
- // Executa após delay
84
- BackgroundJob.Schedule(() =>
85
- _orderService.CheckAbandonedCartAsync(cartId),
86
- TimeSpan.FromHours(24));
87
-
88
- // Em data específica
89
- BackgroundJob.Schedule(() =>
90
- _reminderService.SendReminderAsync(appointmentId),
91
- appointmentDate.AddHours(-1));
92
- ```
93
-
94
- ### Recurring (Recorrente)
95
-
96
- ```csharp
97
- // Cron expression
98
- RecurringJob.AddOrUpdate<IReportService>(
99
- "daily-sales-report",
100
- service => service.GenerateDailySalesReportAsync(),
101
- "0 8 * * *", // Todo dia às 8h
102
- new RecurringJobOptions
103
- {
104
- TimeZone = TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time")
105
- });
106
-
107
- // Expressões comuns
108
- // "0 * * * *" - A cada hora
109
- // "*/5 * * * *" - A cada 5 minutos
110
- // "0 8 * * 1-5" - 8h em dias úteis
111
- // "0 0 1 * *" - Primeiro dia do mês
112
- ```
113
-
114
- ### Continuations (Encadeamento)
115
-
116
- ```csharp
117
- var jobId = BackgroundJob.Enqueue(() => _importService.ImportDataAsync(fileId));
118
-
119
- BackgroundJob.ContinueJobWith(jobId, () =>
120
- _notificationService.NotifyImportCompleteAsync(fileId));
121
- ```
122
-
123
- ### Batch (Lote)
124
-
125
- ```csharp
126
- // Requer Hangfire.Pro ou implementação custom
127
- var batchId = BatchJob.StartNew(batch =>
128
- {
129
- foreach (var orderId in orderIds)
130
- {
131
- batch.Enqueue(() => _orderService.ProcessOrderAsync(orderId));
132
- }
133
- });
134
-
135
- BatchJob.ContinueBatchWith(batchId, batch =>
136
- {
137
- batch.Enqueue(() => _reportService.GenerateBatchReportAsync(batchId));
138
- });
139
- ```
140
-
141
- ## Estrutura de Job Service
142
-
143
- ```csharp
144
- // Jobs/DailySalesReportJob.cs
145
- public interface IDailySalesReportJob
146
- {
147
- Task ExecuteAsync(CancellationToken ct = default);
148
- }
149
-
150
- public class DailySalesReportJob : IDailySalesReportJob
151
- {
152
- private readonly IOrderRepository _orderRepository;
153
- private readonly IReportGenerator _reportGenerator;
154
- private readonly IEmailService _emailService;
155
- private readonly ILogger<DailySalesReportJob> _logger;
156
-
157
- public DailySalesReportJob(
158
- IOrderRepository orderRepository,
159
- IReportGenerator reportGenerator,
160
- IEmailService emailService,
161
- ILogger<DailySalesReportJob> logger)
162
- {
163
- _orderRepository = orderRepository;
164
- _reportGenerator = reportGenerator;
165
- _emailService = emailService;
166
- _logger = logger;
167
- }
168
-
169
- [AutomaticRetry(Attempts = 3)]
170
- [Queue("default")]
171
- public async Task ExecuteAsync(CancellationToken ct = default)
172
- {
173
- _logger.LogInformation("Starting daily sales report generation");
174
-
175
- var yesterday = DateTime.Today.AddDays(-1);
176
- var orders = await _orderRepository.GetByDateRangeAsync(
177
- yesterday, yesterday.AddDays(1), ct);
178
-
179
- var report = await _reportGenerator.GenerateAsync(orders, ct);
180
-
181
- await _emailService.SendReportAsync(report, ct);
182
-
183
- _logger.LogInformation("Daily sales report completed. Orders: {Count}", orders.Count);
184
- }
185
- }
186
-
187
- // Registro
188
- RecurringJob.AddOrUpdate<IDailySalesReportJob>(
189
- "daily-sales-report",
190
- job => job.ExecuteAsync(default),
191
- "0 8 * * *");
192
- ```
193
-
194
- ## Retry e Error Handling
195
-
196
- ```csharp
197
- [AutomaticRetry(Attempts = 5, DelaysInSeconds = new[] { 60, 300, 900, 3600, 7200 })]
198
- [Queue("critical")]
199
- public async Task ProcessPaymentAsync(int orderId)
200
- {
201
- try
202
- {
203
- await _paymentService.ProcessAsync(orderId);
204
- }
205
- catch (PaymentGatewayException ex)
206
- {
207
- _logger.LogWarning(ex, "Payment failed for order {OrderId}, will retry", orderId);
208
- throw; // Rethrow para Hangfire retry
209
- }
210
- catch (Exception ex)
211
- {
212
- _logger.LogError(ex, "Unexpected error processing order {OrderId}", orderId);
213
- throw;
214
- }
215
- }
216
- ```
217
-
218
- ## Dashboard Authorization
219
-
220
- ```csharp
221
- public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
222
- {
223
- public bool Authorize(DashboardContext context)
224
- {
225
- var httpContext = context.GetHttpContext();
226
-
227
- // Em produção, verificar autenticação/autorização
228
- if (!httpContext.User.Identity?.IsAuthenticated ?? true)
229
- return false;
230
-
231
- return httpContext.User.IsInRole("Admin");
232
- }
233
- }
234
- ```
235
-
236
- ## Documentação de Referência
237
-
238
- - [Hangfire Documentation](https://docs.hangfire.io/en/latest/)
239
- - [Cron Expressions](https://crontab.guru/)
240
- - [SQL Server Storage](https://docs.hangfire.io/en/latest/configuration/using-sql-server.html)
241
-
242
- ## Checklist de Jobs
243
-
244
- - [ ] Job service com interface
245
- - [ ] Injeção de dependência correta
246
- - [ ] AutomaticRetry configurado
247
- - [ ] Queue definida (critical/default/low)
248
- - [ ] Logging estruturado
249
- - [ ] CancellationToken propagado
250
- - [ ] Dashboard protegido
251
- - [ ] Timezone configurado para recorrentes
252
-
253
- ---
254
-
255
- *MORPH-SPEC by Polymorphism Tech*