Infra y operación: reportes/cache/jobs/archivos/monitoreo/accesos
Infra y operación (responde: reportes, cache, jobs, archivos, monitoreo, accesos)
Estado: backend Fase 1 ya corriendo en el VPS (app + Postgres, API
/api/v1, multi-tenant, venta con precio final + IGV real). Esto define cómo crece sin romperse.
1. ¿Separar reportes de transacciones y sincronizarlos? — Sí, pero por etapa
- Hoy (1 tenant / pocos usuarios): NO hace falta otra base. Una sola Postgres + vistas materializadas para reportes ya aísla lo pesado.
- Cuando el bot/reportes pesen: agregar una réplica de lectura de Postgres. La sincronización es automática (streaming replication nativa de Postgres) — no se sincroniza a mano.
- El bot/Flai y los reportes consultan la RÉPLICA; las escrituras (ventas, guías) van a la primaria. Así una consulta pesada no tumba la transaccional.
2. Cache (Redis) — sí, lo incluimos
Para qué: respuestas frecuentes del bot, sesiones, rate-limit por tenant (cuidar la capa gratuita de IA), y colas de jobs.
- En el VPS: agregar un contenedor redis al
docker-compose(interno, sin puerto público). - En AWS: ElastiCache.
3. Jobs / colas — sí
Para tareas que no deben bloquear la operación: emisión SUNAT, generar CSV/PDF, recordatorios de cobranza, conciliación de pagos, refresco de reportes.
- Opción A:
pg-boss(colas sobre la misma Postgres) — cero infra extra, ideal para empezar. - Opción B:
BullMQ(sobre Redis) — más potente cuando crezca.
4. Archivos: fotos de entrega, CSV y PDF — dónde van
- Almacenamiento: un bucket (no en la BD).
- En el VPS: MinIO (S3-compatible, contenedor) o un volumen
/opt/contodo-data/uploads. - En AWS: S3 (mismo código, solo cambia el endpoint).
- En el VPS: MinIO (S3-compatible, contenedor) o un volumen
- Fotos de entrega (WhatsApp): el webhook descarga la media → guarda en el bucket → liga la URL a la entrega (
deliveries.photo_url, ya está en el esquema). - CSV: se genera al vuelo (ya hay export CSV en la app) o por job si es grande.
- PDF: generado por job (p. ej. Puppeteer/pdfkit) → se guarda en el bucket → link de descarga.
5. Monitoreo y observabilidad — sí, una herramienta para ver TODA la infra
| Necesidad | Herramienta (VPS) | En AWS |
|---|---|---|
| ¿Está arriba? (uptime, alertas) | Uptime Kuma (contenedor) | Route53 health checks |
| Métricas de servidor/contenedores (CPU/RAM/IO) | Netdata o Grafana + Prometheus + cAdvisor | CloudWatch |
| Logs centralizados | Grafana Loki + Promtail | CloudWatch Logs |
| Errores de la app | Sentry (SaaS, free tier) | Sentry / X-Ray |
Recomendación VPS: Uptime Kuma (alertas si algo se cae) + Netdata (métricas en vivo) — ambos como contenedores Docker, sin tocar tus otros servicios. Te dan una vista de toda la infra (incluido recuperamas, mail, etc.).
6. Logs y gestión de acceso (tenant-admin y super-admin)
- Auditoría (
audit_log, ya creada): quién hizo qué, por tenant. La ve:- el admin del tenant → solo SU empresa,
- el super-admin → todas + impersonación.
- Gestión de acceso: RBAC por rol; el admin del tenant gestiona usuarios/roles/flags de su empresa; el super-admin gestiona planes, consumo IA y estados (panel
/admin). - Logs de la app → a Loki/CloudWatch; los de negocio (auditoría) → en la BD por tenant.
7. Cómo queda el docker-compose (VPS) al sumar todo
Todo como contenedores nuevos, sin tocar nginx/SFTP/mail/recuperamas. Migración a AWS:
redis→ElastiCache,minio→S3, réplica→RDS read replica, monitoreo→CloudWatch.
8. Roadmap actualizado (orden sugerido)
- ✅ Fase 1 (hecha): Postgres multi-tenant + API ventas (precio final) + auth por API key.
- Auth de usuarios (login, sesiones) + RBAC real + panel admin conectado a BD.
- Archivos: MinIO + subida de fotos de entrega + export CSV/PDF por job.
- Cache + colas (Redis + pg-boss/BullMQ): rate-limit IA, jobs SUNAT/PDF/recordatorios.
- SUNAT (boletas/facturas/guías) vía PSE/OSE.
- Reportes: vistas materializadas → réplica de lectura cuando pese; Flai sobre la réplica.
- Monitoreo: Uptime Kuma + Netdata (+ Sentry).
- Migración progresiva a AWS cuando el volumen lo justifique.
9. Datos grandes: paginación, lazy load, batch y mobile-first
Regla: nunca cargar todo de golpe. Siempre por páginas/lotes.
Paginación (dónde va)
- En la API (capa de datos):
?limit=&offset=con tope de 1000 por página (ya implementado en/api/v1/ventas). Para tablas muy grandes → keyset/cursor (created_at < ?) que es más rápido que offset alto. - En la UI: la tabla pide solo la página visible (100/500/1000 configurable) y trae la siguiente al hacer scroll/click.
Lazy load / virtualización
- La tabla renderiza solo las filas visibles (virtual scroll) aunque haya 50k registros → no traba el navegador (clave en móvil).
- Los dashboards/Flai consultan la réplica (no la transaccional) y con agregados, no fila por fila.
Exportes grandes (CSV/PDF) por BATCH
- Para miles de filas, el export corre como job que lee por lotes (1000 en 1000), va escribiendo el archivo, y al terminar deja un link de descarga (no bloquea la pantalla).
Mobile-first 📱
- La app ya es responsive (se ve en cualquier navegador móvil). Profundizamos mobile-first porque los vendedores y repartidores trabajan desde el celular:
- Toma de pedido rápida en móvil (precio final, pocos toques).
- Repartidor: lista de entregas + marcar entregado + foto + ubicación desde el celu.
- Flai por WhatsApp (el canal más móvil).
- En el roadmap: revisar cada pantalla en móvil y priorizar las de campo.
Relacionado: [[27-arquitectura-datos-dashboards]] · [[20-roadmap-backend]] · [[28-auditoria-roles-limites]] · [[26-despliegue-costos-admin]].