Commit Graph
75 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 8747ff950e ui: show ventas generation errors as toast in preview
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 15:38:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 531fb29122 fix: group terceros by cedula not fecha-as-factura
For terceros, _guardar_envio stores the automation date in the factura
field (not a patient id), so COALESCE(factura, cedula) still collapsed
all terceros into one row. Now GROUP BY uses cedula for tipo=terceros
and factura for transaccion/ventas. Template hides the date in the
factura column for terceros rows.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-26 21:45:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ab2ef167f9 feat: add Resumen Diario TNS page as submodule
Groups envios by factura+tipo per day and shows estado_final
(exitoso if any send succeeded, error persistente if all failed).
Supports inline reenvío and JSON detail modal. Added to sidebar
under Historial TNS and as TNS submodule link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-26 17:59:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cefc8b664b fix: automation.html usa status string (success/warning/error) no booleano ok
- Fila warning: amarillo, sin botón reenviar
- Tab 'Ya existe' en filtros para ver solo warnings
- Filtros basados en status en lugar de ok boolean
- Toast muestra conteo correcto de 3 estados

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 11:02:20 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6a452cd950 feat: sistema de 3 estados (success/warning/error) para envíos TNS
- _parse_tns_resp retorna 'success'|'warning'|'error' en lugar de bool
- 'ya existe/registrado/autorización' → warning (sin reenvío, no es error real)
- errores reales → error (con reenvío)
- Guarda JSON crudo completo en respuesta_api
- logs.html: badge amarillo para warning, verde para success, rojo para error
- Filtro de historial incluye opción 'warning'
- reenvío en logs.py solo disponible para status='error'
- reenvío en logs.py usa misma lógica _parse_tns_resp y soporta ventas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 10:45:15 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 59ee62591c chore: bajar intervalo scheduler a 20 segundos
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 12:00:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cffeae7e94 fix: parallelize WA sync and surface scheduler errors in historial
- whatsapp_sync: send patients concurrently (asyncio.gather + semaphore=10) instead of sequentially — eliminates long waits with many patients
- envios_erp: auto-refresh historial every 60s when scheduler tab is active
- main: wrap scheduler job to catch exceptions and log them to sync_wa_log so failures are visible in historial

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 11:34:30 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 599391739f feat(logs): filtro por cédula de paciente en historial de envíos
- Agrega columna cedula a tabla envios (migración automática)
- _guardar_envio almacena la cédula en los 4 pasos de automation
- pac_map (COD_PACIENTE→DOCIDENT) para RDA/preserv/ventas
- logs.py busca por cedula LIKE en vez de idrecepcion/contrato
- logs.html etiqueta el input como "Cédula paciente"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 22:37:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6cbf0732e6 feat: resolve exam prices via TARIFA+EMPRESA JOIN, show company name
- PRECIO now falls back to catalog price (TARIFA) when 0/null
- JOIN EMPRESA + EMPRESA_SUB + TARIFA in exam query
- NOM_EMPRESA propagated to log and historial display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-18 14:58:10 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 268451decc fix: render errores_det objects as readable text in historial
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:39:05 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 33e569c27a fix: historial shows error detail and correct Colombia timestamp
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:37:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 83c8b2aa0b fix: format scheduler times in Colombia UTC-5 server-side
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:31:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 12f5f1388d fix: correct column names in scheduler status query (total, errores)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:26:34 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 467a24baa4 feat: scheduler live status — endpoint + UI polling every 15s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:21:32 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9d79fe932b fix: reduce diagnosticos batch 500→200, add start_from resume param
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 15:13:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9a7e4e219b feat: add CIE-10 sync endpoint and migration button in ERP tab
- POST /envios/erp/sync-diagnosticos: reads all 12422 diagnosticos from
  Firebird, sends to WhatsApp in batches of 500 via ingest_diagnosticos.php
- envios_erp.html: new "Migración CIE-10" card with Migrar button and result

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 10:27:52 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6157d2c2f9 fix: show raw PHP response in error message, clean up errores column UI
- sync_paciente: catch JSONDecodeError separately and include HTTP status
  + first 300 chars of raw response so PHP errors are visible in the log
- envios_erp.html: Errores column shows count only (not all inline messages)
  — error detail is already visible in the expandable Ver N row

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 09:57:45 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cd63683869 feat: enrich sync log with exams, diagnosis, EPS and valor per patient
- scheduler.py: after sync_todos(), inject diagnostico, nit_empresa,
  valor_total and examenes_det (cups/nombre/precio) into each detalle entry
- whatsapp_sync.py: guardar_sync_log stores full enriched fields in detalle_json
- envios_erp.html: expanded row shows per-patient card with Dx, EPS, valor
  and a CUPS/examen/precio table — scrollable, max-h-96

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 09:52:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e044f21e3e feat: store and display per-patient sync detail in historial
- Add detalle_json column to sync_wa_log via migration
- guardar_sync_log() now stores doc, nombre, action, examenes count per patient
- Historial table shows "Ver N" button that expands a row with patient list,
  action badge (Nuevo/Actualizado/Omitido) and exam count per patient

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 09:33:46 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 dc18d128fb feat(envios/erp): add manual sync trigger endpoint and test UI
- POST /envios/erp/sync-now?ventana_min=N calls sync_recientes with configurable window
- sync_recientes() now returns a result dict (ok, total, created, updated, skipped, errores, detalle)
- ERP tab shows a "Prueba manual" card with ventana selector (2m / 30m / 2h / hoy) and result breakdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 21:40:54 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8e27225326 feat: módulos de envío TNS/ERP Lab + sync de médico, empresa y valor total
- Hub /envios/tns con 5 sub-tabs (Terceros, Transacción RIPS, Facturas Venta, Prueba RDA, Automatización) via iframe lazy
- Hub /envios/erp con sub-tabs Pacientes y Sync Automático (historial scheduler)
- Modo embed (?embed=1) en base.html para cargar páginas sin sidebar/header dentro de iframes
- Sidebar simplificado: 6 ítems individuales reemplazados por módulos TNS y ERP Lab
- Scheduler y endpoint /pacientes/examenes ahora incluyen médico ordenante (DOCIDMEDICO), empresa/EPS (NIT_EMPRESA) y valor total (VALORTOTAL) desde Firebird

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 21:13:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 31c0b71c90 fix(automation): quitar filtro por convenio del panel de control
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 15:26:55 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6dee8fba82 feat(automation): resultados con filtro Errores/Enviados/Todos y filas descriptivas
- Lista unificada reemplaza los dos paneles separados (failures/successes)
- Tabs de filtro: Errores (default si hay), Enviados, Todos — con contadores
- Filas de error: borde rojo, badge del paso, factura+paciente, mensaje inline, botón Reenviar
- Reenvío actualiza la fila en tiempo real: rojo → verde sin recarga
- btn-run solo se habilita si los pasos activos tienen datos reales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 15:12:13 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 fe31af2f9a feat(automation): paso chips, results failure-first con reenvío por item
- 4 chips toggleables (Terceros/RDA/Pre-servicios/Ventas) que controlan
  qué pasos se ejecutan en vista previa y en el envío masivo
- Backend: parámetro `pasos` en run_automation para saltarse pasos no
  seleccionados; agrega `idrecepcion`/`codigo` a cada detalle item
- Nuevos endpoints POST /automation/reenviar-tercero, /reenviar-rda y
  /reenviar-venta para reenvío individual con SQL BY_ID para cada tipo
- Panel de resultados rediseñado: barra de resumen por paso, sección
  de fallos expandida con botón "Reenviar" por item (actualiza row in-
  place), sección de exitosos colapsada por defecto

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 15:03:49 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 73062af8bc feat: paso 4 ventas en automation + fixes varios
- Automation: agrega Paso 4 (Ventas/Crear) con fetch _SQL_VENTAS,
  filtro por excluded_ventas_set, loop de envío y log de actividad
- Automation: _guardar_envio ahora almacena idrecepcion y contrato
  para que /ventas reconozca registros enviados por automation
- Contratos: corrige NameError en toggle_excluir (faltaba request: Request)
- Ventas: agrega check if not q en send_one y send para evitar TypeError
- Ventas HTML: agrega columna Contrato en la tabla de facturas
- json_generator: normaliza etnia >2 chars a '99' (ej: 999 → 99)
- json_generator: agrega campo ciudadExp usando el mismo cod_ciudad

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 14:29:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 21eb99d18d fix: agregar tipo ventas al historial de logs
Badge verde para ventas, opción en filtro de tipo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 11:57:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f103d536c7 feat: excluir_ventas independiente por contrato
- Nueva columna excluir_ventas en tabla contratos (migración automática)
- load_excluded_ventas_set() para filtrar en /ventas
- Toggle independiente en /contratos para RDA y Ventas por separado
- Modal edición con checkbox excluir_ventas
- 040 marcado excluir_rda=1, excluir_ventas=0 en seed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 11:56:28 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6b84ecfd90 feat: módulo de facturas venta (Ventas/Crear) para contrato 040
- generar_factura_venta en json_generator.py con mapeo completo del JSON
- Queries default tipo 'ventas' (por fecha y por número) filtradas a contrato 040
- Ruta /ventas con preview, send-one y send masivo
- Template ventas.html con tabla, resumen y modal JSON
- Link en navegación lateral

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 11:16:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cb3b327938 Add reenviar button in /logs for failed envios
POST /logs/reenviar/{id} re-sends stored JSON to TNS and updates
status to 'success' in-place if it succeeds. Button appears only
on error rows with saved JSON; updates row color and badge without reload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 09:24:22 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c18da17317 Fix pre-servicios preview: clear store once, clean row HTML structure
- Move _rdaJsonStore={} reset to before both sections so ps-json-* keys
  are not wiped when pacientes section renders
- Replace divide-y wrapper divs with explicit border-b on each row,
  eliminating duplicate/misplaced dividers in the pre-servicios list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 09:18:58 -05:00
Lizandro Guarnizo a47e0a843a fix: mismo patron store+textContent para JSON de pre-servicios 2026-07-10 21:35:45 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e6860a6957 fix: JSON preview recepciones via store (evita innerHTML injection)
feat: paso 1 registra terceros EPS de pre-servicios junto a particulares

- _rdaJsonStore guarda JSON por key, toggleRdaJson usa textContent
- escHtml() para caracteres especiales en diagnostico
- _SQL_PACIENTES_EPS obtiene pacientes de PRESSERV_DIAN
- rows_pac_todos fusiona particulares + EPS deduplicando por CODIGO

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 21:33:00 -05:00
Lizandro Guarnizo ef02303dde feat: mostrar JSON de recepciones paso 2 en preview (expandible) 2026-07-10 21:25:22 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9f2bd5164e feat: opcion 'sin contrato' para enviar numeroContrato null en TNS
- Agrega columna sin_contrato en tabla contratos (migration automatica)
- Contrato 040 marcado excluir=0, sin_contrato=1 en seed
- load_sin_contrato_set() retorna contratos que deben ir con null
- generar_rda_paciente acepta sin_contrato_set y fuerza numeroContrato=null
- Automation paso 2 y 3 pasan sin_contrato_set al generador
- Pagina contratos: columna y toggle "Sin contrato", checkbox en modal editar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 21:22:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 648a0a1910 feat: preview muestra lista de pre-servicios con JSON expandible
- Agrega preservicios_preview al endpoint /preview con el JSON generado por cada RCXC/SC
- Muestra sección naranja debajo de pacientes con factura, fecha, paciente y exámenes
- Clic en cada fila despliega el JSON completo que se enviará a TNS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 20:47:58 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c2a092c0e7 feat: paso 3 pre-servicios RCXC/SC y limpieza de código copago
- Agrega paso 3 en automatización: envía RDA desde PRESSERV_DIAN (prefijos RCXC/SC) para pacientes EPS con PS_NUM IS NOT NULL
- Filtra paso 2 con PS_NUM IS NULL para separar particulares/empresas de EPS
- Elimina parámetro copago y función _calcular_descuento_pct (código muerto)
- Limpia referencia a d.copago en automation.html (UI paso 3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 20:43:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c20e1a7476 feat: log de actividad por usuario
- Tabla activity_log en SQLite (migración automática)
- Registra: login, login_fallido, rda_enviado, rda_masivo, rda_directo,
  automation_run, contrato_creado, contrato_editado, contrato_toggle
- Endpoint GET /logs/actividad con filtros por usuario, acción y fecha
- UI /logs/actividad con badges de color por tipo de acción
- Enlace "Actividad" en navegación lateral

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 17:11:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 eb9c57b324 feat: botón re-enviar en registros ya enviados en /transaccion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 16:12:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 02d251685e feat: mostrar contrato en vista previa de recepciones en automation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 15:52:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 200a3f550b feat: excluir contratos del envío TNS
- Columna excluir en tabla contratos (migración automática)
- 25 contratos nuevos sembrados con excluir=1 (laboratorios externos, clínicas, médicos particulares)
- load_excluded_set() en contratos.py para consultar el set en runtime
- preview: marca items excluidos y los reporta en el conteo
- send/send-one/send-direct: bloquea envío si contrato está excluido
- automation preview+run: filtra excluidos antes del loop, reporta count
- UI /contratos: columna Envío TNS con toggle Activo/Excluido, fila en rojo si excluida

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 15:44:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3baa6e5f75 feat(transaccion): envío RDA directo por prefijo + número de factura
Nuevo endpoint POST /transaccion/send-direct y panel "Enviar RDA directo"
en la UI: ingresa Tipo (prefijo) y Número, busca en Firebird y envía a TNS
sin necesidad de rango de fechas ni pasar por el flujo de preview.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 15:10:41 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0f3a760de4 feat(contratos): tabla de contratos con tipo_usuario por contrato
Agrega tabla `contratos` en SQLite sembrada con los 17 contratos del
laboratorio. `generar_rda_paciente` consulta el mapa contrato→tipoUsuario
como primera prioridad antes de derivar de TIPOUSU/TIPOUSUSISPRO.
Incluye CRUD en /contratos con UI en sidebar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 15:00:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b0175a2ca5 feat(sync-log): historial de sincronizaciones WhatsApp en sync_wa_log
- Nueva tabla sync_wa_log (total, created, skipped, updated, errores, origen, modo)
- Log guardado en /pacientes/sync-all, /terceros/send y /automation/run
- Ruta GET /pacientes/historial devuelve últimos 100 registros
- UI: tabla de historial con origen, modo, conteos y detalle de errores

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:13:28 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1aab14f705 feat(pacientes): modo insertar en sync-all — solo crea nuevos, omite existentes
sync_todos() ahora acepta modo='insertar'|'upsert'. La ruta /pacientes/sync-all
usa insertar: skippea cédulas que ya están en lab_pacientes. Los hooks
automáticos (terceros/automation) siguen en upsert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:06:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e7c6bc794a feat(pacientes): sync de pacientes Firebird → WhatsApp Lab
- Nuevo servicio whatsapp_sync.py: mapeo de campos RIPS→lab_pacientes
  y cliente HTTP para /api/lab/ingest_paciente.php
- Nueva ruta /pacientes con sync masiva por rango de fechas o todos
- Hook en /terceros/send y /automation/run: sync silencioso a WhatsApp
  después de cada envío a TNS
- Config: campos whatsapp_url y whatsapp_api_key + botón probar conexión

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 10:49:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b3b283a7d0 fix: syntaxHighlight regex adding spaces inside time values
The number regex /:(\s*)(\d+)/ was matching colons inside time strings
like "14:51:26" turning them into "14: 51: 26". Changed to require the
space that JSON.stringify always adds after key-value colons (": \d+")
so colons inside string values are not affected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 17:41:37 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 69372a5673 Agrega filtro convenio en automation/transaccion/test-rda y fix particular (contrato 12)
- automation: filtro contrato en SQL pacientes+RDA, numero LHXC en run()
- transaccion: filtro contrato en preview/send-one/send
- test-rda: filtro tipo_usuario (11/07/12), default contrato "12", acepta "12"/"012"
- json_generator: detecta particular por CODCONTRATO "12"/"012" además de NIT_EMPRESA PART; fuerza tipousuario="12", codFormaPago="CLIP", plazoDias="0"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:23:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7e0c6039b8 Fix profesionalRemisionante con slash y mejora display resultado test-rda
- json_generator: limpia DOCIDMEDICO a solo dígitos (eg "9410/86" → "941086") para que TNS acepte el código
- test_rda.html: resultado con syntax highlight en JSON enviado y respuesta TNS, mejor legibilidad del error TNS, botones Resp.TNS y JSON env. con íconos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:44:46 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7699303a53 Mejora Transacción y Historial: estado por fila, envío individual y filtros avanzados
- Transacción: tabla con estado Enviado/Pendiente/Error por IDRECEPCION, botón enviar fila a fila o masivo, modal con JSON + respuesta TNS por registro
- Historial: filtros por fecha, tipo, IDRECEPCION/contrato; paginación 50 por página; modal con 3 tabs (JSON enviado / Respuesta TNS / Mensaje)
- DB: migración automática para agregar columnas idrecepcion, contrato, mensaje_tns a tabla envios
- Logs route: nuevo endpoint /logs/detalle/{id} para cargar detalle completo vía JS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:40:11 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ef71a1db56 test-rda: add preview, ver más pagination, sent tracking, default contrato=011
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:32:53 -05:00