bdd9319fd032755abab903d25dacf9f55b82168a
La auditoria confirma lo que se pedia verificar: la IA SOLO puede usar las tres herramientas internas. Una por llamada, ninguna se ejecuta jamas (el input del modelo solo va a schema.safeParse, no hay despachador), y no se envia ningun tool del proveedor, web search, ejecucion de codigo, MCP ni beta. Lo que NO cumplia era la otra mitad, la correspondencia con las plantillas: CRITICO - el documento cobraba un IVA que la cotizacion no cobra. Cada partida se imprimia a precio SIN IVA y debajo un unico total CON IVA, rematado con "Importes con IVA incluido", mientras el PDF economico del mismo correo dice "los precios no incluyen IVA" sobre las mismas cifras. Las lineas no sumaban su propio total. Ahora la caja de totales desglosa subtotal / IVA / total como la plantilla autorizada, las lineas siguen sin IVA igual que el otro documento, y la nota al pie dice lo que de verdad hacen las lineas. CRITICO - los avisos bloqueantes no bloqueaban nada. hayBloqueantes() no se llamaba en ningun sitio y la ruta del PDF nunca leia avisos: el documento del cliente se descargaba igual con una fuga de notas internas dentro. Ahora devuelve 409 con la lista de lo que hay que corregir. El anexo interno si se permite: es justo el que el asesor necesita para arreglarlo. ALTO - seis campos que SI se imprimen al cliente no pasaban por los filtros de marca, moneda, garantias y PII: el texto y el autor de la cita destacada, la metrica y el periodo de cada resultado, quien decide cada pendiente, y el momento del backlog. textoVisible ahora los cubre y queda documentado que debe seguir a lo que dibuja el PDF. ALTO - el plan Bucefalo se caia del documento y de sus totales, aunque si aparece en el PDF economico y en el Excel: cargarEconomia nunca leia la relacion. El cliente recibia dos documentos con alcances distintos. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Cotizador E3
Sistema de generación de cotizaciones para Consultoría E3 (marketing digital, Querétaro MX). Servicios organizados en 4 fases, dos tipos de pago (único / mensual), planes CRM Bucéfalo y financiamiento opcional. Exporta a PDF y Excel.
Stack
- Frontend / app web: Next.js 16 (App Router) + React 19 + Tailwind CSS v4 + Zustand
- ORM: Prisma 7 (cliente generado en
src/generated/prisma, driver adapterPrismaPg) - Base de datos: PostgreSQL 16 (vía Docker)
- Auth: JWT (
jose) en cookie httpOnly, contraseñas conbcryptjs - API alterna: servicio Python FastAPI en
api/(para n8n / integraciones)
Requisitos
- Node.js 20+
- Docker (para PostgreSQL)
- Un archivo
.enven la raíz — copia .env.example y define al menosJWT_SECRET
Arranque rápido (Windows)
start.bat :: levanta PostgreSQL en Docker, aplica migraciones y arranca Next.js
stop.bat :: detiene todo
Arranque manual
docker compose up -d postgres # base de datos
npx prisma migrate deploy # aplica migraciones
npx tsx prisma/seed.ts # carga catálogo (idempotente)
npm run dev # http://localhost:3000
Comandos
| Comando | Propósito |
|---|---|
npm run dev |
Servidor de desarrollo (puerto 3000) |
npm run build |
Build de producción (incluye chequeo de tipos) |
npm run lint |
ESLint |
npm run db:migrate |
prisma migrate dev |
npm run db:seed |
Carga de datos semilla |
npm run db:studio |
Prisma Studio |
npm run db:generate |
Regenera el cliente Prisma |
API Python (opcional)
cd api
pip install -r requirements.txt
uvicorn main:app --reload --port 8000 # Swagger en /docs
Referencia completa de endpoints en api/COTIZADOR_API_SKILL.md.
Despliegue en Coolify
El stack de producción está en docker-compose.coolify.yml: postgres + web (Next.js) + api (FastAPI). El contenedor web aplica las migraciones de Prisma automáticamente en cada arranque.
Pasos
- Sube el repo a GitHub (privado recomendado).
- En Coolify: + New Resource → Docker Compose, conecta el repo y la rama.
- En la configuración del recurso, define Docker Compose Location =
/docker-compose.coolify.yml. - Coolify detecta los servicios y asigna dominio a
web(puerto 3000) yapi(puerto 8000) vía las variablesSERVICE_FQDN_*— configura los dominios deseados en la UI. - Define las variables de entorno en Coolify:
| Variable | Obligatoria | Notas |
|---|---|---|
JWT_SECRET |
Sí | openssl rand -base64 32 |
API_KEY |
Sí (para el API) | Clave para agentes/n8n |
DB_PASSWORD |
Recomendada | Password de PostgreSQL (default postgres) |
RUN_SEED |
Primer deploy | true solo la primera vez; luego false |
SEED_ADMIN_EMAIL / SEED_ADMIN_PASSWORD / SEED_ADMIN_NAME |
Primer deploy | Usuario admin inicial |
SEED_ASESOR_EMAIL / SEED_ASESOR_PASSWORD / SEED_ASESOR_NAME |
No | Asesor opcional |
- Deploy. Orden de arranque:
postgres(healthy) →web(migra + seed + sirve) →api. - Después del primer despliegue exitoso, cambia
RUN_SEEDafalsey redeploya (el seed es idempotente, pero no hace falta correrlo cada vez).
Healthchecks
- Web:
GET /api/health(verifica también la conexión a la BD) - API:
GET /health
Notas
- No expongas el puerto 5432: los servicios se comunican por la red interna del compose.
- El volumen
postgres_datapersiste la base de datos entre deploys. No lo borres. - El API expone REST en
https://<dominio-api>con auth porX-API-Keyo JWT. El servidor MCP se retiro el 2026-07-28 (verAGENTS.md). - Las versiones de
api/requirements.txtestan fijas a proposito: un rango abierto dejo entrarmcp2.0.0 y tumbo el API en produccion. Sube dependencias a proposito, no al redesplegar. - La fórmula de financiamiento y los cálculos viven duplicados en
src/lib/calculators.tsyapi/app/services/calculators.py— mantenlos en paridad.
Documentación para agentes
Las convenciones del proyecto, gotchas de Prisma 7 / PDFKit / Next.js 16 y el modelo de datos
están en AGENTS.md (importado por CLAUDE.md).
Languages
TypeScript
78%
Python
21.2%
Dockerfile
0.3%
Batchfile
0.2%
CSS
0.2%