Este es un sistema de Remote Spotify Player para aplicaciones DJ construido con arquitectura orientada a eventos. El proyecto permite controlar Spotify remotamente desde consolas DJ y aplicaciones como Rekordbox, con sincronización en tiempo real entre múltiples dispositivos. El proyecto utiliza:
- Frontend: React 18+ con Vite como build tool y TypeScript para UI de control DJ
- Backend: Python 3.12+ con FastAPI para microservicios
- Cloud Platform: Google Cloud Platform (GCP) con servicios serverless
- Event-Driven Architecture: Comunicación asíncrona entre servicios con Cloud Pub/Sub
- Real-time Sync: Cloud Firestore para sincronización de estado de playback (<100ms latency)
- Spotify Integration API - Autenticación OAuth y comunicación con Spotify Web API
- Playback Control API - Control de reproducción (play, pause, volume, seek)
- Sync Service - Sincronización en tiempo real del estado de playback vía Firestore
- DJ Console Integration API - Integración con controladores MIDI/HID y hardware DJ
- Eventos Asíncronos: Para comunicación entre servicios (Cloud Pub/Sub)
- REST APIs: Para comunicación síncrona (FastAPI endpoints)
- Real-time Sync: Cloud Firestore para estado de playback en tiempo real
- OAuth 2.0: Para autenticación con Spotify
Regla de Oro: Todo componente debe ser observable. La observabilidad no es opcional.
Criterio de "Done": Una funcionalidad solo está completa cuando tiene:
- ✅ Traces: Instrumentación con OpenTelemetry en operaciones críticas
- ✅ Metrics: RED metrics (Rate, Errors, Duration) + métricas de negocio
- ✅ Logs: Logs estructurados en JSON con trace context
- ✅ Dashboard: Visualizaciones en Grafana
- ✅ Alerts: Alertas configuradas para errores críticos
- ✅ Tests: Tests de observabilidad (metrics, traces, logs)
Stack Open-Source Obligatorio:
- OpenTelemetry (instrumentación unificada)
- Prometheus (métricas y alerting)
- Grafana (visualización)
- Jaeger (distributed tracing)
- Loki (log aggregation)
Ver: ADR-010: Observability-First Architecture y Observability Best Practices
- Cada servicio debe ser independiente y autónomo
- Base de datos por servicio (Database per Service pattern)
- Desacoplamiento mediante eventos
- Sin dependencias directas entre servicios
- Event Sourcing: Considerar para servicios que requieren auditoría completa
- CQRS: Separación de comandos y consultas donde tenga sentido
- Saga Pattern: Para transacciones distribuidas
- Event Notification: Para notificar cambios de estado
- Circuit Breaker para llamadas externas
- Retry policies con backoff exponencial
- Timeouts apropiados
- Health checks en todos los servicios
- Eventos: PasadoTense + Sufijo "Event" (ej:
UserAuthenticatedEvent,PlaybackStateChangedEvent) - Comandos: Imperativo + Sufijo "Command" (ej:
StartPlaybackCommand,RefreshTokenCommand) - Handlers: Nombre del mensaje + "Handler" (ej:
UserAuthenticatedEventHandler,MIDICommandHandler) - Servicios: Sustantivo + "Service" (ej:
SpotifyService,PlaybackService,SyncService) - Variables/Funciones: snake_case (ej:
get_playback_state,refresh_spotify_token) - Clases: PascalCase (ej:
SpotifyUser,PlaybackRepository,MIDIDevice) - Constantes: UPPER_SNAKE_CASE (ej:
MAX_RETRY_ATTEMPTS,SPOTIFY_API_TIMEOUT)
- Componentes: PascalCase (ej:
PlaybackControls,TrackDisplay,VolumeSlider) - Hooks: camelCase con prefijo "use" (ej:
useSpotifyPlayer,usePlaybackState,useMIDIDevice) - Funciones: camelCase (ej:
startPlayback,handleVolumeChange,syncPlaybackState) - Interfaces/Types: PascalCase con prefijo "I" o sufijo "Props" (ej:
ITrack,PlaybackControlsProps) - Constantes: UPPER_SNAKE_CASE (ej:
SPOTIFY_API_BASE_URL,MAX_VOLUME)
services/
├── {service-name}/
│ ├── app/
│ │ ├── api/ # FastAPI endpoints (routers)
│ │ ├── core/ # Configuration, settings
│ │ ├── application/ # Use cases, command/query handlers
│ │ ├── domain/ # Domain models, business logic
│ │ ├── infrastructure/ # DB, messaging, external services
│ │ ├── events/ # Event schemas and handlers
│ │ ├── schemas/ # Pydantic request/response models
│ │ └── main.py # FastAPI application entry point
│ ├── tests/
│ │ ├── unit/
│ │ ├── integration/
│ │ └── conftest.py
│ ├── pyproject.toml # Python dependencies (Poetry)
│ └── .copilot-context.md
frontend/
├── src/
│ ├── components/ # Reusable React components
│ │ ├── common/ # Shared components
│ │ └── features/ # Feature-specific components
│ ├── pages/ # Page components (routes)
│ ├── hooks/ # Custom React hooks
│ ├── services/ # API clients
│ ├── stores/ # State management (Zustand)
│ ├── types/ # TypeScript types
│ ├── utils/ # Utility functions
│ └── App.tsx
├── tests/
└── vite.config.ts
- React 18+: UI library con hooks y concurrent features
- Vite 5+: Build tool con HMR ultra-rápido
- TypeScript 5+: Type safety
- React Router v6: Client-side routing
- TanStack Query: Server state management
- Zustand: Client state management
- Tailwind CSS: Utility-first styling
- shadcn/ui: Component library
- Vitest: Testing framework
- React Testing Library: Component testing
- Python 3.12+: Latest stable version
- FastAPI: Modern async web framework
- Uvicorn: ASGI server
- Pydantic v2: Data validation with type hints
- SQLAlchemy 2.0: ORM asíncrono
- Alembic: Database migrations
- aio-pika: RabbitMQ async client
- pytest: Testing framework
- structlog: Structured logging
- black: Code formatting
- ruff: Fast linting
- mypy: Static type checking
- PostgreSQL: Base de datos principal (database per service)
- RabbitMQ: Message broker para eventos
- Redis: Caché distribuido
- Docker: Containerization
- Docker Compose: Local development orchestration
- npm packages para componentes React compartidos
- Shared utilities y types
- Common API client configurations
- Python packages (pip/poetry) para código compartido
- Event contracts y schemas compartidos
- Common middleware y utilities
- NO crear dependencias directas entre microservicios
- NO compartir bases de datos entre servicios
- NO hacer llamadas síncronas si se puede usar eventos
- NO incluir lógica de negocio en controladores
- NO exponer entidades de dominio directamente
- SÍ usar DTOs/Schemas para todas las APIs
- SÍ validar eventos y comandos
- SÍ implementar idempotencia en handlers
- SÍ usar logging estructurado
- SÍ documentar todos los eventos publicados/consumidos
- SÍ instrumentar TODOS los servicios con OpenTelemetry (traces, metrics, logs)
- SÍ exponer métricas RED (Rate, Errors, Duration) en
/metrics - SÍ usar logs estructurados JSON con correlation_id, trace_id, span_id
- SÍ propagar trace context en HTTP headers y eventos
- SÍ crear dashboards en Grafana para cada servicio
- SÍ configurar alertas en Prometheus para errores críticos
- SÍ implementar
/healthendpoint con dependency checks - SÍ escribir tests de observabilidad (metrics, traces, logs)
- SÍ documentar métricas en README del servicio
- SÍ documentar APIs con OpenAPI/Swagger en
/docsy/redoc(Backend) - SÍ documentar componentes con Storybook (Frontend)
- SÍ usar type hints en todas las funciones
- SÍ usar async/await para operaciones I/O
- SÍ usar Pydantic para validación de datos
- SÍ implementar health checks en todos los servicios
- SÍ seguir Clean Architecture (domain, application, infrastructure)
- SÍ usar black + ruff para formateo consistente
- SÍ usar pytest con fixtures para testing
- SÍ usar structlog para logs estructurados
- SÍ instrumentar con @tracer.start_as_current_span() operaciones críticas
- SÍ documentar todos los endpoints con docstrings y ejemplos
- SÍ usar Pydantic Field() con descriptions para modelos
- SÍ usar TypeScript strict mode
- SÍ usar React hooks (useState, useEffect, useCallback, etc.)
- SÍ implementar error boundaries
- SÍ usar React Query para server state
- SÍ implementar code splitting con React.lazy
- SÍ usar Tailwind para estilos
- SÍ seguir principios de composición sobre herencia
- SÍ documentar componentes públicos con Storybook
- SÍ usar JSDoc/TSDoc para documentar props
- Unit tests: Para lógica de dominio (pytest)
- Integration tests: Para event handlers y database
- Contract tests: Para eventos compartidos
- API tests: Para endpoints FastAPI (httpx + TestClient)
- Observability tests: Para metrics, traces, logs estructurados ✅
- Coverage: Mínimo 80% de cobertura
- Unit tests: Para hooks y utilities (Vitest)
- Component tests: Para componentes React (Testing Library)
- Integration tests: Para flujos completos
- E2E tests: Para user journeys críticos (Playwright - opcional)
- Coverage: Mínimo 70% de cobertura
- Metric emission tests: Verificar que métricas se emiten correctamente
- Span creation tests: Verificar que spans se crean para operaciones
- Structured log tests: Verificar formato JSON y campos obligatorios
- Context propagation tests: Verificar trace context se propaga
- Health check tests: Verificar endpoint
/healthresponde correctamente
Cuando trabajes en este proyecto, siempre considera:
- Documentar eventos: Cada evento debe estar documentado en
docs/events/ - Diagramas de flujo: Para sagas y procesos complejos
- ADRs: Para decisiones arquitectónicas importantes
- README: Cada servicio debe tener su propio README
Referencia los scripts y comandos específicos en cada servicio's README.
Este proyecto utiliza metodología Kanban para gestión continua del flujo de trabajo.
- BACKLOG.md: Backlog principal con todas las historias de usuario
- Historias en formato: "Como... Quiero... Para..."
- Priorizadas por valor de negocio usando RICE framework
- Límites WIP: In Progress (5), In Review (3)
- To Do: Historias priorizadas y refinadas, listas para trabajarse
- In Progress: En desarrollo activo (máximo 5 simultáneas)
- In Review: En code review o QA (máximo 3 simultáneas)
- Done: Completadas y en producción
- Usa plantilla en
docs/backlog-template.md - Formato de historia de usuario con criterios de aceptación
- Estima con Story Points (1, 2, 3, 5, 8, 13)
- Asigna prioridad y Epic
- Agrega a
BACKLOG.mden sección correspondiente
- Manual de Product Owner:
/docs/guides/product-owner-guide.md - Guía de Kanban:
/docs/guides/kanban-guide.md - Plantilla de historia:
/docs/backlog-template.md
Este proyecto implementa un sistema automatizado para convertir ideas en tareas ejecutables en ClickUp.
- IDEAS.md: Archivo centralizado para capturar ideas rápidas
- Formato simple: Contexto, Problema, Valor, Prioridad (🔴/🟡/🟢/💭)
- No requiere formato perfecto - lo importante es capturar la esencia
- Las ideas se refinan periódicamente a historias de usuario formales
IDEAS.md → BACKLOG.md → Technical Tasks → ClickUp
💡 📋 ⚙️ ✅
Cuando el Product Owner solicite crear tareas para un sprint, Copilot debe:
-
Analizar prioridades en
BACKLOG.md:- Identificar user stories en "High Priority" con estado "To Do"
- Considerar story points y dependencias
- Sugerir cuáles incluir en el sprint basado en capacidad del equipo
-
Descomponer US en tareas técnicas:
- Cada user story genera 2-5 tareas dependiendo de complejidad
- Usar nomenclatura
TASK-XXX(secuencial) - Tareas en inglés usando formato de
docs/task-template.md
-
Para cada tarea, generar:
- Description: Technical scope, archivos a modificar, dependencias
- Functional Acceptance Criteria: 4-6 criterios orientados a negocio/usuario
- Technical Acceptance Criteria: Code quality, performance, security, testing, observability
- Best Practices to Apply: Checklist detallado de:
- Architecture (Clean Architecture, CQRS, Repository pattern)
- Code Quality (SOLID, meaningful names, small methods)
- Event-Driven (idempotency, correlation IDs, outbox pattern, versioning)
- Resilience (circuit breaker, retry policies, timeouts)
- Security (input validation, parameterized queries, no sensitive data in logs)
- Testing (TDD, unit tests, integration tests, contract tests)
- Observability (structured logging, metrics, health checks, correlation IDs)
- Recommendations: Before/During/After implementation tips
- Testing Strategy: Unit, integration, manual testing checklist
- Related Resources: Links a docs, ADRs, event specs, service context
- Definition of Done: Checklist completo
-
Presentar preliminar para revisión:
- Mostrar resumen de tareas generadas (sprint overview)
- Permitir revisar cada tarea una por una
- Aceptar modificaciones antes de aprobar
- NO crear tareas en ClickUp sin aprobación explícita del PO
-
Workflow de revisión iterativa:
PO: "Muéstrame TASK-001 completa" Copilot: [Despliega tarea completa con todos los detalles] PO: "Modifica TASK-001 - agrega AC sobre logging de errores" Copilot: [Actualiza TAC y muestra cambio] PO: "Aprobada. Siguiente tarea." Copilot: [Muestra TASK-002...] -
Después de aprobar todas:
- Generar archivo
sprint-X-tasks.mdcon todas las tareas aprobadas - Proveer instrucciones para crear en ClickUp (manual o API)
- Actualizar BACKLOG.md marcando US como "In Progress"
- Generar archivo
Cuando el PO solicite:
-
"Genera tareas para el próximo sprint basado en prioridades" → Analizar BACKLOG.md, identificar High Priority, descomponer en tareas técnicas
-
"Crea tareas preliminares para US-XXX" → Generar 2-5 tareas técnicas para esa user story específica
-
"Muéstrame TASK-XXX completa" → Desplegar tarea completa con todos los detalles del template
-
"Modifica TASK-XXX: [instrucción]" → Actualizar tarea según instrucción y mostrar cambio
-
"Aprobada. Siguiente tarea." → Marcar como aprobada y mostrar siguiente tarea del sprint
-
"Exporta tareas aprobadas para ClickUp" → Generar archivo
sprint-X-tasks.mdcon formato ClickUp-compatible
- Plantilla de tarea:
/docs/task-template.md - Flujo completo:
/docs/guides/idea-to-task-flow.md - Captura de ideas:
/IDEAS.md
- Tareas en inglés: Para colaboración internacional
- Revisión una por una: PO debe aprobar cada tarea individualmente
- Best practices incluidas: Cada tarea tiene checklist de arquitectura, seguridad, testing
- Contexto completo: Links a docs, eventos, ADRs relevantes
- Criterios claros: Functional + Technical ACs bien definidos
- Recomendaciones prácticas: Tips before/during/after implementation
- Documentación arquitectónica:
/docs/architecture/ - Catálogo de eventos:
/docs/events/ - Guías de desarrollo:
/docs/guides/ - ADRs:
/docs/adr/ - Backlog del proyecto:
/BACKLOG.md