ConTodo
Plataforma / DevOps

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).
  • 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

NecesidadHerramienta (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 + cAdvisorCloudWatch
Logs centralizadosGrafana Loki + PromtailCloudWatch Logs
Errores de la appSentry (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)

  1. Fase 1 (hecha): Postgres multi-tenant + API ventas (precio final) + auth por API key.
  2. Auth de usuarios (login, sesiones) + RBAC real + panel admin conectado a BD.
  3. Archivos: MinIO + subida de fotos de entrega + export CSV/PDF por job.
  4. Cache + colas (Redis + pg-boss/BullMQ): rate-limit IA, jobs SUNAT/PDF/recordatorios.
  5. SUNAT (boletas/facturas/guías) vía PSE/OSE.
  6. Reportes: vistas materializadas → réplica de lectura cuando pese; Flai sobre la réplica.
  7. Monitoreo: Uptime Kuma + Netdata (+ Sentry).
  8. 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]].