Arquitectura del ecosistema Timeliber
Última actualización: 2026-04-09
Fuente: análisis del código fuente + docker-compose + configs de cada app.
Nivel 1 — Contexto del sistema
¿Quién interactúa con Timeliber y qué sistemas externos consume?
flowchart TB
subgraph Usuarios
GUEST["📱 Huésped<br/>(WhatsApp)"]
ADMIN["🖥️ Hotelero<br/>(Dashboard web)"]
end
subgraph Timeliber["☁️ Timeliber Ecosystem"]
CORE["Monorepo<br/>timeliber-workspace"]
end
subgraph Externos
META["WhatsApp<br/>(Meta Cloud API)"]
GROQ["Groq<br/>(LLM Inference)"]
OPENAI["OpenAI<br/>(Embeddings)"]
end
GUEST -->|mensaje| META
META -->|webhook| CORE
CORE -->|respuesta| META
META -->|mensaje| GUEST
ADMIN -->|HTTPS| CORE
CORE -->|Inference API| GROQ
CORE -->|Embeddings API| OPENAI
Nivel 2 — Contenedores
Cada servicio corre como contenedor Docker dentro de la red timeliber-net.
flowchart TB
subgraph External["Servicios Externos"]
WA["📱 WhatsApp<br/>(Meta)"]
GROQ_API["🧠 Groq API"]
OAI["🔷 OpenAI API"]
end
subgraph Docker["🐳 Docker Host — timeliber-net"]
subgraph Proxy
TRAEFIK["Traefik<br/>:80 / :443"]
end
subgraph Apps["apps/"]
ORCH["🤖 AI Orchestrator<br/>FastAPI :8002<br/>LangGraph + Groq"]
TRAVEL_API["🏨 Travel API<br/>FastAPI :8001<br/>SQLAlchemy"]
TRAVEL_FE["🖥️ Travel Frontend<br/>Vite :5173"]
MAIN_API["📧 Main API<br/>FastAPI :8000"]
MAIN_FE["🌐 Main Frontend<br/>Next.js :3000"]
TOOLS_API["🔧 RAG Studio<br/>FastAPI :8010"]
TOOLS_FE["🧪 Tools Frontend<br/>Next.js :3001"]
end
subgraph Infra["infra/"]
PG[("PostgreSQL 16<br/>:5432<br/>travel_db")]
REDIS[("Redis 7<br/>:6379")]
QDRANT[("Qdrant<br/>:6333")]
N8N["⚙️ n8n<br/>:5678"]
EVO["📲 Evolution API<br/>:8080"]
end
end
WA <-->|webhook| EVO
EVO <-->|API| N8N
N8N -->|POST /chat :8002| ORCH
ORCH -->|HTTP :8001| TRAVEL_API
ORCH -->|inference| GROQ_API
TRAVEL_API --> PG
TRAVEL_API --> QDRANT
TRAVEL_API --> REDIS
TOOLS_API --> QDRANT
TOOLS_API --> PG
TOOLS_API -->|embeddings| OAI
MAIN_API --> PG
TRAEFIK --> TRAVEL_FE
TRAEFIK --> MAIN_FE
TRAEFIK --> N8N
TRAVEL_FE -->|API calls| TRAVEL_API
MAIN_FE -->|API calls| MAIN_API
TOOLS_FE -->|API calls| TOOLS_API
Nivel 3 — Componentes del AI Orchestrator
El servicio más complejo del ecosistema. Diagrama detallado del grafo LangGraph:
flowchart LR
START([HumanMessage]) --> LC[load_context]
LC -->|"GET /properties/{id}/context"| TRAVEL_API["Travel API"]
LC --> ROUTER[router]
ROUTER -->|BOOKING| EXTRACT{extractor_node}
ROUTER -->|FAQ| FAQ[faq_node]
ROUTER -->|CHITCHAT| CHAT[chitchat_node]
EXTRACT -->|"extrae: nombre, fechas, guests"| BOOK[booking_node]
BOOK -->|tool_calls| TOOLS[call_tools]
FAQ -->|tool_calls| TOOLS
TOOLS -->|"consultar_disponibilidad<br/>consultar_conocimiento_hotel<br/>crear_reserva_pendiente"| TRAVEL_API
TOOLS --> BOOK
TOOLS --> FAQ
BOOK --> SYNC[sync_state_node]
FAQ --> SYNC
CHAT --> SYNC
SYNC -->|"PATCH /conversation-sessions"| TRAVEL_API
SYNC --> FIN([Respuesta al huésped])
style EXTRACT fill:#f9f,stroke:#333
style TOOLS fill:#bbf,stroke:#333
style SYNC fill:#bfb,stroke:#333
Guards y validadores
| Guard | Ubicación | Protege contra |
|---|---|---|
should_extract_or_book |
router/edges.py |
Salta extractor si datos ya están en el estado |
_last_bot_said |
nodes/booking.py |
Evita que el bot repita la misma pregunta (antiloop) |
Validador en crear_reserva_pendiente |
tools/travel.py:159-177 |
Bloquea reservas con guest_name == "nuestro cliente" |
_INSTRUCTION_LEAK_RE |
nodes/booking.py |
Filtra instrucciones internas del output al usuario |
LLM_MAX_CHAT_MESSAGES |
src/config.py |
Limita historial a 12 mensajes (evita tokens excesivos) |
LLM_MAX_RAG_CONTEXT_CHARS |
src/config.py |
Limita contexto RAG a 12,000 chars |
Nivel 3 — Componentes del Travel Backend
flowchart TB
subgraph API["API Layer (FastAPI)"]
AUTH[auth.py]
AVAIL[availability.py]
KNOW[knowledge.py]
PROP[property_context.py]
RES[reservations.py]
SESS[conversation_sessions.py]
ROOMS[rooms.py]
GUESTS[guests.py]
RT[room_types.py]
HP[health.py]
end
subgraph Services["Service Layer"]
S_AVAIL[availability_service]
S_KNOW["knowledge_service<br/>(Qdrant + OpenAI)"]
S_PROP[property_context_service]
S_RES["reservation_service<br/>(business rules)"]
S_SESS[conversation_session_service]
end
subgraph Data["Data Layer"]
PG[("PostgreSQL<br/>11 modelos")]
QD[("Qdrant<br/>embeddings")]
end
AVAIL --> S_AVAIL --> PG
KNOW --> S_KNOW --> QD
PROP --> S_PROP --> PG
RES --> S_RES --> PG
SESS --> S_SESS --> PG
Flujo de datos entre verticales
flowchart LR
subgraph Ingestion["Ingesta (offline)"]
PDF["📄 Documentos"]
TOOLS["🔧 RAG Studio"]
end
subgraph Runtime["Runtime (online)"]
ORCH["🤖 Orchestrator"]
TRAVEL["🏨 Travel API"]
end
subgraph Storage["Almacenamiento"]
QD[("Qdrant")]
PG[("PostgreSQL")]
end
PDF -->|upload| TOOLS
TOOLS -->|chunk + embed| QD
TOOLS -->|FAQ generation| QD
ORCH -->|GET /knowledge/search| TRAVEL
TRAVEL -->|vector search| QD
TRAVEL -->|SQL queries| PG
ORCH -->|POST /reservations/public| TRAVEL
TRAVEL -->|INSERT| PG
Redes Docker
| Red | Propósito | Miembros |
|---|---|---|
timeliber-net |
Comunicación interna entre servicios | Todos los apps + infra |
proxy-net |
Capa de proxy reverso | Traefik + frontends públicos |
Documentación relacionada
| Documento | Ruta |
|---|---|
| Mapa del monorepo | monorepo/MONOREPO_MAP.md |
| Stack tecnológico | inventory/TECH_STACK.md |
| Travel ARCHITECTURE | ../apps/travel/backend/docs/ARCHITECTURE.md |
| AI Orchestrator | apps/AI_ORCHESTRATOR.md |
| ADRs | architecture/README.md |
| Glosario | glossary/GLOSSARY.md |
| Deploy | ../infra/DEPLOY.md |