-
territory_memberships:- Índice composto:
(user_id, territory_id) - Uso: Busca de membership por usuário e território
- Impacto: Alto (queries frequentes)
- Índice composto:
-
community_posts:- Índice composto:
(territory_id, status, created_at_utc) - Uso: Feed do território ordenado por data
- Impacto: Alto (queries frequentes)
- Índice composto:
-
moderation_reports:- Índice composto:
(target_type, target_id, created_at_utc) - Uso: Listagem de reports por target
- Impacto: Médio (queries menos frequentes)
- Índice composto:
Plano de Implementação: Requisitos Desejáveis para Produção
Resumo
Este documento detalha o plano de implementação para os requisitos desejáveis (pós-lançamento) identificados na avaliação completa para produção (docs/50_PRODUCAO_AVALIACAO_COMPLETA.md).
📋 Requisitos Desejáveis Planejados
1. Índices de Banco de Dados
Status: Planejado
Prioridade: Média
Complexidade: Média
Estimativa: 1-2 dias
Objetivo
Adicionar índices faltantes identificados na revisão de código para melhorar performance de queries.
-
Análise de Queries:
- Identificar queries lentas via logs
- Analisar execution plans
- Priorizar índices por impacto
-
Criar Migration:
// Migration: AddPerformanceIndexes migrationBuilder.CreateIndex( name: "IX_territory_memberships_user_territory", table: "territory_memberships", columns: new[] { "user_id", "territory_id" }, unique: true); migrationBuilder.CreateIndex( name: "IX_community_posts_territory_status_created", table: "community_posts", columns: new[] { "territory_id", "status", "created_at_utc" }); migrationBuilder.CreateIndex( name: "IX_moderation_reports_target_created", table: "moderation_reports", columns: new[] { "target_type", "target_id", "created_at_utc" }); -
Testar Performance:
- Comparar tempos de execução antes/depois
- Verificar impacto em writes
- Monitorar espaço em disco
-
Validar em Staging:
- Testar com dados de produção (sanitizados)
- Verificar impactos negativos
- Ajustar se necessário
Critérios de Sucesso
- ✅ Queries críticas com latência < 100ms (P95)
- ✅ Índices criados sem impacto negativo em writes
- ✅ Migration testada em staging
2. Métricas Básicas
Status: Planejado
Prioridade: Média
Complexidade: Média-Alta
Estimativa: 2-3 dias
Objetivo
Implementar métricas básicas para observabilidade em produção.
-
Métricas de Performance:
- Request rate (req/s)
- Error rate (%)
- Latência (P50, P95, P99)
- Throughput (bytes/s)
-
Métricas de Negócio:
- Posts criados
- Eventos criados
- Membros cadastrados
- Territórios criados
-
Métricas de Sistema:
- CPU usage
- Memory usage
- Database connections
- Cache hit rate
Opção 1: Application Insights (Azure)
- Pros: Integração fácil, dashboards prontos, alertas
- Contras: Custo, dependência de Azure
- Estimativa: 2 dias
Opção 2: Prometheus + Grafana
- Pros: Open source, flexível, sem vendor lock-in
- Contras: Mais configuração necessária
- Estimativa: 3 dias
Opção 3: CloudWatch (AWS)
- Pros: Integração AWS, fácil configuração
- Contras: Custo, dependência de AWS
- Estimativa: 2 dias
Recomendação
Prometheus + Grafana (Opção 2) para flexibilidade e sem vendor lock-in.
-
Adicionar Prometheus:
dotnet add package prometheus-net.AspNetCore -
Configurar Métricas:
// Program.cs app.UseHttpMetrics(); app.MapMetrics(); -
Adicionar Métricas Customizadas:
private static readonly Counter PostsCreated = Metrics .CreateCounter("araponga_posts_created_total", "Total posts created"); private static readonly Histogram RequestDuration = Metrics .CreateHistogram("araponga_request_duration_seconds", "Request duration"); -
Configurar Grafana:
- Dashboard para métricas de performance
- Dashboard para métricas de negócio
- Alertas básicos
Critérios de Sucesso
- ✅ Métricas coletadas corretamente
- ✅ Dashboards funcionando
- ✅ Alertas configurados
3. Connection Pooling Explícito
Status: Planejado
Prioridade: Baixa
Complexidade: Baixa
Estimativa: 1 dia
Objetivo
Configurar connection pooling explicitamente para melhor controle e monitoramento.
-
Configurar Pooling no EF Core:
services.AddDbContext<ArapongaDbContext>(options => options.UseNpgsql(connectionString, npgsqlOptions => { npgsqlOptions.EnableRetryOnFailure( maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(5), errorCodesToAdd: null); npgsqlOptions.CommandTimeout(30); })); -
Configurar Connection String:
{ "ConnectionStrings": { "Postgres": "Host=...;Port=5432;Database=...;Username=...;Password=...;Pooling=true;MinPoolSize=5;MaxPoolSize=100;Connection Lifetime=300" } } -
Monitorar Conexões:
- Métricas de conexões ativas
- Alertas para pool exhaustion
- Logs de conexões
Critérios de Sucesso
- ✅ Pool configurado corretamente
- ✅ Métricas de conexões funcionando
- ✅ Sem connection leaks
4. Exception Mapping com Exceções Tipadas
Status: Planejado
Prioridade: Média
Complexidade: Média
Estimativa: 2-3 dias
Objetivo
Criar exceções tipadas e mapeamento adequado para melhor tratamento de erros.
-
Criar Exceções Tipadas:
// Application/Exceptions/DomainException.cs public class DomainException : Exception { public DomainException(string message) : base(message) { } public DomainException(string message, Exception innerException) : base(message, innerException) { } } public class ValidationException : DomainException { public ValidationException(string message) : base(message) { } } public class NotFoundException : DomainException { public NotFoundException(string resource, object id) : base($"{resource} with ID {id} was not found.") { } } public class UnauthorizedException : DomainException { public UnauthorizedException(string message) : base(message) { } } -
Atualizar Exception Handler:
var statusCode = exception switch { ValidationException => StatusCodes.Status400BadRequest, NotFoundException => StatusCodes.Status404NotFound, UnauthorizedException => StatusCodes.Status401Unauthorized, ArgumentException => StatusCodes.Status400BadRequest, _ => StatusCodes.Status500InternalServerError }; -
Migração Gradual:
- Substituir
throw new Exception(...)por exceções tipadas - Atualizar services para usar exceções tipadas
- Manter compatibilidade com código existente
- Substituir
Critérios de Sucesso
- ✅ Exceções tipadas criadas
- ✅ Exception handler atualizado
- ✅ Migração gradual concluída
5. Validação Completa com Validators
Status: Planejado
Prioridade: Baixa
Complexidade: Baixa-Média
Estimativa: 3-5 dias
Objetivo
Criar validators para todos os requests críticos usando FluentValidation.
-
Auth:
SocialLoginRequestValidator
-
Territories:
TerritorySearchRequestValidatorTerritoryNearbyRequestValidatorTerritorySuggestionRequestValidator
-
Memberships:
DeclareMembershipRequestValidator
-
Feed:
CreatePostRequestValidator✅ (já existe)CreateCommentRequestValidatorFeedQueryRequestValidator
-
Events:
CreateEventRequestValidatorUpdateEventRequestValidator
-
Map:
CreateMapEntityRequestValidatorMapQueryRequestValidator
-
Moderation:
CreateReportRequestValidator
-
Marketplace:
CreateStoreRequestValidatorCreateListingRequestValidatorCreateInquiryRequestValidator
-
Criar Validators:
- Um validator por request crítico
- Mensagens de erro claras
- Validações de negócio quando necessário
-
Registrar Validators:
- Já configurado automaticamente via
AddValidatorsFromAssemblyContaining<Program>
- Já configurado automaticamente via
-
Testar Validators:
- Testes unitários para cada validator
- Testes de integração para validação end-to-end
Critérios de Sucesso
- ✅ Validators para todos os requests críticos
- ✅ Mensagens de erro claras
- ✅ Testes implementados
6. Concorrência Otimista
Status: Planejado (Pós-lançamento)
Prioridade: Baixa
Complexidade: Média-Alta
Estimativa: 3-5 dias
Objetivo
Implementar concorrência otimista para evitar perda de dados em alta concorrência.
Entidades a Atualizar
- CommunityPost
- TerritoryEvent
- MapEntity
- TerritoryMembership
-
Adicionar RowVersion:
public class CommunityPost { public byte[] RowVersion { get; set; } } -
Configurar no DbContext:
entity.Property(e => e.RowVersion) .IsRowVersion() .ValueGeneratedOnAddOrUpdate(); -
Tratar ConcurrencyException:
try { await _unitOfWork.CommitAsync(cancellationToken); } catch (DbUpdateConcurrencyException) { throw new DomainException("The entity was modified by another operation."); }
Critérios de Sucesso
- ✅ RowVersion em entidades críticas
- ✅ Tratamento de conflitos implementado
- ✅ Testes de concorrência
7. Distributed Tracing
Status: Planejado (Futuro)
Prioridade: Baixa
Complexidade: Alta
Estimativa: 1-2 semanas
Objetivo
Implementar distributed tracing quando houver múltiplos serviços.
Quando Implementar
- Quando houver separação de serviços (Auth, Feed, Map, etc.)
- Quando houver comunicação assíncrona entre serviços
- Quando precisar rastrear requests através de múltiplos serviços
Opções
- OpenTelemetry: Padrão da indústria, vendor-agnostic
- Jaeger: Open source, popular
- Zipkin: Open source, simples
- Application Insights: Azure, fácil integração
Recomendação
OpenTelemetry para flexibilidade e padrão da indústria.
8. Redis Cache
Status: Planejado (Futuro)
Prioridade: Baixa
Complexidade: Média
Estimativa: 3-5 dias
Objetivo
Implementar cache distribuído quando houver múltiplas instâncias da aplicação.
Quando Implementar
- Quando houver múltiplas instâncias da aplicação
- Quando cache in-memory não for suficiente
- Quando precisar compartilhar cache entre instâncias
-
Adicionar Redis:
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis -
Configurar Cache:
services.AddStackExchangeRedisCache(options => { options.Configuration = connectionString; options.InstanceName = "Arah:"; }); -
Migrar de IMemoryCache para IDistributedCache:
- Atualizar
TerritoryCacheService - Atualizar
FeatureFlagCacheService - Testar performance
- Atualizar
📊 Priorização
Alta Prioridade (Pós-lançamento Imediato)
- Índices de Banco de Dados - Melhora performance imediata
- Métricas Básicas - Necessário para monitoramento
- Exception Mapping - Melhora tratamento de erros
Média Prioridade (3-6 meses)
- Validação Completa - Melhora qualidade de dados
- Connection Pooling - Otimização
Baixa Prioridade (6-12 meses)
- Concorrência Otimista - Quando houver alta concorrência
- Distributed Tracing - Quando houver múltiplos serviços
- Redis Cache - Quando houver múltiplas instâncias
📝 Checklist de Implementação
Índices de Banco
- Análise de queries lentas
- Criar migration com índices
- Testar performance
- Validar em staging
- Deploy em produção
Métricas
- Escolher plataforma (Prometheus/Grafana)
- Adicionar pacotes NuGet
- Configurar métricas básicas
- Criar dashboards
- Configurar alertas
Connection Pooling
- Configurar pooling explicitamente
- Adicionar retry policies
- Monitorar conexões
- Documentar configuração
Exception Mapping
- Criar exceções tipadas
- Atualizar exception handler
- Migrar código existente
- Testar tratamento de erros
Validação Completa
- Listar requests críticos
- Criar validators
- Testar validators
- Documentar validações
Concorrência Otimista
- Identificar entidades críticas
- Adicionar RowVersion
- Configurar no DbContext
- Tratar ConcurrencyException
- Testar concorrência
Documento criado em: 2025-01-XX
Próxima revisão: Após lançamento em produção