Lo que aprenderás:
Esta página es la referencia de arquitectura autorizada para ZappWay, generada a partir de un escaneo completo del código base (commit 14982f37). Cubre todos los subsistemas principales: estructura monorepo, esquema de base de datos, topología de cola/trabajador, cargadores de ingestión, capa vectorial Qdrant, canalización de incrustación, RAG multidisparo adaptable, motor de chat, autenticación, orquestador de sincronización, las integraciones de 13 canales, almacenamiento de archivos, enrutador modelo LLM y observabilidad.
🔢 Tabla de contenidos
- Overall System Architecture
- Database Layer
- Queue & Worker Architecture
- Ingestion Engine & Loaders
- Vector Database Layer — Qdrant
- Embedding Pipeline
- RAG & Retrieval Pipeline
- Chat & Conversation Engine
- Multi-Tenant Isolation & Auth
- Sync Orchestrator
- External Integrations & Channels
- File Storage & Media Pipeline
- LLM Orchestration & Model Router
- Observability & Monitoring
- Gaps & Recommendations
1. Arquitectura general del sistema
ZappWay es un pnpm monorepo estructurado en 3 aplicaciones y 2 árboles de paquetes. La aplicaciónapps/zappway aloja el panel, la página de destino, el blog y los documentos. Toda la lógica empresarial central se encuentra en packages/zappway/lib (~160 archivos). Una aplicación apps/workers-services dedicada ejecuta todos los trabajadores en segundo plano y la API de WhatsApp Bridge de forma aislada, consumiendo trabajos de las colas BullMQ-Pro respaldadas por Redis.
Mapa de aplicación
Mapa del paquete
2. Capa de base de datos
Fuente:packages/zappway/prisma/schema.prisma (1548 líneas) · 33 modelos · 23 enumeraciones
PostgreSQL a través de Prisma con las funciones de vista previa fullTextSearch y fullTextIndex habilitadas. El modelo Organization es el límite del inquilino raíz; todas las demás entidades tienen su alcance directa o transitivamente.
Inventario de modelo completo
Enumeraciones clave
3. Arquitectura de colas y trabajadores
Fuente:packages/zappway/lib/types/index.ts, apps/workers-services/workers/
Tres colas BullMQ-Pro dedicadas separan las preocupaciones. La cola load-datasource es la cola activa principal; los otros dos están parcialmente implementados.
Configuración del trabajador: cargador de fuente de datos
Mecanismo de deduplicación: Redis
SET NX con la clave ld:lock:{datasourceId} evita que la misma fuente de datos se ejecute en paralelo.
Apagado elegante: maneja SIGTERM y SIGINT: cierra el trabajador y sale de Redis limpiamente.
Inventario de trabajadores
4. Motor de ingesta y cargadores
Fuente:packages/zappway/lib/datastores/datasources/, packages/zappway/lib/loaders/
Todos los cargadores extienden DatasourceLoaderBase. El punto de entrada taskLoadDatasource() selecciona el cargador correcto en tiempo de ejecución según DatasourceType. La salida es una matriz AppDocument[] normalizada que se introduce en el motor de fragmentación y luego en Qdrant.
Mapeo del cargador
Cargador de sitios web: detalle de canalización
Fuente:packages/zappway/lib/loaders/web-site.ts (515 líneas)
El WebSiteLoader es el cargador más complejo. Su proceso se ejecuta en 6 etapas: (1) Descubrimiento: analiza el XML del mapa del sitio o rastrea a través de findDomainPages(); (2) Normalización: desduplicación de URL, eliminación de parámetros UTM, nombre de host en minúsculas; (3) Filtrado de lista negra: aplica la configuración black_listed_urls; (4) Sondeo HTTP — HEAD → GET con reparación de ruta de servidor en 404; (5) Administración de niños: inserta web_page fuentes de datos infantiles, elimina huérfanos; (6) En cola: emite trabajos secundarios con puntuaciones de prioridad (inicio = 5, mapa del sitio = 8, otros = 10). La simultaneidad tiene un límite de 6 a través de mapWithConcurrency. Límite del plan aplicado a través de accountConfig[plan].limits.maxWebsiteURL (predeterminado: 25).
5. Capa de base de datos vectorial — Qdrant
Fuente:packages/zappway/lib/datastores/qdrant.ts (731 líneas)
Cada almacén de datos se asigna exactamente a una colección de Qdrant denominada zw_{datastoreId}, lo que proporciona un aislamiento vectorial estricto por inquilino. QdrantManager incluye una rutina de migración automática que detecta discrepancias en las métricas de dimensión o distancia y recrea la colección de forma transparente, lo que permite actualizaciones del modelo de incorporación sin tiempo de inactividad.
Configuración de colección
Esquema de carga útil (por punto)
6. Incrustación de canalización
Fuente:packages/zappway/lib/datastores/gemini-embeddings.ts, packages/zappway/lib/multimodal-memory/
Todas las incrustaciones utilizan Gemini Embedding 2 Preview, lo que produce vectores de 3072 dimensiones que coinciden con el VECTOR_SIZE de Qdrant. La canalización utiliza valores taskType asimétricos por sitio de llamada (RETRIEVAL_DOCUMENT durante la ingestión y RETRIEVAL_QUERY en el momento de la búsqueda), lo cual es fundamental para la calidad de la recuperación con el modelo de incrustación asimétrico de Gemini.
Configuración
Soporte multimodal
embedMultimodal() acepta GeminiPart[][] donde cada parte puede ser { text } o { inlineData: { mimeType, data } } (imágenes codificadas en base64, fotogramas de vídeo, audio, páginas PDF). Esto incorpora contenido que no es texto en el mismo espacio de 3072 dimensiones que el texto, lo que permite una verdadera búsqueda semántica multimodal.
El módulo multimodal-memory/ proporciona indexación dedicada (indexer.ts - 24,5 KB), fragmentos específicos de medios (media-chunkers.ts), gestión de colecciones, búsqueda y activadores de colas asíncronas.
7. RAG y canalización de recuperación
Fuente:packages/zappway/lib/chat-v4/rag.ts (493 líneas)
ZappWay implementa RAG adaptativo multidisparo con hasta 6 intentos de recuperación progresivos en 3 niveles de calidad. Cada intento relaja los umbrales de similitud para maximizar el recuerdo, mientras que evaluateRagQuality() permite la salida anticipada cuando los resultados son lo suficientemente sólidos. Un disyuntor evita fallas en cascada y ragMemo (caché en memoria) deduplica intentos idénticos dentro de una sesión.
Umbrales adaptativos
El Modo profundo se activa mediante
shouldFavorDeepRag(query) y aplica umbrales iniciales más altos. minUcount es 1 para consultas de un solo almacén de datos y 2 para consultas de varios almacenes de datos. Los tiempos de espera varían de 8 segundos (Nivel 1) a 12 segundos (Nivel 3), limitados por el presupuesto restante del chat. Si es remainingMs() < 120s, el máximo de intentos se reduce a 4.
8. Motor de chat y conversación
Fuente:packages/zappway/lib/chat-v4/chat.ts (1147 líneas), packages/zappway/lib/agent/tools/
La función de chat organiza el ensamblaje de avisos del sistema, el truncamiento del historial de mensajes, el RAG de múltiples disparos, la creación de herramientas de tiempo de ejecución, la ejecución de LLM con transmisión y la cadena de respaldo del modelo completo, todo dentro de un presupuesto de tiempo compartido que se aplica en cada punto de control.
Tipos de eventos SSE
Herramientas de tiempo de ejecución
9. Aislamiento y autenticación de múltiples inquilinos
Fuentes:packages/zappway/lib/auth/authConfig.ts, authAdapter.ts y authProviders.ts
Auth.js Core procesa directamente las solicitudes HTTP del servidor con un adaptador Prisma personalizado; next-auth/react permanece limitado al cliente. Se admiten cuatro métodos de inicio de sesión. En el primer inicio de sesión, la plataforma aprovisiona automáticamente la pila completa de inquilinos de forma atómica.
Aislamiento de inquilinos por capa
Modelo RBAC
Configuración de sesión
Compatibilidad regional: 37 configuraciones regionales, incluido RTL (árabe, hebreo, persa, urdu). Orden de resolución: ruta URL →
NEXT_LOCALE cookie → i18next cookie → Accept-Language encabezado → predeterminado en.
10. Orquestador de sincronización
Fuente:apps/workers-services/workers/check-and-sync-cron.ts
Un trabajador controlado por cron escanea todas las fuentes de datos con status = synched, filtra por lastSyncAt + syncInterval y distribuye trabajos individuales load-datasource. Un trabajador check-stalled maneja la recuperación de fuentes de datos atascadas en el estado running más allá de un umbral configurable.
11. Integraciones y canales externos
Fuente:packages/zappway/integrations/ — Adaptadores de 13 canales
Todos los canales normalizan los mensajes entrantes al mismo modelo interno Conversation + Message y enrutan a través del motor unificado chat-v4.
Capacidades del canal
Autenticación del proveedor de servicios
12. Almacenamiento de archivos y canalización de medios
Fuente:packages/zappway/lib/aws.ts
Admite almacenamiento compatible con S3 (AWS S3, Cloudflare R2, MinIO) a través de AWS SDK v3. Los archivos se cargan a través de URL prefirmadas, se almacenan en organizations/{orgId}/ y FileLoader los extrae para su extracción e ingesta.
Variables de entorno S3
13. Orquestación LLM y enrutador de modelos
Fuente:packages/zappway/lib/config.ts (943 líneas), packages/zappway/lib/chat-model/model.ts (745 líneas)
50+ models across 12 providers via a unified OpenAI-SDK-compatible interface. Provider routing is automatic based on each model’s baseUrl in ModelConfig. OpenAI, Google Gemini, and OpenRouter are all accessed through the same OpenAI SDK client with different base URLs and API keys.
Inventario de modelos
🧠 OpenAI - Directo
🟡 Google: directo a través de la API de Gemini
🔶 Antrópico - vía OpenRouter
Otros proveedores: a través de OpenRouter
Modelos de nivel gratuito:
gpt_4o_mini, gpt_5_mini, gpt_5_nano, gpt_5_4_mini, gpt_5_4_nano, gemini_flash_2_0
Importante: Los modelos de la familia GPT-5 no admiten el ajuste manual de temperatura; utilizan el reconocimiento automático de temperatura.
14. Observabilidad y seguimiento
Fuente:packages/zappway/lib/logger.ts, apps/workers-services/sentry.*.config.ts
Los trabajadores publican una carga útil
WorkerHealth en Redis (health:worker:{name}, 30s TTL) cada 10s. Campos: status, startedAt, lastActivityAt, jobsProcessed, jobsFailed, queueLength, system.memoryMB, system.uptimeMs. Expuesto a través de /api/workers/health.
Los trabajadores también transmiten registros en tiempo real al canal Redis Pub/Sub logs:datasource para monitoreo en vivo del panel.
15. Lagunas y recomendaciones
Brechas identificadas
Recomendaciones
- Enable cloud logging — Uncomment Axiom or use Datadog / Grafana Loki for production log retention.
- Add rate limiting — Per-organization token-bucket on chat endpoints.
- Implement DLQ — BullMQ supports
deadLetterQueueoption; enable for all 3 queues. - Embedding fallback —
text-embedding-3-largefrom OpenAI (3072-dim compatible) as secondary. - Qdrant snapshots — Cron-based snapshot to S3 for disaster recovery.
- Test coverage — Integration tests for the RAG pipeline and ingestion workers as a starting priority.
Fortalezas arquitectónicas
Vocabulario
· Última actualización: marzo de 2026

