- F0 blindaje: Redis/Celery, pg_hba sin trust LAN, secretos a env 600, backups, webhook auth, jobs muertos - F1 caja: bugs POS, reembolsos al corte, apartados, CFDI, topes de descuento en cotizacion/apartado - F2/F7 IA de catalogo: autocategorizacion, dedup de SKUs con embeddings, OCR de facturas, descripciones, claves SAT, limpieza de fitment - F3 IA en el flujo: vision Yonke, preguntas MeLi, venta cruzada, anomalias, sinonimos, busqueda semantica (rerank/embeddings) - F4/F8 escala y cartera: /metrics+Prometheus+Grafana, pool, score de credito, churn, metricas multi-tenant - Nexus Yonke (M1-M6): modelo de datos 1-de-1, alta por donador, vitrina publica, MeLi usado, consignacion, garantia por dias, reportes, etiquetas - Marketplace B2B entre yonkes (catalogo + pedidos cross-tenant) - Seguridad: auth en /api/admin/* (35 endpoints), alertas por tenant - Migraciones v4.27/v4.28; timers expire-demos y rollup-metrics
12 KiB
Auditoría #2 — Mejoras y IA no conversacional (post F0–F4)
Fecha: 11-oct-2026 · Base: 5 investigaciones nuevas con evidencia en
archivo:línea, SQL real y estado del host. Contexto: segunda pasada sobre el estado ya mejorado (F0–F4 hechos). Busca la capa que falta, incluidas regresiones y puntos ciegos de la primera pasada.
0. Resumen ejecutivo
La primera pasada dejó una base sólida, pero esta segunda encontró regresiones y puntos ciegos:
Corregido YA en esta pasada:
- Redis caído otra vez (18:31 UTC):
redis.confhacíabind 127.0.0.1 172.17.0.1; sidocker0no está arriba, Redis muere en bucle ("Cannot assign requested address") y con él todo Celery (fitment, publicación MeLi en lote, webhook). → Arreglado (bind 127.0.0.1 ::1) +vm.overcommit_memory=1+reset-failed; Celery vivo. - 30 de 35 endpoints
/api/admin/*SIN auth (solotenants*/users*la tenían):DELETE /api/admin/parts,POST /api/admin/import/<type>,upload-image,export/<type>… expuestos. → Guard globalbefore_requestque exige token ADMIN en toda la superficie; verificado 401.
Lo demás que falta (priorizado):
- MeLi sigue "inerte": 52 publicaciones de Rached con
inventory_id=NULL(0/52), 31 órdenes pagadas sin convertir,module_marketplace=false, sync congelado desde el 11-jun, 0 imágenes. No es la API: es el mapeo SKU→inventario + imágenes. - Template de tenant congelado en 32 tablas (un tenant real tiene ~91): funciona solo porque el alta aplica v1.1→v4.27 sobre un template desactualizado → frágil.
- Flags de módulo inconsistentes (
*_enableden dashboard vsmodule_*en POS): activar MercadoLibre/WhatsApp en el panel no se refleja en el POS. - Yonke construido y vacío: sin flag de módulo, sin link de navegación, sin plan asignable, 0 piezas.
- Lealtad sin cerrar el ciclo (acumula pero no se puede canjear con descuento real).
- Backups: sin offsite, sin retención (7.2 GB), sin alerta de backup; y
expire_demos.pyno está cableado a ningún timer. - Reset de demo no limpia PII (clientes/conversaciones quedan).
- La IA de embeddings está construida pero SIN usar:
semantic_search.embed()/find_similar()no tienen un solo caller → es la palanca más barata para media docena de mejoras.
1. Regresiones / puntos ciegos operativos (con evidencia)
| # | Hallazgo | Evidencia | Estado |
|---|---|---|---|
| 1 | Redis muere por bind a docker0 |
redis-server.log:847 Cannot assign requested address 172.17.0.1; redis.conf:88 |
✅ arreglado |
| 2 | 32 endpoints /api/admin/* sin auth |
dashboard/server.py (35 rutas, 3 con ADMIN) |
✅ arreglado (guard global) |
| 3 | Admin de catálogo roto (500) | /api/admin/stats,/groups → 500 (tablas parts/part_categories retiradas, server.py:2716-2743) |
pendiente |
| 4 | Backups Oct 2–10 inexistentes + sin offsite + sin retención + sin alerta de backup | backups/; BACKUP_S3_BUCKET sin set |
parcial (timer ya corre) |
| 5 | expire_demos.py sin timer |
grep systemd/=0 |
pendiente |
| 6 | Template congelado (32 tablas) + drift (sale_payments ausente) |
tenant_template 32 vs tenant real 91 |
pendiente |
| 7 | Reset de demo deja PII (no trunca customers,whatsapp_messages,wa_*,audit_log) |
manager/services/tenant_service.py:188-240 |
pendiente |
| 8 | 14 DB tenant_* huérfanas (6 con PII de prueba) vs 8 registradas |
pg_database |
pendiente |
| 9 | Flags de módulo inconsistentes | dashboard escribe meli_enabled, POS lee module_meli (config_bp.py:1269), manager usa module_* |
pendiente |
| 10 | Manager sin nginx/TLS/2FA; auditoría vacía; bug de comparación de versiones ("v4.9">="v4.10") |
manager/services/migration_service.py:82 |
pendiente |
| 11 | Sin TLS en el host, sin firewall; 5432/5003 en 0.0.0.0 |
ss -tlnp; iptables -S ACCEPT |
pendiente (decisión) |
| 12 | nexus comparte rol en TODAS las DB; sin roles por tenant |
has_database_privilege=t |
pendiente |
| 13 | nginx del repo difiere del vivo (falta bloque wildcard de tenants; sobra nexus_quart/login2) |
nginx/nexus-pos.conf vs /etc/nginx/... |
pendiente |
| 14 | Sin analytics/tracking en la cara pública (cero GA/GTM/pixel) | grep = 0 | pendiente |
| 15 | i18n.js muerto (fuerza es, cero t()), *.min.js desactualizados |
i18n.js:322 |
pendiente |
| 16 | Aislamiento multi-tenant por proceso: 8 workers × N tenants × pool; sin PgBouncer; scans cross-tenant O(n) | tenant_db.py, marketplace_external_bp.py:113 |
pendiente |
| 17 | Token del webhook de Alertmanager en claro en el repo | docker/alertmanager/alertmanager.yml |
pendiente |
2. MeLi / Yonke / WhatsApp — estado real y brechas
MercadoLibre (Rached): 52 listings, inventory_id 0/52, 31 órdenes paid sin convertir (nexus_sale_id NULL), sync_errors 52/52 (jun-11), last_sync_at 2026-06-11, 0 imágenes, module_marketplace=false. Bloqueo operativo = mapear SKU→inventario + subir imágenes + encender el módulo.
Ausente comercialmente (0 refs en código): descripción de anuncio, facturación automática al convertir (usa _create_sale_manual que salta el hook de CFDI/contabilidad), persistir comisión/rentabilidad, variaciones, catalog_listing/price_to_win, promociones, reputación, SLA de preguntas (4 sin responder, una de febrero), multi-cuenta, backoff de rate-limit (429).
Yonke: código completo (M1–M6), 0 datos. Falta: flag module_yonke (no existe), link en navegación, plan asignable desde admin, tenant piloto, exposición pública de usados, categorías ML de usados, botón "publicar usado" en la UI.
WhatsApp: 8 bridges vivos + WA CRM (:3010) pero module_whatsapp=false en todos, WA CRM sin cablear (secret placeholder), 0 mensajes; y el flujo WA no escribe actividades en el CRM (aunque sí factura pedidos).
3. IA no conversacional — la siguiente ola (con prontitud de datos)
3.1 La palanca infrautilizada
pos/services/semantic_search.py tiene embed() (4096 dims), find_similar(), cosine_similarity(), rerank() — el rerank está integrado y el resto NO tiene un solo caller. Es la base más barata para: matching, dedup, alternativas, limpieza de fitment, búsqueda semántica de bodega y respuestas de compatibilidad.
3.2 Priorizado por impacto/esfuerzo
| Prio | Oportunidad | Punto de integración | Datos (real) | Enfoque | Esfuerzo |
|---|---|---|---|---|---|
| 1 | Ligar inventario→catálogo a escala (habilita casi todo) | sku_matcher.py:82,138; endpoint /inventory/match-catalog |
355k items sin ligar; 17,246 catálogo; 406,393 xrefs | exact+interchange (ya) + embeddings en el fallback de nombres (hoy difflib) |
M |
| 2 | Enriquecer catálogo: descripciones e imágenes | catalog_import_service.py:14; image_scraper.py:55 |
95% de inventory.description vacío; 0/17,246 supplier_catalog con imagen/desc; hay imágenes en los Excel de data/ |
LLM para descripción ES; cargar imágenes de proveedor + visión para validar | S–M |
| 3 | "Alternativas / piezas similares" (feature muerta) | catalog_service._get_alternatives:1859; dashboard/server.py:1915 |
supplier_catalog_interchange (406k) + catálogo 17k |
reconstruir sobre interchange + find_similar() (hoy consulta tablas TecDoc retiradas → vacío) |
M |
| 4 | Anuncios MeLi: título + descripción + categoría | marketplace_external_service.build_item_payload:237; meli_service.search_categories:280 |
nombre/marca/compat/donor | LLM (categoría vía domain_discovery) + descripción |
S–M |
| 5 | Claves SAT de productos (clave_prod_serv/clave_unidad 100% vacías) |
cfdi_builder.py:178; cfdi_facturapi_builder.py:83 |
nombre/categoría/marca de 170k | reglas + LLM → CFDI correcto | S |
| 6 | Persistir comisión/rentabilidad por listing | marketplace_listings (nuevas columnas); _calculate_meli_net_price:387 (ya calcula, no guarda) |
listings + costo | guardar fee/net/costo → margen por publicación | S |
| 7 | Facturación automática al convertir orden MeLi | convert_order_to_sale/_create_sale_manual:1759 (salta pos_engine CFDI) |
órdenes MeLi | enrutar por process_sale o encolar CFDI |
S |
| 8 | Extracción de pedidos desde WhatsApp (texto/voz/foto) | whatsapp_bp.py:376 (hoy menú rígido) |
whisper_local (voz), part_vision/invoice_ocr (foto), catálogo |
LLM/NER → cotización borrador | M–L |
| 9 | Limpieza de fitment ruidoso | qwen_fitment.py:113,298; inventory_vehicle_compat.py:322 |
41.5M filas (estrada ~131/pieza; qwen 99.5%) |
apagar qwen por defecto en bulk-import + scorear ruido con embeddings/rerank |
M |
| 10 | Búsqueda semántica de bodega (150,778 items, multi-vendedor) | peer_service, catalog_service.get_bodega_availability:2562 |
150k con nombre/SKU | embeddings + rerank (offline) | M |
| 11 | Métricas de negocio por tenant + anomalías multi-tenant + salud de cartera | master rollup diario; anomaly_detector.py (intra-tenant) |
por definir | rollup + z-score entre tenants | M |
| 12 | Dedup/normalización con embeddings | sku_matcher.match_name:82 |
estrada: 6,121 grupos de name duplicado |
find_similar() clustering |
M |
3.3 No vale la pena todavía (cold-start honesto)
- Forecast de demanda por SKU, elasticidad/precios, predicción de quiebre, fraude/anomalías por SKU, churn/scoring por cliente: hay ~70 líneas de venta en toda la plataforma y 0 compras.
cross_sellestadístico yanomaly_detectorse auto-marcan encold_start. Dejar diseñado, no invertir hasta tener miles de transacciones por tenant. - IA de ops: triage de logs con LLM y agrupación de alertas con ML = overkill (volumen KB/día, 1 receiver). Lo útil es sin IA: alerta de backup/celery/tenant caído y
predict_linearpara disco.
4. Roadmap propuesto
| Fase | Foco | Entregable verificable |
|---|---|---|
| F5 — Cerrar lo crítico (2-3 días) | Redis estable (hecho) · auth admin (hecho) · admin catálogo sin 500 · expire_demos a timer · unificar flags de módulo · reset de demo con PII · limpiar DB huérfanas · alerta de backup |
0 endpoint admin sin auth; módulos coherentes dashboard↔POS; alerta de backup llega |
| F6 — MeLi de verdad (1 sem) | Mapear los 52 listings → inventario · pipeline de imágenes · encender module_marketplace y module_yonke · publicar con descripción/categoría · persistir comisión · facturación automática al convertir |
Publicar SKU con imagen desde el POS → vender en ML → orden convertida + CFDI encolado |
| F7 — IA de catálogo (2 sem) | Ligado masivo con embeddings · descripciones + imágenes · "alternativas/similares" funcional · SAT keys · limpieza de fitment | ≥70% de items ligados a catálogo; alternativas devuelven resultados; fitment por pieza < 20 filas |
| F8 — Escala y cartera (2-3 sem) | PgBouncer + pool · métricas de negocio por tenant + anomalías multi-tenant + salud de cartera · analytics en la cara pública · Yonke piloto · WA CRM por negocio · TLS/firewall/roles | panel de cartera; 30+ tenants sin agotar conexiones; 1 tenant Yonke en producción |
5. Métricas de éxito
- Confiabilidad: 0 servicios en bucle; backups diarios verificados + offsite; alertas que llegan.
- Cierre: 0 endpoints
/api/admin/*sin auth; flags de módulo coherentes. - MeLi: 100% de listings con
inventory_id; >0 órdenes convertidas + facturadas; publicaciones con imagen y descripción. - IA de catálogo: % items ligados a catálogo (0→≥70%); tiempo de alta de anuncio; búsquedas sin resultado.