# Padrões de Arquitetura - MORPH Framework

## 🏗️ Clean Architecture Simplificada

```
┌────────────────────────────────────────────────┐
│                    Web                          │
│         (Blazor Server, Controllers)           │
├────────────────────────────────────────────────┤
│                 Application                     │
│      (Services, Commands, Queries, DTOs)       │
├────────────────────────────────────────────────┤
│                   Domain                        │
│        (Entities, Value Objects, Enums)        │
├────────────────────────────────────────────────┤
│               Infrastructure                    │
│    (EF Core, External Services, Repositories)  │
├────────────────────────────────────────────────┤
│                   Agents                        │
│        (MS Agent Framework, AI Services)       │
└────────────────────────────────────────────────┘
```

### Regras de Dependência
- Web → Application, Infrastructure, Agents
- Application → Domain
- Infrastructure → Domain, Application (interfaces)
- Agents → Domain, Application (interfaces)
- Domain → Nada (núcleo isolado)

---

## 📁 Organização por Feature

```
Application/
├── Features/
│   ├── Reports/
│   │   ├── Commands/
│   │   │   └── CreateReportSchedule/
│   │   ├── Queries/
│   │   │   └── GetReportSchedule/
│   │   ├── Services/
│   │   │   ├── IReportScheduleService.cs
│   │   │   └── ReportScheduleService.cs
│   │   └── DTOs/
│   │       └── ReportScheduleDto.cs
│   │
│   └── Users/
│       ├── Commands/
│       ├── Queries/
│       └── Services/
│
└── Common/
    ├── Interfaces/
    └── Exceptions/
```

---

## 🔄 CQRS Simplificado (Sem MediatR)

```csharp
// Application/Features/Reports/Services/IReportScheduleService.cs
public interface IReportScheduleService
{
    // Queries
    Task<ReportScheduleDto?> GetByIdAsync(int id);
    Task<List<ReportScheduleDto>> GetAllAsync();

    // Commands
    Task<ReportScheduleDto> CreateAsync(CreateReportScheduleRequest request);
    Task UpdateAsync(int id, UpdateReportScheduleRequest request);
    Task DeleteAsync(int id);
}
```

---

## 🔐 Segurança

### Authorization - Policy-Based
```csharp
// Program.cs
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("CanManageReports", policy =>
        policy.RequireRole("Admin", "ReportManager"));
});

// No componente Blazor
@attribute [Authorize(Policy = "CanManageReports")]
```

### Current User Service
```csharp
public interface ICurrentUserService
{
    string? UserId { get; }
    string? UserName { get; }
    bool IsAuthenticated { get; }
}
```

---

## ⚠️ Exception Handling

### Hierarquia
```csharp
public abstract class DomainException : Exception
{
    protected DomainException(string message) : base(message) { }
}

public class NotFoundException : DomainException
{
    public NotFoundException(string entityName, object key)
        : base($"Entity \"{entityName}\" ({key}) was not found.") { }
}

public class ValidationException : DomainException
{
    public IDictionary<string, string[]> Errors { get; }
}

// Feature-specific
public class ReportScheduleNotFoundException : NotFoundException
{
    public ReportScheduleNotFoundException(int id)
        : base("ReportSchedule", id) { }
}
```

---

## 🔌 HTTP Clients com Polly

```csharp
services.AddHttpClient<IMemberKitClient, MemberKitClient>(client =>
{
    client.BaseAddress = new Uri(configuration["MemberKit:BaseUrl"]!);
})
.AddTransientHttpErrorPolicy(p =>
    p.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2)));
```

---

## 🤖 Agents como Services (.NET 10)

> **IMPORTANTE:** Use exclusivamente Microsoft Agent Framework.

```csharp
// Agents/DependencyInjection.cs
using Microsoft.Extensions.AI;

public static IServiceCollection AddAgents(this IServiceCollection services, IConfiguration configuration)
{
    // Registrar ChatClient
    services.AddSingleton<IChatClient>(sp =>
    {
        var config = sp.GetRequiredService<IConfiguration>();

        return new ChatClient(
            model: "gpt-4o-mini",
            credential: new ApiKeyCredential(config["AzureOpenAI:ApiKey"]!),
            endpoint: new Uri(config["AzureOpenAI:Endpoint"]!)
        );
    });

    // Registrar agents como services
    services.AddScoped<IReportAnalyzerAgent, ReportAnalyzerAgent>();

    return services;
}

// Uso transparente nos services
public class ReportGeneratorJob(IReportAnalyzerAgent analyzer)
{
    public async Task ExecuteAsync(int scheduleId, CancellationToken ct)
    {
        var analysis = await analyzer.AnalyzeAsync(data, ct);
    }
}

// Implementação do agent
public class ReportAnalyzerAgent : IReportAnalyzerAgent
{
    private readonly IChatClient _chatClient;

    public ReportAnalyzerAgent(IChatClient chatClient)
    {
        _chatClient = chatClient;
    }

    public async Task<string> AnalyzeAsync(object data, CancellationToken ct)
    {
        var agent = _chatClient.CreateAgent(
            instructions: "Você é um especialista em análise de relatórios...",
            name: "ReportAnalyzer"
        );

        var response = await agent.RunAsync($"Analise: {data}", cancellationToken: ct);
        return response.Content;
    }
}
```

**Referência completa:** [Agent Framework Setup](./agent-framework-setup.md)

---

## 🎨 UI Component Libraries

### Decisão Arquitetural (ADR)

**Contexto:**
Projetos Blazor no MORPH-SPEC precisam de componentes UI consistentes, especialmente para features AI-first.

**Decisão:**
- **Padrão recomendado:** Fluent UI Blazor para projetos AI-first
- **Alternativa:** MudBlazor para SaaS tradicional
- **Híbrido:** Permitido quando justificado

**Razões:**

| Critério | Fluent UI | MudBlazor |
|----------|-----------|-----------|
| **AI Components** | ✅ Nativos (chat, streaming) | ❌ Não tem |
| **Microsoft Integration** | ✅ Agent Framework, Aspire | ❌ Terceiro |
| **Performance** | ✅ ~200KB | ⚠️ ~500KB |
| **Componentes** | ⚠️ ~50 | ✅ ~140 |
| **Future-proof** | ✅ Microsoft mantém | ❓ Comunidade |

**Consequências:**
- ✅ Melhor integração com stack Microsoft (.NET 10, Agent Framework)
- ✅ Performance otimizada (menor bundle)
- ✅ UX consistente com produtos Microsoft (Copilot, Teams)
- ⚠️ Pode precisar MudBlazor para grids/charts complexos
- ⚠️ Menos templates prontos que MudBlazor

### Matriz de Decisão

| Tipo de Projeto | UI Library Recomendada |
|-----------------|------------------------|
| SaaS com AI/chat | **Fluent UI** |
| SaaS com analytics pesados | **Fluent UI + MudBlazor** |
| Dashboard tradicional | **MudBlazor** |
| Admin panel simples | **Fluent UI** |
| Produto enterprise complexo | **Fluent UI + MudBlazor** |

### Pattern de Uso Híbrido

```csharp
// Program.cs - Registrar ambas libs
builder.Services.AddFluentUIComponents();
builder.Services.AddMudServices(); // Só se necessário
```

```razor
<!-- Usar Fluent UI para estrutura principal -->
<FluentLayout>
    <FluentHeader>
        <FluentToolbar>...</FluentToolbar>
    </FluentHeader>

    <FluentNavMenu>
        <FluentNavLink>...</FluentNavLink>
    </FluentNavMenu>

    <FluentMain>
        <!-- Usar MudBlazor para componentes específicos -->
        <MudDataGrid T="Order" ...>
            <!-- Grid complexo -->
        </MudDataGrid>

        <MudChart>
            <!-- Charts analytics -->
        </MudChart>

        <!-- Voltar para Fluent UI para AI -->
        <FluentMessageBar>
            AI response
        </FluentMessageBar>
    </FluentMain>
</FluentLayout>
```

### Checklist de Escolha

**Use Fluent UI quando:**
- [ ] Projeto tem features de AI/chat
- [ ] Integração com Agent Framework
- [ ] Performance é prioridade
- [ ] UX tipo Copilot/Microsoft 365
- [ ] Budget de bundle size limitado

**Adicione MudBlazor quando:**
- [ ] Precisa de DataGrid avançado (filtros, agrupamento, export)
- [ ] Dashboards com charts customizados
- [ ] Componentes que Fluent UI não oferece
- [ ] Time já conhece MudBlazor

**Use MudBlazor 100% quando:**
- [ ] Projeto não tem AI
- [ ] Já existe codebase MudBlazor
- [ ] Precisa de 100+ componentes diferentes
- [ ] Material Design é requisito

**Referência completa:** [Fluent UI Setup](./fluent-ui-setup.md)

---

## ✅ Checklist de Arquitetura

- [ ] Domain sem dependências externas
- [ ] Features organizadas por pasta
- [ ] Interfaces em Application, implementações em Infrastructure
- [ ] DTOs para comunicação entre camadas
- [ ] Exceptions customizadas para domínio
- [ ] DI via construtor (não Service Locator)
- [ ] Agents tratados como services
- [ ] Authorization via policies
- [ ] HTTP Clients tipados com retry
