Consult AS Technology 895a831ff8 feat(mi-dia): seccion 'Mis capturas de afluencia' en el panel del vendedor
Nueva tabla LeadCaptura (quien capturo cada lead, algo que Monday no
guarda porque el creador del item siempre es el token del API). El
POST /api/leads la registra con el usuario del token y el resumen de
Mi dia la enriquece con el estado/origen actual del lead en Monday.
La captura rapida refresca el panel al registrar.
2026-09-02 02:13:13 +00:00

FRASA Ecosystem

Ecosistema comercial de Frasa Desarrollos S.A.P.I. de C.V.

Componentes

Componente Ruta Descripción
apps/landing / Entrada al ecosistema
apps/cotizador /quote/ Cotizador financiero (4 propuestas, PDF ANEXO A)
apps/alta-clientes /client/ Alta de clientes (wizard, firma digital, PDFs PLD)
apps/cobranza /pay/ Planes de enganche, vencidos, estados de cuenta
apps/dashboards /dash/ Tableros KPI (leads, oportunidades, inventario, cobranza)
apps/mi-dia /hoy/ Agenda del vendedor (mis leads, actividades, acciones CRM)
apps/agente-ia /ai/ Asistente IA con documentos del ecosistema
api-gateway /api/ Express 5 + Prisma + integración Monday.com

PWA (instalabilidad básica)

Las 7 apps son instalables (manifest + íconos): cada una tiene public/manifest.webmanifest ("Frasa · <app>", display: standalone, theme_color/background_color) e íconos 192/512 en public/icons/ (generados con scripts/generar-iconos-pwa.py, venv /root/.venv-tools).

Decisión: NO hay service worker. Solo se busca instalabilidad básica (ícono en el teléfono que abre la app a pantalla completa). Un SW con caché arriesga servir bundles viejos tras cada deploy (los usuarios son vendedores en campo; no van a limpiar caché a mano). Si algún día se quiere modo offline, hay que diseñar primero la estrategia de invalidación de caché.

Desarrollo local

Cada app es un proyecto Vite independiente: npm install && npm run dev (o npm run preview tras npm run build). Tests: npx vitest run en cada paquete. El API: cd api-gateway && npm install && npx prisma migrate dev && npm run dev.

Variables de entorno: copiar .env.example a .env y completar (el .env nunca se commitea).

Servidor actual (LXC sin Docker)

Esta máquina es un contenedor LXC sin nesting: Docker no puede correr contenedores. El stack corre directo en el host:

  • NGINX (apt) sirve los dist/ de las apps y proxifica /api/ → 127.0.0.1:3000. Config: deploy/nginx-host.conf → /etc/nginx/sites-available/frasa.
  • API como servicio systemd: deploy/frasa-api.service → frasa-api.service (systemctl status frasa-api, logs en /var/log/frasa-api.log).
  • Rebuild de apps tras cambios: VITE_API_URL=/api npm run build en cada app + systemctl reload nginx (no requiere restart).

Acceso público: Cloudflare Tunnel

El stack se expone en https://frasa.consultoria-as.com mediante Cloudflare Tunnel (Zero Trust), sin abrir puertos ni depender del DDNS:

  • Túnel administrado desde el dashboard (Zero Trust → Networks → Tunnels); el ingress vive en Cloudflare: public hostname frasa.consultoria-as.com → http://localhost:80. No hay config.yml local.
  • Servicio systemd cloudflared (instalado con cloudflared service install <token>, token en /etc/cloudflared/token). SSL lo termina Cloudflare automáticamente; Certbot ya no aplica en este servidor.
  • NGINX de host sigue en puerto 80 con server_name _ (catch-all), así que cualquier hostname del túnel funciona sin cambios.
  • Las ligas de firma remota se construyen con window.location.origin, así que ya salen con el dominio público al usarlas desde ahí.

El docker-compose.yml queda listo para cuando el stack se mude a una VM con Docker.

Deploy con Docker (VM futura)

git clone https://git.consultoria-as.com/consultoria-as/FRASA-CAS.git /opt/frasa-ecosystem
cd /opt/frasa-ecosystem
cp .env.example .env && nano .env        # completar secretos

# SSL: webroot (funciona con nginx corriendo y renueva sin downtime)
docker compose up -d nginx               # primer arranque SIN ssl: ver nota abajo
certbot certonly --webroot -w /var/www/certbot -d frasadesarrollos.ddns.net

docker compose build && docker compose up -d
docker compose logs -f api
curl https://frasadesarrollos.ddns.net/api/health

Modo local sin SSL (LAN): .env con NGINX_CONF=nginx.http.conf hace que NGINX sirva todo por HTTP en el puerto 80. Cuando el DDNS apunte a este servidor: certbot certonly --webroot -w /var/www/certbot -d frasadesarrollos.ddns.net, quita NGINX_CONF del .env (vuelve nginx.conf con 443) y docker compose restart nginx. Renovación: certbot renew --deploy-hook "docker compose -f /opt/frasa-ecosystem/docker-compose.yml restart nginx".

Backup: scripts/backup.sh (cron sugerido 17 2 * * *).

Monday.com

Workspace Frasa-CAS, organizado en carpetas como el CRM original del cliente:

  • CRM: Leads, Oportunidades, Apartado, Actividades
  • Ventas: Unidades (inventario), Ventas, Flujo Escrituras, Saldos a Favor, Cobranza, Seguimiento Preventa
    • Cobranza (board 18429260549) y Seguimiento Preventa (board 18429260580): estructura replicada del CRM anterior, sin flujo automático por ahora. Creados por API; pendiente moverlos a la carpeta Ventas (folder 21263260) a mano en la UI.
  • Postventa: Comunicación (bitácora postventa: unidad, canal, estado, fecha)
  • Generales: Contactos, Motivos No Compra, Desarrollos

Los board IDs están en .env.example. Webhook: POST /api/webhooks/monday (responde el challenge de activación).

Board Unidades — columnas de obra/estatus

Alimentadas por api-gateway/scripts/sync-obra-estatus.py desde el Reporte_EstatusVenta.xlsx del cliente (idempotente, --dry-run disponible; ver docstring del script):

  • % Avance obra, Meses atraso (numbers), Contratista, Clave catastral, No. oficial, Vendedor, Broker (text), Venc. autorización (date).
  • Fecha entrega obra (date): la columna original Fecha entrega ya traía datos de habitabilidad, por eso se creó una nueva.
  • Hitos documentales (checkbox): Cert. Gas, TO / C4, Régimen inscrito, Lista avalúo. Se encienden cuando la fecha del hito en el Excel ya pasó; el script nunca los apaga.
  • Nota: en No. oficial / Clave catastral el Excel del cliente trae fechas programadas (no números oficiales); se cargan como texto ISO tal cual.

Boards operativos nuevos

  • Flujo Escrituras: un item por mes/semana/proyecto con Escrituras (numbers) e Ingreso (numbers) del Flujo Calendario del cliente. Idempotencia por nombre único (AGOSTO SEM 3 AL 7 - SOLE).
  • Saldos a Favor: name CLIENTE / UNIDAD; columnas Desarrollo (status), Unidad (text), Monto (numbers), Estado (Pendiente/Devuelto), Comentario. Idempotencia por Unidad+Desarrollo.

Las unidades SOLE y MUTUO no existen en el board Unidades: el script las reporta como saltadas (sus vendedor/broker/venc. autorización no se cargan por ahora).

Pendientes conocidos

  • Migrar Prisma de SQLite a Postgres 16 (dinero a Decimal).
  • Auth JWT, helmet, rate-limit, CORS restringido (hoy: red interna).
  • Self-hostear worker/wasm de tesseract.js (OCR sin internet).
  • Automatizaciones Monday (round-robin, recordatorios 10 días) y cron de cobranza en el API.
Description
Integracion de operacion con monday para los departamentos de Cobranza, Ventas y Servicio al cliente de FRASA DESARROLLOS
Readme 14 MiB
Languages
TypeScript 94.9%
Python 2.8%
JavaScript 1.9%
CSS 0.2%
HTML 0.1%