Departamento ERP · Odoo · Documento de arquitectura

ERP Hub— el cerebro central del departamento

Un VPS que coordina a un equipo que ya no pica código: los desarrolladores dirigen a Claude en local, y todo lo que ocurre —contexto, tareas, pruebas, decisiones— aterriza solo en un único cerebro compartido, siempre al día.

En planificación 3 devs · abierto a más ~10 clientes self-hosted 2026-07-16
En una frase

Qué es

Los markdown de la memoria son la fuente de verdad; los hooks los alimentan solos desde el trabajo de los devs; los bots de cron vigilan git y el correo; CodeGraph + el grafo de conocimiento los vuelven consultables; y los dos Claudes leen y escriben todo eso — de modo que, trabaje quien trabaje y esté quien esté delante, el departamento entero está al día en un solo sitio.
◐ Cuerpo 1

El Claude del dev

En su ordenador. Actúa cuando hay alguien dirigiendo: programa en la copia local y escribe al cerebro.

una misma
mente
◑ Cuerpo 2

El Claude del VPS

El "cuarto trabajador". Autónomo: resume, clasifica emails, levanta Odoo y testea. Nunca mergea.

Qué construimos

Las capacidades y su "hecho"

Cada capacidad tiene un criterio medible de cuándo está terminada — sin tecnicismos, en qué se nota.

C1

Memoria compartida

Cualquier dev abre un cliente y Claude ya sabe su contexto, lo último que hizo cualquiera y las tareas abiertas.

Hecho cuandocada bloque de trabajo aparece resumido en la memoria en <2 min, solo.
C2

Presencia en vivo

Ver en un sitio quién trabaja ahora, en qué cliente y rama. Si dos coinciden, ambos reciben aviso.

Hecho cuandoel estado del equipo refleja la realidad sin que nadie lo actualice.
C3

Emails → tareas

Por ahora cada dev pega el email de su cliente en su propio Claude; en minutos hay una tarea clasificada en el cliente correcto.

Hecho cuando9 de 10 emails acaban bien clasificados sin tocar nada; los dudosos van a triaje.
C4

Testeo automático (QA)

El Hub levanta el Odoo del cliente, corre los tests y prueba en navegador — la red de seguridad.

Hecho cuandoningún cambio llega a un cliente sin pasar por esto.
C5

Claude del Hub bajo demanda

Te conectas al VPS y le encargas ("analiza el issue #12"); trabaja en ramas hub/* y entrega una propuesta.

Hecho cuandoentrega PR + informe y jamás mergea ni toca producción.
C6

Onboarding de un dev

Un comando deja la máquina lista: VPN, repos, hooks e identidad.

Hecho cuandoun dev nuevo está operativo en <30 min sin que nadie toque su equipo.
Arquitectura

El mapa, de un vistazo

Para empezar, la conexión al VPS es simple: acceso directo (SSH) para quien quiera ir al grano, o a través del Claude de cada dev. El método definitivo se decide más adelante.

Los devs — todos iguales, cada uno en su LOCAL

dev
Dev 1
Claude + hooks
dev
Dev 2
Claude + hooks
dev
Dev 3
Claude + hooks
+
más devs
se añaden solos
▲ ▼   Conexión al VPS · SSH directo o vía el Claude del dev · self-hosted   ▲ ▼

◑ ERP Hub — VPS 16 GB

self-hosted
Memoria global
repo git de markdown · contexto, sesiones, tareas, emails
Código espejo
10 checkouts + CodeGraph
Grafo conocimiento
Basic Memory sobre los MD
Staging Odoo
doodba, on-demand
Claude del Hub
headless · ramas hub/* · QA
Presencia + cron
FastAPI + 5 bots · Playwright

Hacia fuera

git
GitHub org
repo por cliente · issues = tareas
mail
Emails a mano
cada dev los pega desde su equipo · buzón auto = futuro
ssh
Acceso directo
te conectas al VPS y le hablas
Las dos máquinas

Qué carpetas hay en cada lado

En el portátil del dev, solo lo que necesita para trabajar. En el VPS, todo lo compartido y lo pesado. Nada importante vive solo en el portátil.

~/erp/ · ordenador del dev
~/erp/                       # abre Claude aquí (todos sus proyectos)
├── CLAUDE.md               # identidad + apunta al cerebro
├── .hub/
│   ├── identidad.json      # quién soy, mis clientes, dónde está el VPS
│   └── age.pub             # mi clave pública (secretos)
├── jmc/                    # clon del repo del cliente
└── cliente-x/
erp-hub-memory/ · el VPS
erp-hub-memory/
├── MEMORY.md               # índice global
├── equipo/
│   ├── estado.md           # presencia en vivo
│   ├── devs/               # identidad de cada dev
│   └── reglas/             # el estándar común
├── clientes/jmc/
│   ├── contexto.md         # quién es el cliente
│   ├── proyecto.md         # repo, rama, staging
│   ├── credenciales.age    # cifrado (sops+age)
│   ├── sesiones/          # bloques resumidos (auto)
│   ├── emails/            # emails clasificados
│   └── tareas/
└── hub/ cola.md · qa/     # encargos e informes
Cada dev, registrado

El VPS sabe dónde tiene cada uno sus proyectos

No todos guardan los proyectos en la misma ruta. El cerebro registra, por dev, en qué carpeta local vive cada cliente — para saber siempre dónde está todo.

equipo/devs/juan.md · en el VPS
---
dev: juan
maquina: portatil-juan
clientes:
  jmc:        ~/erp/jmc
  cliente-x:  ~/erp/cliente-x
ultima_conexion: 2026-07-16 09:05
---
# Juan — dev del equipo ERP
Skills y estándares globales sincronizados ✅
equipo/devs/pedro.md · rutas distintas, sin problema
---
dev: pedro
maquina: mac-pedro
clientes:
  jmc:   /Users/pedro/dev/jmc
  otro:  /Users/pedro/dev/otro
ultima_conexion: 2026-07-16 09:31
---

Se registra en el alta del dev y se actualiza solo cuando clona un proyecto nuevo. Así el cerebro —y su Claude— saben exactamente en qué ruta de cada máquina vive cada cliente, aunque cada uno lo tenga en un sitio distinto.

Conexión y arranque

Cómo el dev sabe que está conectado

No hay ritual de conexión: la VPN está siempre arriba y el cerebro se conecta solo al abrir Claude. Estas dos piezas —baratas— hacen que el dev lo vea y confíe desde el primer segundo.

Canal · MCP

Dinámico, bajo demanda

El VPS expone un servidor MCP. El Claude del dev consulta y escribe en el cerebro en el momento exacto en que hace falta (contexto del cliente, presencia, crear tarea). Es lo mismo que ya hace CodeGraph.

Canal · Hooks

Automático, garantizado

Aunque Claude no llame a nada, los hooks capturan siempre lo esencial: los eventos de presencia y el cierre de bloques. La red de seguridad para que nada dependa de que "se acuerde".

Opción 1 · aviso al arrancar
$ claude
── ERP Hub ─────────────────────────────
✅ Conectado al cerebro (VPS)
   12 clientes · Pedro y María activos ahora
   3 tareas tuyas abiertas en JMC
─────────────────────────────────────────

# si el VPS no responde:
⚠️  Sin conexión al cerebro
   No se llega al VPS → revisa tu conexión
   (sigues trabajando; se sincroniza al volver)
Opción 2 · comando erp
$ erp
▸ Conexión al VPS…… ✅ el VPS responde
▸ Cerebro ERP (MCP)… ✅ conectado
▸ Repo de memoria…… ✅ al día (pull ok)
▸ Identidad……… Juan · JMC, Cliente-X

Todo listo — abriendo Claude en ~/erp/
Conectado conectas pero el VPS no responde Sin conexión · app de escritorio con esta misma luz = fase 2, al abrir a más devs
Forma de trabajar

Estándares, skills y agentes

La manera de trabajar no se le explica a cada dev: se define una vez y le llega sola a su Claude. Igual que en la Pi, pero compartido por todo el equipo.

Cuatro capas de reglas — cada una vive donde le toca

CapaEjemplosDónde vive
Global
todo el equipo
Commits en inglés · rama por tarea · no tocar PROD · black/ruff/pylint-odooVPS · biblioteca global
Por stack"Odoo → convenciones OCA + estas librerías"VPS · según el stack
Por negocio"JMC factura a 60 días · no tocar la secuencia de facturas"VPS · contexto del cliente
Por proyecto
técnico
CLAUDE.md del repo · skill "añadir campo a la factura" · agente "jmc-tester"En el git del proyecto
🌐 La biblioteca global vive en el VPS (equipo/skills/ · equipo/agents/ · equipo/reglas/) y se sincroniza a cada dev. Todos comparten el mismo maletín: un skill "montar un módulo Odoo", un agente "odoo-tester", los estándares. Una sola fuente — y cuando cambias algo ahí, todos lo tienen en la siguiente sesión.
Llega vía · git clone

Lo del proyecto viene con el código

El CLAUDE.md, los skills y los agentes dentro del repo llegan solos al clonarlo. Los tiene el dev y también el Claude del VPS. Cero esfuerzo.

Llega vía · al iniciar

Lo global se inyecta al arrancar

El hook injector hace pull del VPS y mete en contexto solo lo que aplica: global + stack del proyecto + negocio del cliente. Como ya haces en la Pi.

Y funciona en los dos sentidos: cuando un skill de un proyecto resulta útil para todos, se promociona a global — pasa a la biblioteca del VPS y desde entonces lo tiene el equipo entero. El maletín común crece con lo que aporta cada uno.

Los archivos, por dentro

Contexto real, no abstracto

Ejemplos con contenido real de cómo se ve la ficha de un cliente, la presencia del equipo y un email ya convertido en tareas.

clientes/acme/contexto.md
---
cliente: jmc
dev_asignado: juan
odoo_version: "17.0"
---
# JMC S.L.

Distribuidora de material de oficina, ~40
empleados. Contacto: Marta (admin).

## Siempre tener en cuenta
- No tocar la secuencia de facturas (AEAT).
- Aprobación de pedidos > 5.000 €.
- A producción solo los viernes por la mañana.
clientes/acme/sesiones/…_juan.md
---
dev: juan   cliente: jmc
rama: jmc/feat-descuento
tarea: "#48 descuento no sale a crédito"
---
# Bloque de trabajo — Juan en JMC

## Qué se hizo
- Bug en account_move.py: condición de
  pago demasiado estricta. Corregido.
- Añadido test test_descuento_credito.

## Estado — rama lista, pendiente QA.
NO mergeado.

equipo/estado.md — presencia en vivo (TTL 30 min)

DevClienteRamaÚltima acciónDesde
JuanJMCjmc/feat-descuentoedit invoice.py09:05
PedroJMCjmc/fix-stockrun tests09:31
MaríaCliente-Xx/portal-loginedit portal.js08:50
⚠️ Juan y Pedro coinciden en JMC (ramas distintas) — aviso, no bloqueo.
Cómo funciona

Un email de JMC, de punta a punta

Sigue una petición real desde que llega hasta que se aprueba, viendo qué cuerpo actúa en cada paso.

1

Llega el email local

Marta escribe a Juan. Él lo pega a mano en su Claude, desde su propio ordenador: "tengo este email de JMC…". Su Claude lo interpreta al vuelo. (Sin buzón automático por ahora.)

2

Se parte en tareas local

Detecta JMC y separa dos cosas: un bug (descuento a crédito) y una mejora (exportar a Excel). Crea los issues #48 y #49 en el centro, no en el portátil.

3

Juan trabaja el bug local

Al decir "vamos con el bug de JMC", el hook le inyecta el contexto del cliente y lo que hizo Pedro. Claude corrige en la copia local, en jmc/feat-descuento.

4

Cambia de cliente → se guarda solo hub

Juan salta al Cliente-X sin cerrar nada. El cambio de cliente cierra el bloque: el Hub lo resume desde el flujo de eventos y lo guarda en sesiones/.

5

El Hub testea hub

Te conectas al VPS y le dices "prueba la rama de descuento": levanta el Odoo de JMC (doodba), corre los tests, factura a crédito con Playwright y responde ✅ 12 tests OK, descuento correcto (captura).

6

Un humano aprueba

Un dev revisa y mergea. El Hub nunca mergea ni toca producción.

Cuando aparece algo nuevo

El cerebro aprende sobre la marcha — y no duplica

No hay que dar de alta nada antes de empezar. En cuanto algo aparece, el cerebro lo registra solo en la carpeta del cliente con todo lo que necesita. Y si ya existía, avisa en vez de duplicar.

Cliente nuevo

Se registra al tocarlo

Un dev empieza con "Bodegas Rivas", que no existe. Su Claude crea la ficha esqueleto, empieza a registrar la actividad, y pide dos líneas de contexto que solo sabe un humano.

Email nuevo

Genera todo en el centro

Le pasas el email a mano. El cerebro genera en la carpeta del cliente todo lo que necesita: guarda el email, lo clasifica, crea la tarea con el texto citado y la prioridad. Sin que muevas nada más.

Repetido

Avisa, no duplica

Si otra persona pasa el mismo email, el cerebro ve que ya existe la tarea y quién la lleva — y te lo dice, en vez de crear un duplicado.

Pedro pega el mismo email de Marta
$ "tengo este email de JMC: no sale el descuento…"

⚠️  Esto ya está registrado
   Tarea #48 · "descuento no sale a crédito" (JMC)
   La lleva Juan · rama jmc/feat-descuento · desde 09:05

No creo un duplicado. ¿Quieres verla o añadir algo?

Puede hacerlo porque todo vive en el centro: las tareas y la presencia. Antes de crear nada, el cerebro mira si ya existe una tarea para eso en ese cliente y si alguien está en ella. Los dos únicos límites: no puede probar código que no esté subido al remoto, ni inventar el contexto de un cliente nuevo — eso lo teclea un humano (dos líneas).

La capa de grafo

Dos grafos, unidos por el módulo

El grafo del código y el grafo del conocimiento del departamento, conectados: desde una tarea saltas directo al código que la resuelve.

CodeGraph

Grafo de código

La estructura del código de los 10 clientes. Ya lo usas.

  • "¿Dónde se calcula el descuento en JMC?" → _compute_amount()
  • Quién llama a qué, sin grep.
  • Se refresca con codegraph sync tras cada pull.
puente · el módulo / la ruta
Basic Memory

Grafo de conocimiento

Las entidades del departamento y sus relaciones, sobre los mismos markdown.

  • "¿Qué módulos toca más Pedro?"
  • "Este email, ¿en qué acabó?" → Tarea → Commit
  • "¿Qué tareas abiertas tiene JMC?"
ClienteDevTareaSesiónEmailMóduloCommit

El nexo es el módulo: el nodo jmc_facturacion del grafo de conocimiento apunta a su subgrafo en CodeGraph. Así, desde "tarea #48 sobre facturación de JMC" saltas al código real sin buscar a mano.

Los bots de cron

Cinco vigilantes, cada uno una cosa

Mismo patrón que tu scheduler actual con claude -p. Ninguno depende de que un dev haga nada.

BotCadaQué hace
fetch-commits10–15 mingit fetch de los 10 repos → apunta commits en actividad.md → refresca CodeGraph y el grafo.
email-inbox (futuro)5–15 minAutomatiza el buzón tareas@. Al principio no hace falta: los devs pasan los emails a mano desde su Claude.
work-blocks5 minDetecta bloques cerrados (cambio de cliente / inactividad / fin de día) → resume → guarda la sesión.
hub-queue2 minLee hub/cola.md → ejecuta encargos del Claude del VPS (testeo, análisis) → informe.
digest-diario09:00Resumen del día anterior por dev/cliente → queda en el VPS, lo ves al conectarte.
al conectarte al VPS · digest del día
📊 Equipo ERP — 16/07
JMC: 4 commits (Juan 3, Pedro 1) · issue #48 en QA ✅ · 2 tareas nuevas por email
Cliente-X: 2 commits (María) · portal-login en progreso
🔴 Pendiente aprobación: merge de jmc/feat-descuento
Cómo empezamos

Hoja de ruta por fases

Cada fase entrega valor por sí sola. Con las tres primeras ya tienes el corazón funcionando.

F0

Cimientos

VPS + WireGuard + repos + secretos cifrados + script de onboarding.

2–3 días
F1

Visibilidad

Cron que registra commits por cliente + digest que ves al conectarte.

1–2 días
F2
🏁 Mínimo viable = F0 + F1 + F2

Memoria + presencia

Tus hooks en modo equipo: contexto al abrir, resumen por bloques.

3–5 días
F3

Emails → tareas

Buzón + clasificación automática → issue + borrador de respuesta.

2–3 días
F4

El cuarto trabajador

Claude del Hub + Odoo staging (doodba) + QA con Playwright.

4–6 días
F5

Extras

Grafo semántico completo, Plane, dashboard — cuando duelan, no antes.

Antes de arrancar

Lo que tienes que confirmar

Solo estas bloquean. En tres ya hay recomendación clara; una es grande.

D1 · la grande

¿Dónde vive el código de los clientes?

GitHub privado + copias espejo, o Forgejo en el VPS. Lo más caro de revertir.

Recomendación GitHub — pero revisa antes si algún contrato prohíbe la nube. Si alguno exige on-premise → Forgejo.

D2

El VPS

Proveedor y tamaño. Lo monta el equipo de sistemas.

Recomendación OVH nuevo, 16 GB. Nunca el VPS2 (PROD de thetraktor).

D3

Suscripciones Claude

Cuántas y de qué nivel. Es el coste dominante.

Recomendación 3× Max (devs) + 1 para el Hub. Evaluar plan Team.

D4 · más adelante

Buzón de emails

No bloquea el arranque: por ahora cada dev pasa los emails a mano desde su ordenador. El buzón automático tareas@… queda para cuando queráis automatizarlo.

Sin prisa el dominio se decide al llegar a F3.

Riesgo nº1

Las credenciales de 10 clientes. Hoy viven en texto plano en los markdown. El Hub concentraría los accesos de 10 empresas, así que sops + age desde el día 0 es innegociable — cifradas dentro del repo, una clave por persona.

Herramientas

Con qué se monta — y qué reaprovecha

Casi todo el software es open-source o ya lo tienes montado. El único coste recurrente real son las suscripciones de Claude.

PiezaHerramientaRol¿Ya lo tienes?
Conexión al VPSSSH (por ahora)Acceso directo o vía el Claude del dev · método final a decidir
Memoriarepo git de markdownFuente de verdad, versionada✅ tu sistema de memoria
Grafo de códigoCodeGraphEstructura del código✅ ya en 5 repos
Grafo de conocimientoBasic MemoryEntidades y relaciones sobre los MDnuevo
Tareasissues del forgeTarea ↔ commit, en el centro✅ gh CLI
Presencia + resúmeneshooks + claude -pQuién hace qué, sin cerrar sesión✅ injector/observer
Email → tareaIMAP + HaikuClasificación automática✅ patrón soporte email
Testeodoodba + PlaywrightLevanta Odoo y prueba✅ Playwright
Secretossops + ageCredenciales cifradasnuevo · necesario
Cronscheduler propioLos 5 bots✅ tu scheduler