Skip to main content
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

  1. Overall System Architecture
  2. Database Layer
  3. Queue & Worker Architecture
  4. Ingestion Engine & Loaders
  5. Vector Database Layer — Qdrant
  6. Embedding Pipeline
  7. RAG & Retrieval Pipeline
  8. Chat & Conversation Engine
  9. Multi-Tenant Isolation & Auth
  10. Sync Orchestrator
  11. External Integrations & Channels
  12. File Storage & Media Pipeline
  13. LLM Orchestration & Model Router
  14. Observability & Monitoring
  15. Gaps & Recommendations

1. Arquitectura general del sistema

ZappWay es un pnpm monorepo estructurado en 3 aplicaciones y 2 árboles de paquetes. La aplicación apps/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

  1. Enable cloud logging — Uncomment Axiom or use Datadog / Grafana Loki for production log retention.
  2. Add rate limiting — Per-organization token-bucket on chat endpoints.
  3. Implement DLQ — BullMQ supports deadLetterQueue option; enable for all 3 queues.
  4. Embedding fallbacktext-embedding-3-large from OpenAI (3072-dim compatible) as secondary.
  5. Qdrant snapshots — Cron-based snapshot to S3 for disaster recovery.
  6. 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