ADR-002: Reemplazo de CQRS/CommandBus por Orchestrator¶
Estado¶
Aceptada
Fecha¶
2025-01-15
Contexto¶
El backend original implementaba el patrón CQRS (Command Query Responsibility Segregation) con un CommandBus para procesar acciones del usuario.
Problemas identificados:¶
- Sobre-ingeniería: Para un sistema con ~10 comandos, el overhead de CQRS era desproporcionado
- Indirección excesiva: Command → CommandBus → Handler → Result → Response
- Boilerplate: Cada nueva funcionalidad requería crear Command DTO + Handler + registrar en bus
- Debugging complejo: Stack traces profundos oscurecían el flujo real
- Testing verbose: Mocks de CommandBus en cada test
Requisitos:¶
- Mantener separación de concerns (no acoplar API a infraestructura)
- Simplificar el flujo de control
- Reducir boilerplate para nuevas features
- Facilitar testing y debugging
Decisión¶
Reemplazar CQRS/CommandBus por un Orchestrator central que coordina el flujo de trabajo directamente.
Implementación:¶
class Orchestrator:
async def toggle(self) -> ToggleResponse: ...
async def start(self) -> ToggleResponse: ...
async def stop(self) -> ToggleResponse: ...
El Orchestrator:
- Expone métodos directos para cada operación
- Coordina adaptadores (AudioRecorder, WhisperAdapter, LLMProvider)
- Mantiene el estado del sistema
- Emite eventos a WebSocket clients
Consecuencias¶
Positivas¶
- ✅ Flujo explícito: API → Orchestrator → Adapters (3 capas vs 6+)
- ✅ Menos código: Eliminamos ~500 LOC de CommandBus infrastructure
- ✅ Debugging simple: Stack traces claros y cortos
- ✅ Testing directo: Mockeamos adaptadores, no buses abstractos
- ✅ Onboarding: Nuevos devs entienden el sistema en minutos
Negativas¶
- ⚠️ Menos extensible: Agregar un "middleware" global es menos trivial
- ⚠️ Orchestrator "god object": Riesgo de que crezca demasiado (mitigado con composición)
Alternativas Consideradas¶
Mantener CQRS simplificado¶
- Rechazado: Incluso simplificado, el overhead conceptual no se justificaba.
Event Sourcing¶
- Rechazado: Sobre-ingeniería aún mayor para el caso de uso actual.
Simple Functions (sin clase)¶
- Rechazado: Perdíamos gestión de estado y lifecycle.