- CRM: Leads, Oportunidades, Apartado, Actividades - Ventas: Unidades, Ventas, Flujo Escrituras, Saldos a Favor - Postventa: Comunicación (tablero nuevo, id 18429259043) - Generales: Contactos, Motivos No Compra, Desarrollos Los boards se movieron con update_board_hierarchy (folder_id)
123 lines
6.6 KiB
Markdown
123 lines
6.6 KiB
Markdown
# 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)
|
|
|
|
```bash
|
|
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
|
|
- **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.
|