Herramientas Recomendadas para Nexus Platform¶
Fecha: 2026-01-30 Estado: Pendiente de implementación Prioridad: Alta
Índice¶
- Resumen Ejecutivo
- Prioridad CRÍTICA
- Prioridad ALTA
- Prioridad MEDIA
- Detalles de Implementación
- Plan de Ejecución
Resumen Ejecutivo¶
Estado Actual de Gaps¶
| Área | Estado | Criticidad |
|---|---|---|
| Observabilidad | 40% | ALTA |
| Testing | 5% | CRÍTICA |
| CI/CD | 10% | CRÍTICA |
| Seguridad | 35% | CRÍTICA |
| Performance | 25% | ALTA |
| Base de Datos | 60% | ALTA |
Stack Recomendado¶
┌─────────────────────────────────────────────────────────────┐
│ STACK RECOMENDADO │
├─────────────────────────────────────────────────────────────┤
│ │
│ INMEDIATO (Esta semana): │
│ ├── Redis ────────────── Cache + SignalR backplane │
│ ├── Serilog ──────────── Structured logging │
│ └── xUnit ────────────── Testing framework │
│ │
│ CORTO PLAZO (2-4 semanas): │
│ ├── OpenTelemetry ────── Tracing distribuido │
│ ├── Polly ────────────── Resilience patterns │
│ ├── GitHub Actions ───── CI/CD pipeline │
│ └── Key Vault ────────── Secrets management │
│ │
│ MEDIANO PLAZO (1-2 meses): │
│ ├── Prometheus ───────── Métricas │
│ ├── Grafana ──────────── Dashboards │
│ ├── pgBackRest ───────── Database backups │
│ └── Semgrep ──────────── Security scanning │
│ │
└─────────────────────────────────────────────────────────────┘
Prioridad CRÍTICA¶
1. Redis¶
Propósito: Cache distribuido + SignalR backplane
Por qué es crítico: - SignalR no escala horizontalmente sin backplane - Memory leaks en diccionarios estáticos - Sin caché distribuido entre instancias - Rate limiting inexistente
Esfuerzo: 3-5 días Costo: Gratis (self-hosted) o ~$15-50/mes (managed)
Documentación: Ver docs/ANALISIS-REDIS.md
2. Serilog¶
Propósito: Structured logging
Por qué es crítico: - Logs actuales son texto plano, imposible buscar/filtrar - Sin correlación entre requests - Sin contexto de usuario/sesión en logs
Paquetes NuGet:
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="6.0.0" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.3.0" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
Implementación:
// Program.cs
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Enrich.WithEnvironmentName()
.Enrich.WithThreadId()
.WriteTo.Console(new JsonFormatter())
.WriteTo.File("logs/nexus-.log", rollingInterval: RollingInterval.Day)
.WriteTo.Seq("http://localhost:5341") // Opcional: Seq para búsquedas
.CreateLogger();
builder.Host.UseSerilog();
Esfuerzo: 4-8 horas Costo: Gratis (archivos) o ~$30/mes (Seq cloud)
3. xUnit + Testing Stack¶
Propósito: Testing framework
Por qué es crítico: - 0% de cobertura actual - Cualquier cambio puede romper funcionalidad sin saberlo - Deployments son "deploy and pray"
Paquetes NuGet:
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" />
<PackageReference Include="Moq" Version="4.20.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Testcontainers" Version="3.10.0" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
Estructura de proyectos:
tests/
├── Orchestrator.Api.Tests/
├── Orchestrator.Workers.Tests/
├── Shared.Admin.Tests/
└── Integration.Tests/
Prioridad de tests:
1. CopilotService - Lógica crítica, máquina de estados
2. ExecutionService - Parsing de output, creación de backlog
3. ClickUpSyncService - Integración externa compleja
4. DevSessionService - Core del producto
Esfuerzo: 2-4 semanas para cobertura básica (50%) Costo: Gratis
Prioridad ALTA¶
4. OpenTelemetry¶
Propósito: Tracing distribuido
Por qué es importante: - Sin visibilidad del flujo de requests entre servicios - Imposible diagnosticar latencia - No se puede identificar cuellos de botella
Paquetes NuGet:
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.12" />
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.5.1" />
Implementación:
// Program.cs
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService("Orchestrator.Api"))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddEntityFrameworkCoreInstrumentation()
.AddSource("Nexus.DevSession")
.AddSource("Nexus.Copilot")
.AddJaegerExporter(options =>
{
options.AgentHost = "localhost";
options.AgentPort = 6831;
}));
Docker Compose para Jaeger:
services:
jaeger:
image: jaegertracing/all-in-one:1.54
ports:
- "6831:6831/udp" # Agent
- "16686:16686" # UI
environment:
- COLLECTOR_OTLP_ENABLED=true
Esfuerzo: 1-2 días Costo: Gratis (Jaeger self-hosted) o ~$50/mes (Honeycomb, Datadog)
5. Polly¶
Propósito: Resilience patterns (retry, circuit breaker, timeout)
Por qué es importante: - APIs externas fallan (Claude, ClickUp, UltraMsg) - Sin retry automático - Sin circuit breaker (un servicio caído afecta todo)
Paquetes NuGet:
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="9.0.0" />
<PackageReference Include="Polly" Version="8.4.0" />
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
Implementación:
// Program.cs
builder.Services.AddHttpClient<IClaudeClient, ClaudeClient>()
.AddTransientHttpErrorPolicy(policy => policy
.WaitAndRetryAsync(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))))
.AddTransientHttpErrorPolicy(policy => policy
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));
builder.Services.AddHttpClient<IClickUpClient, ClickUpClient>()
.AddTransientHttpErrorPolicy(policy => policy
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)))
.AddTransientHttpErrorPolicy(policy => policy
.CircuitBreakerAsync(10, TimeSpan.FromMinutes(1)));
Políticas recomendadas:
| Servicio | Retry | Circuit Breaker | Timeout |
|---|---|---|---|
| Claude API | 3x con backoff exponencial | 5 fallos → 30s break | 120s |
| ClickUp API | 3x con 1s delay | 10 fallos → 60s break | 30s |
| UltraMsg | 2x | 5 fallos → 30s break | 10s |
Esfuerzo: 4-8 horas Costo: Gratis
6. GitHub Actions¶
Propósito: CI/CD pipeline
Por qué es importante:
- Directorio .github/workflows/ está vacío
- Deploys manuales con scripts PowerShell
- Sin validación automática de PRs
Workflow básico:
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Test
run: dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage"
- name: Upload coverage
uses: codecov/codecov-action@v4
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep Security Scan
uses: returntocorp/semgrep-action@v1
with:
config: p/csharp
deploy:
needs: [build, security]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to Production
run: echo "Add deployment steps here"
Esfuerzo: 1-2 días Costo: Gratis (2000 min/mes en GitHub Free)
7. Azure Key Vault / HashiCorp Vault¶
Propósito: Secrets management
Por qué es importante:
- Secretos hardcodeados en appsettings.json
- API keys visibles en el repositorio
- Sin rotación de secretos
Opción A - Azure Key Vault:
// Program.cs
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{vaultName}.vault.azure.net/"),
new DefaultAzureCredential());
// Los secretos se cargan automáticamente
var claudeApiKey = builder.Configuration["Claude:ApiKey"];
Opción B - Variables de entorno + Docker secrets:
# docker-compose.yml
services:
api:
environment:
- Claude__ApiKey=${CLAUDE_API_KEY}
- ClickUp__ApiToken=${CLICKUP_API_TOKEN}
secrets:
- claude_api_key
secrets:
claude_api_key:
file: ./secrets/claude_api_key.txt
Opción C - HashiCorp Vault:
// Program.cs
builder.Configuration.AddVault(options =>
{
options.Address = "http://localhost:8200";
options.Token = Environment.GetEnvironmentVariable("VAULT_TOKEN");
options.MountPoint = "secret";
options.SecretPath = "nexus";
});
Esfuerzo: 1-2 días Costo: Azure Key Vault ~$0.03/10K operaciones, Vault OSS gratis
Prioridad MEDIA¶
8. Prometheus + Grafana¶
Propósito: Métricas + Dashboards
Por qué es importante: - Sin métricas de negocio ni sistema - Sin visibilidad de salud de la plataforma - Sin alertas proactivas
Métricas recomendadas:
| Métrica | Tipo | Descripción |
|---|---|---|
nexus_executions_total |
Counter | Total de ejecuciones |
nexus_execution_duration_seconds |
Histogram | Latencia de ejecuciones |
nexus_devsession_messages_total |
Counter | Mensajes procesados |
nexus_claude_api_latency_seconds |
Histogram | Latencia de Claude API |
nexus_active_sessions |
Gauge | Sesiones activas |
nexus_backlog_items_pending |
Gauge | Items pendientes en backlog |
nexus_rabbitmq_queue_depth |
Gauge | Profundidad de colas |
Implementación:
// Program.cs
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation()
.AddPrometheusExporter());
app.MapPrometheusScrapingEndpoint("/metrics");
Docker Compose:
services:
prometheus:
image: prom/prometheus:v2.50.0
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana:10.3.0
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
Esfuerzo: 2-3 días Costo: Gratis (self-hosted)
9. pgBackRest¶
Propósito: Database backups automatizados
Por qué es importante: - Sin backups automatizados - Riesgo de pérdida total de datos - Sin disaster recovery plan
Docker Compose:
services:
pgbackrest:
image: pgbackrest/pgbackrest:latest
volumes:
- ./backups:/var/lib/pgbackrest
- ./pgbackrest.conf:/etc/pgbackrest/pgbackrest.conf
environment:
- PGBACKREST_STANZA=nexus
volumes:
backups:
Configuración (pgbackrest.conf):
[nexus]
pg1-path=/var/lib/postgresql/data
pg1-host=postgres
pg1-host-user=postgres
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=7
repo1-retention-diff=14
start-fast=y
stop-auto=y
Política de backups: - Full backup: Diario a las 3 AM - Incremental: Cada 6 horas - Retención: 7 días full, 14 días differential - Test de restore: Semanal (automatizado)
Esfuerzo: 4-8 horas Costo: Solo almacenamiento (~$5/mes para 50GB)
10. Semgrep¶
Propósito: SAST security scanning
Por qué es importante: - Sin escaneo automático de vulnerabilidades - Secretos en código fuente - Posibles vulnerabilidades de inyección
GitHub Action:
# .github/workflows/security.yml
name: Security Scan
on:
push:
branches: [main, develop]
pull_request:
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep Scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/csharp
p/owasp-top-ten
p/secrets
generateSarif: true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
Reglas recomendadas:
- p/csharp - Reglas específicas de C#
- p/owasp-top-ten - OWASP Top 10
- p/secrets - Detección de secretos
- p/sql-injection - SQL Injection
Esfuerzo: 2-4 horas Costo: Gratis (open source)
Plan de Ejecución¶
Semana 1: Fundamentos¶
- [ ] Día 1-2: Redis (ver
docs/ANALISIS-REDIS.md) - Docker compose
- SignalR backplane
- IDistributedCache
- [ ] Día 3: Serilog
- Configuración básica
- Sinks (Console, File)
- Enrichers
- [ ] Día 4-5: GitHub Actions básico
- Build workflow
- Security scan con Semgrep
Semana 2: Resilience + Testing¶
- [ ] Día 1-2: Polly
- Retry policies para APIs externas
- Circuit breakers
- [ ] Día 3-5: xUnit setup
- Estructura de proyectos de test
- Tests para CopilotService
- Tests para ExecutionService
Semana 3: Observabilidad¶
- [ ] Día 1-2: OpenTelemetry
- Tracing para API
- Jaeger setup
- [ ] Día 3-4: Prometheus + Grafana
- Métricas básicas
- Dashboard inicial
- [ ] Día 5: Key Vault
- Migrar secretos
- Actualizar configuración
Semana 4: Database + Polish¶
- [ ] Día 1-2: pgBackRest
- Configuración de backups
- Test de restore
- [ ] Día 3-5: Completar tests
- ClickUpSyncService
- DevSessionService
- Integration tests
Costos Estimados¶
Self-Hosted (Mínimo)¶
| Herramienta | Costo Mensual |
|---|---|
| Redis | $0 (Docker) |
| Serilog | $0 (archivos) |
| xUnit | $0 |
| OpenTelemetry + Jaeger | $0 (Docker) |
| Polly | $0 |
| GitHub Actions | $0 (2000 min gratis) |
| Prometheus + Grafana | $0 (Docker) |
| pgBackRest | ~$5 (almacenamiento) |
| Semgrep | $0 |
| Total | ~$5/mes |
Managed Services (Recomendado para producción)¶
| Herramienta | Costo Mensual |
|---|---|
| Redis (Azure Cache) | ~$15-50 |
| Seq (logging) | ~$30 |
| Honeycomb (tracing) | ~$50 |
| Azure Key Vault | ~$5 |
| Codecov | $0 (open source) |
| Total | ~$100-135/mes |
Checklist de Implementación¶
Crítico¶
- [ ] Redis implementado
- [ ] Serilog configurado
- [ ] Proyecto de tests creado
- [ ] Al menos 10 tests escritos
Alta Prioridad¶
- [ ] OpenTelemetry funcionando
- [ ] Polly en todos los HttpClients
- [ ] GitHub Actions CI pipeline
- [ ] Secretos movidos a Key Vault
Media Prioridad¶
- [ ] Prometheus exportando métricas
- [ ] Grafana con dashboard básico
- [ ] pgBackRest con backups diarios
- [ ] Semgrep en CI pipeline
- [ ] Cobertura de tests > 50%
Documento generado como parte de la auditoría de arquitectura de Nexus Platform Última actualización: 2026-01-30