Plataforma de gestión empresarial modular, event-driven y AI-native para PYMEs.
- Overview
- Stack técnico
- Módulos implementados
- Estructura del repositorio
- Inicio rápido
- Desarrollo sin Docker
- Tests
- Migraciones de base de datos
- Deploy en producción
- Variables de entorno
- Documentación
CBOS es una plataforma de gestión empresarial composable: cada capacidad de negocio — CRM, ventas, inventario, facturación, portal del cliente — es un módulo independiente que se integra mediante un bus de eventos común. Las empresas activan las capacidades que necesitan, no un paquete rígido.
El sistema está construido como un monolito modular con límites de dominio explícitos — no microservicios prematuros. El event bus (Redis Streams) desacopla los módulos y alimenta el motor de workflows y las notificaciones en tiempo real. La IA (Anthropic Claude API) es infraestructura transversal disponible para cualquier módulo, no un addon.
Estado actual: MVP operativo en producción — 9 módulos Tier 1 + analytics cross-módulo cubriendo el flujo completo:
Discovery → Lead → Opportunity → Quote → Order → Inventory → Portal → Invoice → Payment
979 tests (contrato + integración + e2e) en 51 archivos. Dashboard con datos reales (facturación, pipeline CRM, operaciones).
| Capa | Tecnología | Versión |
|---|---|---|
| Frontend | React + TypeScript + Vite + Tailwind CSS + shadcn/ui | 18.3 / 5.x / 7.3 |
| Backend | FastAPI + SQLAlchemy (async) + asyncpg | Python 3.12 |
| Base de datos | PostgreSQL + Alembic (migrations) | 16 |
| Cache / Events | Redis Streams | 7 |
| Proxy local | Nginx | 1.27-alpine |
| Deploy | Docker Compose + Dokploy (Traefik + Let's Encrypt) | — |
Frontend adicional: TanStack React Query 5, React Router 6, React Hook Form + Zod, Zustand, Recharts, Sonner.
9 módulos Tier 1 + 1 módulo Tier 2 en backend/app/modules/:
| Módulo | Descripción | Tests | Tier |
|---|---|---|---|
| Identity | Auth JWT, registro, usuarios, workspaces, roles | Contract + integration | 1 |
| CRM | Leads, Opportunities (kanban: new → qualified → proposal → negotiation → won/lost), Activities | Contract + integration + e2e | 1 |
| Sales | Cotizaciones con líneas, SalesOrders, conversión Quote → Order | Contract + integration + e2e | 1 |
| Inventory | Catálogo de productos, stock por ubicación, movimientos, reservas, alertas de stock bajo | Contract + integration | 1 |
| Portal | Portal del cliente: cotizaciones públicas, aceptación vía token, sesiones | Contract + integration + e2e | 1 |
| Discovery | Solution Discovery AI — diagnóstico de necesidades vía Anthropic Claude API, blueprints | Contract + integration + e2e | 1 |
| Workflows | Motor de automatización event-driven (Redis Streams), acciones condicionales, DLQ | Contract + integration + consumer | 1 |
| Notifications | Email transaccional + WebSocket tiempo real, preferencias por usuario | Contract + integration + e2e pipeline | 1 |
| Accounting | Facturación completa: invoices, pagos parciales/totales, auto-invoice, overdue scanner | Contract + integration + e2e | 1 |
| Contracts | Gestión de contratos: state machine, cláusulas, eventos de ciclo de vida | Contract + integration (41 tests) | 1 |
| Projects | Gestión de proyectos: state machine, tareas, eventos de ciclo de vida | Contract + integration (44 tests) | 1 |
| HR/Team | Empleados, departamentos, state machine (activo/permiso/terminado) | Contract + integration (48 tests) | 1 |
Cross-módulo:
- Analytics — 3 endpoints de agregación (summary, revenue time-series, pipeline breakdown). 24 tests.
- Event bus — 19+ tipos de eventos, consumers dedicados (workflow, invoice, notification).
Documentación detallada por módulo: docs/capabilities/.
cbos-platform/
├── backend/ FastAPI modular monolith (Python 3.12)
│ ├── app/
│ │ ├── core/ Config, deps, middleware, event bus, security
│ │ ├── events/ Bus de eventos (Redis Streams), tipos de eventos
│ │ ├── modules/ 9 módulos de negocio + analytics
│ │ │ ├── identity/ Auth, usuarios, workspaces
│ │ │ ├── crm/ Leads, opportunities, activities
│ │ │ ├── sales/ Quotes, sales orders
│ │ │ ├── inventory/ Productos, stock, movimientos
│ │ │ ├── portal/ Portal del cliente
│ │ │ ├── discovery/ Discovery AI (Anthropic)
│ │ │ ├── workflows/ Motor de automatización
│ │ │ ├── notifications/ Email + WebSocket
│ │ │ ├── accounting/ Facturación, pagos, overdue scanner
│ │ │ └── analytics/ Agregación cross-módulo
│ │ └── main.py Lifespan, routers, CORS, background tasks
│ ├── tests/ 979 tests (pytest-asyncio)
│ ├── alembic/ Migraciones de base de datos
│ └── requirements.txt
├── composable-os/ React 18 + Vite frontend
│ └── src/
│ ├── pages/ 10 páginas activas (Dashboard, CRM, Sales, Inventory…)
│ ├── services/ API clients (fetch + React Query)
│ ├── components/ shadcn/ui + componentes custom
│ └── lib/ Auth, API wrapper, utilidades
├── nginx/
│ ├── local-http.conf Dev HTTP (activo por defecto via override)
│ └── local-ssl.conf Dev SSL (requiere mkcert -install)
├── docs/ Arquitectura, ADRs, specs de capacidades
│ ├── adr/ 12 Architecture Decision Records
│ └── capabilities/ Spec por módulo (9 archivos)
├── .github/workflows/ci.yml CI pipeline (pytest en push/PR)
├── docker-compose.yml Servicios base compartidos
├── docker-compose.override.yml Dev local (auto-merge, HTTP, puerto 80)
└── docker-compose.prod.yml Producción (Dokploy)
Docker Compose override:
docker-compose.override.ymlse fusiona automáticamente condocker-compose.yml. Activa modo HTTP local, expone puerto 80 y configuraVITE_API_URL. Para producción, Dokploy usadocker-compose.prod.ymlde forma explícita.
- Docker Desktop (o Docker Engine + Compose plugin)
- Git
git clone https://github.com/keilynrp/cbos-platform.git
cd cbos-platform
cp .env.example .env # defaults funcionan para dev — no requiere editar
docker compose up --build
# Primera vez: aplicar migraciones
docker compose exec backend alembic upgrade headAbrir http://localhost — la app está lista.
El repositorio versiona sus hooks en .githooks/. Git no los activa solo, así
que hay que apuntarlo ahí una vez por clon:
git config core.hooksPath .githooksInstala un pre-push que rechaza escrituras directas sobre master, forzando
el flujo de rama + Pull Request. No es una medida de seguridad —se puede saltar
con git push --no-verify— sino un portero contra el despiste: GitHub no ofrece
protecciones de rama del lado del servidor en repositorios privados del plan
gratuito.
| Servicio | URL |
|---|---|
| App (Frontend + API via nginx) | http://localhost |
| Backend API directo | http://localhost:8000 |
| Swagger / API Docs | http://localhost:8000/docs |
| ReDoc | http://localhost:8000/redoc |
| Health check | http://localhost:8000/health |
| PostgreSQL | localhost:5433 |
| Redis | localhost:6380 |
Los puertos de PostgreSQL (5433) y Redis (6380) están desplazados para evitar conflictos con instancias locales. Configurables en
.envvíaPOSTGRES_PORTyREDIS_PORT.
Solo postgres y redis corren en contenedores; backend y frontend corren como
procesos nativos. Es el mismo modelo que usa el CI, y evita los bind mounts
Windows→WSL, que son el principal cuello de botella en máquinas modestas.
Recomendado si el stack completo en Docker te resulta lento.
cp backend/.env.example backend/.env # config del runtime nativo
./scripts/dev-native.sh deps # postgres + redis
./scripts/dev-native.sh backend # migra y arranca uvicorn :8100
./scripts/dev-native.sh frontend # Vite con HMR :8101backend y frontend son procesos en primer plano — cada uno en su terminal.
Para levantar todo junto en una sola: ./scripts/dev-native.sh all.
El script instala dependencias solo cuando requirements.txt o
package-lock.json cambiaron, así que los arranques posteriores son inmediatos.
| Servicio | URL |
|---|---|
| Frontend (Vite + HMR) | http://localhost:8101 |
| Backend API | http://localhost:8100 |
| Swagger / API Docs | http://localhost:8100/docs |
| Health check | http://localhost:8100/health |
En este modo no hay nginx: el frontend llama al backend directamente y CORS lo autoriza vía
ALLOWED_ORIGINSenbackend/.env. El script exportaVITE_API_URLautomáticamente.
Suite de integración con pytest-asyncio contra una base de datos PostgreSQL real (cbos_test).
# Con Docker (recomendado)
docker compose exec backend pytest --tb=short -q
# Local
cd backend && pytest --tb=short -q979 tests en 51 archivos. Las categorías no se solapan: cada archivo cuenta una sola vez y las filas suman 41.
| Categoría | Archivos | Cobertura |
|---|---|---|
| Contract tests | 11 archivos (test_*_contract.py) |
Auth guards, lifecycle, workspace isolation y forma del error por módulo |
| Integration tests | 18 archivos | Flows de servicio y lógica de negocio, incluidos contracts, projects y HR |
| E2E cross-module | 5 archivos (test_e2e_*.py) |
Sales→Accounting, Portal→WS, Discovery→Blueprint, Notification pipeline |
| Consumer / scanner | 3 archivos | Workflow consumer, invoice consumer, overdue scanner |
| Analytics | 2 archivos | Summary, revenue, pipeline: auth, shape, workspace isolation, empty state |
| Smoke | 1 archivo (test_wedge_smoke.py) |
Funnel completo: CRM→Sales→Inventory→Portal→Accounting (7 módulos) |
| Unit (funciones puras) | 1 archivo (test_locale_resolution.py) |
Resolución de locale (ADR 0016): normalización, orden de resolución y Accept-Language; no toca base ni HTTP |
# Cobertura detallada
docker compose exec backend pytest --tb=short -vcd composable-os
npm test # unitarios con vitest (jsdom), sin dependencias externas
npm run test:e2e # end to end con Playwright, requiere el stack levantadoLos e2e no levantan la aplicación: esperan que docker compose up -d ya la esté
sirviendo, porque los flujos que cubren cruzan al backend y a la base de datos.
La primera corrida necesita el navegador (npx playwright install chromium) y
crea un workspace de pruebas e2e-company-profile en la base de desarrollo, que
las corridas siguientes reutilizan en lugar de acumular. Para apuntar a otro
entorno, E2E_BASE_URL=https://... npm run test:e2e.
Cubren lo que ninguna otra capa puede comprobar: que el validador de logo rechace un archivo grande sin llegar a la red, y que los estados de carga y de error se rendericen. El contenido de los PDF se afirma en el backend, que extrae el texto renderizado con pypdf.
CBOS usa Alembic para gestionar el esquema de PostgreSQL.
# Aplicar migraciones pendientes
docker compose exec backend alembic upgrade head
# Nueva migración tras cambiar modelos
docker compose exec backend alembic revision --autogenerate -m "descripcion_del_cambio"
# Ver historial
docker compose exec backend alembic history
# Revertir la última
docker compose exec backend alembic downgrade -1Las migraciones se generan en backend/alembic/versions/. Revisar siempre el archivo generado antes de aplicar en producción.
CBOS se despliega en un VPS vía Dokploy, que gestiona SSL (Let's Encrypt) y el reverse proxy (Traefik) automáticamente.
- Conectar el repositorio en el panel de Dokploy
- Seleccionar
docker-compose.prod.ymlcomo compose file - Configurar las variables de entorno en el panel
- Dokploy gestiona certificados SSL y dominios automáticamente
| Variable | Default | Descripción |
|---|---|---|
POSTGRES_DB |
cbos_dev |
Base de datos |
POSTGRES_USER |
cbos |
Usuario PostgreSQL |
POSTGRES_PASSWORD |
cbos_dev_pass |
Contraseña PostgreSQL |
POSTGRES_PORT |
5433 |
Puerto local PostgreSQL |
REDIS_PORT |
6380 |
Puerto local Redis |
SECRET_KEY |
dev-secret-key-... |
Firma JWT — cambiar en producción |
ENVIRONMENT |
development |
development / production |
ALLOWED_ORIGINS |
["http://localhost", ...] |
CORS — lista JSON |
ANTHROPIC_API_KEY |
— | API key de Anthropic (módulo Discovery) |
| Variable | Descripción |
|---|---|
POSTGRES_PASSWORD |
Contraseña segura para PostgreSQL |
REDIS_PASSWORD |
Contraseña segura para Redis |
SECRET_KEY |
String aleatorio, mínimo 32 caracteres |
DOMAIN |
Dominio de producción (nginx enruta /api/ → backend, / → frontend) |
ANTHROPIC_API_KEY |
Requerido para Discovery AI |
FROM_EMAIL |
Remitente para notificaciones |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASSWORD |
Config SMTP para email transaccional |
docs/
├── FOUNDATIONAL_ARCHITECTURE.md Arquitectura y principios de diseño
├── CAPABILITY_MATRIX_MVP.md Matriz de capacidades del MVP
├── CAPABILITY_MATURITY_SCORECARD.md Scorecard de madurez por módulo
├── API_CONVENTIONS.md Convenciones de la API REST
├── I18N_CONVENTIONS.md Cómo escribir y revisar cadenas traducibles
├── EVENT_REGISTRY_V1.md Catálogo de eventos del sistema (14+ tipos)
├── Q4_2026_SPRINT_PLAN.md Sprint plan actual (G2, G6, E1 — cerrado)
├── IMPLEMENTATION_ALIGNMENT.md Alineación entre plan e implementación
├── adr/ 12 Architecture Decision Records
│ ├── 0001 Modular monolith for MVP
│ ├── 0002 Freeze MVP stack
│ ├── 0003 Commercial operations wedge
│ ├── 0004 Events as versioned domain contracts
│ ├── 0005 Bound frontend to owned capabilities
│ ├── 0006 Promote Portal to Tier 2
│ ├── 0007 Sales-Inventory boundary via Gateway
│ ├── 0008 Promote Discovery + Accounting to Tier 2
│ ├── 0009 Promote Discovery to Tier 1
│ ├── 0010 Promote Accounting to Tier 1
│ ├── 0011 Promote Portal to Tier 1
│ └── 0012 Promote Notifications to Tier 1
└── capabilities/ Especificación por módulo
├── identity.md ├── sales.md ├── workflows.md
├── crm.md ├── inventory.md ├── notifications.md
├── discovery.md ├── portal.md └── accounting.md