docs(crm): abre el changelog del repo y versiona el plan de T2026-08-046
El CRM no tenia CHANGELOG.md. Se crea con el formato del de EFC para que un ticket que cruza los dos productos se lea igual de los dos lados, y se abre con la entrada de T2026-08-046 (fases 5-7). Va en un PR aparte del codigo a proposito: el changelog es el unico archivo garantizado en colision entre tickets, y metido en cada PR de codigo convierte cada merge en una resolucion de conflictos en vez de una revision. La entrada dice tambien lo que NO esta: el lado de EFC del carril todavia no aterriza, las variables de entorno de produccion quedaron sin tocar y el contrato entre repos esta afirmado solo desde el CRM. Un changelog que afirma un entregable completo cuando esta a medias es peor que ninguno. Se versiona ademas el documento Prompt del ticket en docs/planes/, siguiendo la convencion de EFC, para que las decisiones del codigo tengan su porque a la vista sin depender de una carpeta de corrida. Un dato se sustituyo al versionar: un caso de prueba traia un token con forma de llave de pedimento real y aqui va como dummy; el caso prueba que esa FORMA se rechace, asi que el numero concreto no aportaba nada. Refs: T2026-08-046
This commit is contained in:
90
CHANGELOG.md
Normal file
90
CHANGELOG.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Changelog — CRM Agentes de Carga
|
||||
|
||||
Historial de cambios por ticket (más reciente arriba). Cada entrada: fecha, ticket, tipo, repos
|
||||
afectados, qué se hizo y por qué. El formato es el mismo que el de `EFC/backend/CHANGELOG.md`, para
|
||||
que un ticket que cruza los dos productos se lea igual de los dos lados.
|
||||
|
||||
Este archivo lo abre la corrida SUNRISE del 2026-08-07: el repo no tenía changelog. Las entradas
|
||||
llegan en un PR de documentación aparte, nunca dentro del PR de código — el `CHANGELOG.md` es el
|
||||
único archivo garantizado en colisión entre tickets, y metido en cada PR convierte cada merge en una
|
||||
resolución de conflictos.
|
||||
|
||||
---
|
||||
|
||||
## T2026-08-046 (feature, fases 5-7) — Expediente electrónico del CRM y entrega de documentos a EFC
|
||||
|
||||
- **Fecha:** 2026-08-07
|
||||
- **En corto:** Cada solicitud de servicio nace ya con su expediente y su folio propio, que el usuario
|
||||
ve en cuanto guarda. Los documentos de un embarque se adjuntan en un solo paso y viajan solos al
|
||||
expediente electrónico; si ese sistema no responde, el documento **no se pierde**: se queda guardado
|
||||
aquí, la pantalla lo muestra como pendiente de enviar, y se entrega solo cuando el otro lado vuelve.
|
||||
Quien lo necesite puede abrirlo desde el CRM aunque el archivo ya viva del otro lado.
|
||||
- **Tipo:** feature
|
||||
- **Repos:** CRM (backend + frontend). **Las fases 1-4, del lado de EFC, son de otra corrida y todavía
|
||||
no están** — ver «Lo que falta» al final de la entrada.
|
||||
- **Branch:** `feature/T2026-08-046` · **PR:** (pendiente de abrir a mano)
|
||||
- **Inicio:** 2026-08-07T17:40:46 · **Fin:** 2026-08-10T08:00 (la corrida estuvo tres días en pausa
|
||||
entre medias; el detalle está en `SUNRISE/2026-08-07/Diario-2026-08-07.md`)
|
||||
- **Con dos migraciones, generadas y SIN aplicar:** `e6f7a8b9c0d1_crm_expedientes.py` y
|
||||
`f7a8b9c0d1e2` (el outbox del carril). `alembic heads` devuelve **una sola hoja** después de las
|
||||
dos; el `down_revision` se verificó con `alembic heads`, no se supuso.
|
||||
|
||||
- **Contexto:** el CRM guardaba los documentos de sus embarques en su propio almacén y ahí se
|
||||
quedaban. El expediente electrónico —donde de verdad se consultan— vive en EFC, así que había que
|
||||
volver a subir cada documento a mano del otro lado, o no subirlo. Y el enlace entre un expediente
|
||||
del CRM y un pedimento de EFC no podía colgarse de una columna nueva en la tabla de pedimentos: el
|
||||
expediente del CRM nace **antes** de que exista pedimento alguno.
|
||||
|
||||
- **Qué se hizo:**
|
||||
- **El expediente y su folio.** Una solicitud de servicio crea su expediente en la misma
|
||||
transacción del alta: si algo falla, no queda ni la solicitud ni un folio quemado. El consecutivo
|
||||
lo lleva un contador con bloqueo por `(cliente, empresa, mes)` que **reinicia cada mes**, en una
|
||||
sola sentencia atómica —sin leer-modificar-escribir— para que dos altas simultáneas no puedan
|
||||
sacar el mismo número. La restricción de unicidad del folio lo garantiza aunque el contador
|
||||
fallara.
|
||||
- **El carril de entrega hacia EFC.** Clon del carril que ya usa Anexo22, con sus tres capas de
|
||||
reintento: el cliente HTTP reintenta lo transitorio y **corta en seco** ante un error del
|
||||
llamador, la fila pendiente se reintenta con límite de intentos, y un barrido periódico recoge lo
|
||||
que se quedó atrás. Cuatro capas de idempotencia impiden que un reintento duplique un documento
|
||||
del otro lado. **La llamada a EFC nunca ocurre dentro de la petición del usuario**: se encola y se
|
||||
despacha.
|
||||
- **La subida de un paso y el proxy de descarga.** Adjuntar un documento guarda, registra y encola
|
||||
en una sola operación, y responde **aunque EFC esté apagado**. Para abrirlo, el CRM hace de proxy
|
||||
con streaming: el otro sistema nunca entrega una dirección de descarga reutilizable, y reescribir
|
||||
una dirección ya firmada la invalida.
|
||||
- **La pantalla.** La ficha del embarque muestra cada documento con su estado —«Pendiente de
|
||||
enviar», «En expediente», «No se pudo enviar»— y un botón para reintentar el envío cuando algo
|
||||
falló, sin que nadie tenga que entrar a la base.
|
||||
|
||||
- **Tres defectos preexistentes corregidos de paso**, todos en la subida de archivos y todos
|
||||
autorizados por el ticket: un archivo se leía **entero en memoria** antes de comprobar si excedía el
|
||||
tamaño máximo (un archivo de 2 GB se bufferizaba solo para rechazarlo); no había lista de
|
||||
extensiones permitidas, a diferencia del avatar y del centro de ayuda, que sí la tienen; y firmar
|
||||
una dirección de descarga solo comprobaba el prefijo de la empresa, lo que permitía alcanzar
|
||||
**cualquier** objeto de esa empresa —facturas, certificados, importaciones— con el permiso más
|
||||
básico del CRM.
|
||||
|
||||
- **Un defecto propio, encontrado y corregido antes de mergear:** el proxy de descarga comprobaba la
|
||||
respuesta de EFC **demasiado tarde**, ya dentro del envío del archivo. Para entonces la respuesta
|
||||
del CRM ya había salido como «correcta», así que un documento que EFC no encontraba llegaba al
|
||||
usuario como un archivo vacío en vez de como un error. Ahora la comprobación ocurre antes de
|
||||
empezar a responder. Lo destapó una prueba que el ticket pedía y que la fase original no dejó
|
||||
escrita.
|
||||
|
||||
- **Verificación:** `pytest tests/ -q` → **215 pasan, 1 se salta**, contra las 70 del punto de
|
||||
partida; ningún rojo nuevo. En el frontend, la revisión de tipos y las pruebas unitarias quedan
|
||||
**exactamente** en los mismos números rojos que ya tenían antes de este trabajo (38 y 2, ambos
|
||||
heredados y ajenos al ticket). Cada verde se vio fallar primero: seis roturas deliberadas,
|
||||
comprobando que la prueba se pusiera roja nombrando lo que faltaba, y restauradas.
|
||||
|
||||
- **Lo que falta, y hay que saberlo antes de mergear:**
|
||||
- **El lado de EFC (fases 1-4) no está.** Sin él, el carril entrega a un endpoint que todavía no
|
||||
existe: los documentos se guardan en el CRM y quedan «pendientes de enviar» hasta que aterrice.
|
||||
Eso es degradar limpio, no romper — pero nadie debería mergear esto creyendo que el circuito está
|
||||
cerrado de los dos lados.
|
||||
- **Las variables de entorno de producción no se tocaron.** El worker y el proceso periódico de
|
||||
producción no ven la dirección de EFC, así que allá el carril queda **apagado** hasta que alguien
|
||||
las agregue a mano. Está en la lista de pasos manuales del reporte de la corrida.
|
||||
- **El contrato entre los dos repos está afirmado solo de este lado.** El archivo que lo describe
|
||||
vive en el CRM y la suite del CRM lo comprueba; EFC debe afirmar su mitad contra una copia
|
||||
idéntica cuando lleguen sus fases.
|
||||
1470
docs/planes/T2026-08-046_prompt.md
Normal file
1470
docs/planes/T2026-08-046_prompt.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user