Cierra la funcionalidad: el Cotizador ahora ofrece tres descargas por cotizacion
—Excel, PDF economico y PDF consultivo con marca— mas un anexo interno aparte.
Rutas: POST genera, GET lee la ultima, PATCH guarda la edicion del asesor
(revalidando, porque una edicion manual puede introducir una fuga o un USD), y
GET /pdf descarga, con ?anexo=1 para el interno.
Panel: transcripcion opcional, avisos de validacion, campos editables (titulo,
subtitulo, hallazgos, alcance, exclusiones y beneficios) y las descargas.
Los avisos van deliberadamente ARRIBA de los botones de descarga: el objetivo es
que revisar sea mas facil que aprobar.
El anexo interno lleva la ponderacion: ratio precio/valor sobre el desembolso
del primer ano con IVA, su lectura (subcotizado / en rango / alto / objecion
probable), conteo de hallazgos y evidencia, red flags y notas para el asesor.
Va en archivo separado con banda roja "NO ENVIAR", nunca como seccion oculta.
Verificado con 6 suites (114 comprobaciones), typecheck, lint y build. Las mas
importantes son las estructurales: ningun schema declara un campo de dinero de
E3, ningun prompt filtra precios ni cuids, y el documento del cliente no
contiene notas internas ni red flags aunque se inyecten a la fuerza.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
MCP: se retira por completo (endpoint, paquete api/app/mcp/ y dependencia).
Tres razones, en orden de peso:
- Nadie lo usa.
- Llevaba roto desde antes de este trabajo. Con credencial valida devolvia 500:
el handler construia un StreamableHTTPServerTransport nuevo por peticion, sin
manejo de sesion. Lo que estaba expuesto a internet era la puerta abierta de un
cuarto averiado.
- Su SDK sin fijar tumbo el API entero en produccion al saltar a 2.0.0.
Retirarlo es una mitigacion mas fuerte que autenticarlo, que fue lo que hizo el
commit anterior. Recuperable con `git show edb500f5:api/app/mcp/server.py`.
Se limpia tambien la ruta "/mcp" que el endpoint raiz seguia anunciando, y las
menciones a MCP del docstring y la descripcion de Swagger.
Dependencias: once de las doce eran rangos `>=` sin techo, o sea que cada
reconstruccion era una tirada de dados contra PyPI. `pydantic>=2.0` habria
aceptado pydantic 3 con la misma alegria con la que `mcp>=1.0.0` acepto 2.0.0.
Ahora todas van fijadas a la version exacta que corre sana en produccion,
capturada con pip freeze del contenedor healthy.
El lado Next.js ya era reproducible via package-lock.json; por eso el web nunca
se cayo durante el incidente y el api si.
Docs actualizados: AGENTS.md, README.md, api/COTIZADOR_API_SKILL.md y el spec,
que ademas registra en su seccion 0 las tres desviaciones de Fase 0 respecto a
lo disenado (el Despliegue B cancelado, la retirada del MCP y la deriva de
dependencia).
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Convierte el análisis de negocio de docs/BI-propuesta-consultiva-IA.md en una
especificación cerrada para las dos primeras fases del roadmap.
El análisis previo destapó cuatro problemas que el documento de negocio no
anticipaba, los cuatro verificados en disco:
- POST /mcp no tiene autenticación (api/main.py:107) y _obtener_cotizacion hace
SELECT c.* sin lista blanca, con dominio público en producción. Publicaría la
columna de notas internas sin tocar una línea de código.
- No existe una fuente de verdad para los totales: el cálculo está duplicado en
siete consumidores y el IVA está hardcodeado como * 1.16 en PDF y Excel.
- El Excel es un documento del cliente, no una herramienta interna. El diseño
inicial proponía poner ahí las notas internas; se corrigió.
- Las transcripciones se sincronizarían a la nube de MEGA: .megaignore solo
excluye .next, node_modules y .turbo.
También reconcilia nueve contradicciones de contrato entre los diseños
explorados (clave de partida, forma de la evidencia, nombres del valor anual)
que habrían hecho que la capa de validación validara el vacío.
Actualiza AGENTS.md, que había quedado desfasado: 14 modelos y 10 migraciones
(decía 13 y 3), el registro de horas, la doble propuesta, los modelos de cobro
y la convención de no usar diálogos nativos del navegador.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>