- Stack completo con Mattermost, NocoDB y Sales Bot - Procesamiento OCR de tickets con Tesseract - Sistema de comisiones por tubos de tinte - Comandos slash /metas y /ranking - Documentación completa del proyecto Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
209 lines
21 KiB
Markdown
209 lines
21 KiB
Markdown
# Arquitectura del Sistema
|
||
|
||
## Diagrama General
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ INFRAESTRUCTURA │
|
||
│ (Docker Compose) │
|
||
└─────────────────────────────────────┘
|
||
│
|
||
┌──────────────────────────────────────────┼──────────────────────────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
|
||
│ MATTERMOST │ │ SALES BOT │ │ NOCODB │
|
||
│ (Puerto 8065) │◄────────────────►│ (Puerto 5000) │◄────────────────►│ (Puerto 8080) │
|
||
├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤
|
||
│ - Chat empresarial │ │ - Flask/Gunicorn │ │ - UI visual │
|
||
│ - Webhooks │ │ - OCR Tesseract │ │ - API REST │
|
||
│ - Comandos slash │ │ - WebSocket client │ │ - Relaciones │
|
||
│ - Archivos/imágenes │ │ - Handlers │ │ - Webhooks │
|
||
├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤
|
||
│ PostgreSQL │ │ Python 3.12 │ │ PostgreSQL │
|
||
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
|
||
```
|
||
|
||
## Flujo de Datos
|
||
|
||
```
|
||
┌──────────┐ ┌────────────┐ ┌───────────┐ ┌─────────┐ ┌────────────┐
|
||
│ VENDEDOR │────►│ MATTERMOST │────►│ SALES BOT │────►│ NOCODB │────►│ RESPUESTA │
|
||
└──────────┘ └────────────┘ └───────────┘ └─────────┘ └────────────┘
|
||
│ │ │ │ │
|
||
│ │ │ │ │
|
||
▼ ▼ ▼ ▼ ▼
|
||
Mensaje Webhook POST Procesamiento Registro DB Mensaje +
|
||
+ Imagen + Payload OCR + Datos Reacción
|
||
```
|
||
|
||
## Redes Docker
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ HOST (192.168.10.204) │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||
│ │ mattermost-network │ │ sales-bot-network │ │ nocodb-network │ │
|
||
│ │ (bridge) │ │ (bridge) │ │ (bridge) │ │
|
||
│ ├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤ │
|
||
│ │ mattermost:8065 ◄┼──┼► sales-bot:5000 ◄┼──┼► nocodb:8080 │ │
|
||
│ │ postgres:5432 │ │ │ │ postgres:5432 │ │
|
||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Componentes del Sales Bot
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ SALES BOT │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ app.py │ │ handlers.py │ │ ocr_processor │ │
|
||
│ │ ─────────────── │ │ ─────────────── │ │ ─────────────── │ │
|
||
│ │ Flask App │────►│ handle_venta │────►│ Tesseract OCR │ │
|
||
│ │ Endpoints │ │ Lógica negocio │ │ OpenCV │ │
|
||
│ │ Inicialización │ │ Comisiones │ │ Preprocesamiento│ │
|
||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||
│ │ │ │ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ websocket_ │ │ mattermost_ │ │ nocodb_ │ │
|
||
│ │ listener.py │ │ client.py │ │ client.py │ │
|
||
│ │ ─────────────── │ │ ─────────────── │ │ ─────────────── │ │
|
||
│ │ Eventos tiempo │ │ API Mattermost │ │ API NocoDB │ │
|
||
│ │ real │ │ Mensajes │ │ CRUD tablas │ │
|
||
│ │ Thread separado │ │ Archivos │ │ Comisiones │ │
|
||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||
│ │ utils.py │ │
|
||
│ │ ─────────────────────────────────────────────────────────────── │ │
|
||
│ │ extraer_monto() │ extraer_cliente() │ extraer_tubos() │ etc. │ │
|
||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Proceso de Venta
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────────────────┐
|
||
│ PROCESO DE REGISTRO DE VENTA │
|
||
├────────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ 1. RECEPCIÓN │
|
||
│ ┌─────────────────┐ │
|
||
│ │ Vendedor envía │ │
|
||
│ │ mensaje + foto │ │
|
||
│ └────────┬────────┘ │
|
||
│ │ │
|
||
│ 2. WEBHOOK │
|
||
│ ┌────────▼────────┐ │
|
||
│ │ Mattermost │ │
|
||
│ │ Outgoing Hook │ │
|
||
│ └────────┬────────┘ │
|
||
│ │ │
|
||
│ 3. EXTRACCIÓN │
|
||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||
│ │ Parseo de texto │────►│ @monto 1500 │ │
|
||
│ │ │ │ @cliente Juan │ │
|
||
│ │ │ │ @tubos 5 │ │
|
||
│ └────────┬────────┘ └─────────────────┘ │
|
||
│ │ │
|
||
│ 4. OCR (si hay imagen) │
|
||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||
│ │ Descargar img │────►│ Preprocesamiento│ │
|
||
│ │ de Mattermost │ │ OCR Tesseract │ │
|
||
│ └────────┬────────┘ │ Detección tubos │ │
|
||
│ │ └─────────────────┘ │
|
||
│ │ │
|
||
│ 5. VALIDACIÓN │
|
||
│ ┌────────▼────────┐ │
|
||
│ │ Monto OCR vs │ │
|
||
│ │ Monto mensaje │ │
|
||
│ │ (tolerancia 5%) │ │
|
||
│ └────────┬────────┘ │
|
||
│ │ │
|
||
│ 6. REGISTRO │
|
||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||
│ │ NocoDB API │────►│ Vendedor │ │
|
||
│ │ │ │ Venta │ │
|
||
│ │ │ │ Detalle │ │
|
||
│ │ │ │ Meta │ │
|
||
│ └────────┬────────┘ └─────────────────┘ │
|
||
│ │ │
|
||
│ 7. COMISIONES │
|
||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||
│ │ Calcular │────►│ tubos > 3? │ │
|
||
│ │ comisión │ │ comisión = $10 │ │
|
||
│ │ │ │ × (tubos - 3) │ │
|
||
│ └────────┬────────┘ └─────────────────┘ │
|
||
│ │ │
|
||
│ 8. RESPUESTA │
|
||
│ ┌────────▼────────┐ │
|
||
│ │ Mensaje en │ │
|
||
│ │ Mattermost + │ │
|
||
│ │ Reacción ✓ │ │
|
||
│ └─────────────────┘ │
|
||
│ │
|
||
└────────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Seguridad
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ CAPA DE SEGURIDAD │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||
│ │ Mattermost Auth │ │ NocoDB Auth │ │
|
||
│ │ ───────────────── │ │ ───────────────── │ │
|
||
│ │ Bot Token │ │ API Token (JWT) │ │
|
||
│ │ Webhook Secret │ │ Bearer Auth │ │
|
||
│ └─────────────────────┘ └─────────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────────────┐ │
|
||
│ │ Contenedor Sales Bot │ │
|
||
│ │ ───────────────────────────────────────────────── │ │
|
||
│ │ Usuario: salesbot (no-root) │ │
|
||
│ │ Filesystem: read-only donde es posible │ │
|
||
│ │ Red: bridge aislada │ │
|
||
│ └─────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Escalabilidad
|
||
|
||
```
|
||
┌─────────────────────┐
|
||
│ Load Balancer │
|
||
│ (futuro) │
|
||
└──────────┬──────────┘
|
||
│
|
||
┌───────────────────┼───────────────────┐
|
||
│ │ │
|
||
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
||
│ Sales Bot │ │ Sales Bot │ │ Sales Bot │
|
||
│ Worker 1 │ │ Worker 2 │ │ Worker 3 │
|
||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||
│ │ │
|
||
└───────────────────┼───────────────────┘
|
||
│
|
||
┌──────────▼──────────┐
|
||
│ NocoDB │
|
||
│ (PostgreSQL) │
|
||
└─────────────────────┘
|
||
```
|
||
|
||
El sistema está preparado para escalar horizontalmente gracias a:
|
||
- Gunicorn con múltiples workers
|
||
- Base de datos centralizada
|
||
- Contenedores stateless
|