Componentes
sync_worker.py
Archivo único, sin dependencias internas. Estructura:
sync_worker.py
├── Settings (pydantic-settings) # Lee .env
├── PROVINCIAS # Mapa abrev → nombre completo
├── FIXED_SEARCHABLE/FILTERABLE/SORTABLE # Campos fijos del índice
├── normalizar_clave() # "[tag.nombre]" → "attr_tag_nombre"
├── parsear_replace_lote() # JSON embebido → dict plano attr_*
├── build_geo() # "lat,lng" → { lat, lng } para Meilisearch
├── limpiar_certificado() # dict MySQL → documento Meilisearch
├── build_query() # Query con JOIN de 12 tablas
├── meili_upsert() # POST /indexes/.../documents
├── meili_delete() # POST /indexes/.../documents/delete-batch
├── meili_put() # PUT /indexes/.../settings/...
├── sync_atributos() # Lee ATRIBUTOS → actualiza settings
├── check_atributos_changed() # SELECT COUNT con ventana de tiempo
├── run_lotes_cycle() # Drena meilisearch_sync_queue
└── main() # Pool MySQL + loop daemon/cron
meilisearch_sync_queue
CREATE TABLE meilisearch_sync_queue (
certificado_id INT NOT NULL,
is_delete TINYINT NOT NULL DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (certificado_id)
);
| Campo | Descripción |
|---|---|
certificado_id |
PK — garantiza deduplicación automática vía INSERT IGNORE |
is_delete |
0 = upsert en Meilisearch, 1 = eliminar del índice |
created_at |
Solo informativo, no se usa en la lógica |
Triggers
Un trigger por cada tabla que afecta datos de un lote:
| Tabla | Qué detecta | Cómo resuelve el certificado_id |
|---|---|---|
HAC_CERTIFICADO |
Cambio directo en el lote | NEW.id_certificado |
ATRIBUTOS_VALORES |
Cambio en cualquier atributo EAV | NEW.record_id donde tablename = 'HAC_CERTIFICADOS' |
REG_CUENTA_ESTABLECIMIENTO |
Cambio en coordenadas, localidad, nombre | SELECT id_certificado WHERE establecimiento_id = NEW.id_establecimiento |
HAC_CERT_DETALLE |
Cambio en categoría u otros detalles | NEW.certificado_id |
HAC_CERTIFICADO_MOV |
Cambio en estado de venta | NEW.certificado_id |
HAC_OFERTAS |
Nueva oferta o cambio de estado | NEW.certificado_id |
HAC_PRE_ORDEN |
Cambio en el orden previo del lote | NEW.certficado_id |
Typo en el schema
La tabla HAC_PRE_ORDEN tiene certficado_id (sin la segunda i). Los triggers y la query respetan este typo tal cual está en producción.
Trigger DELETE en HAC_CERTIFICADO
Es el único que usa ON DUPLICATE KEY UPDATE is_delete = 1 en lugar de INSERT IGNORE, para garantizar que si el lote ya estaba encolado como upsert y se elimina antes de que el worker corra, se elimine del índice en lugar de reindexarse.
Meilisearch
El índice certificados contiene un documento por lote con:
- Campos fijos: identificación, remate, categoría, cantidades, ubicación, consignatario, precios, estados
- Campos dinámicos
attr_*: uno por cada atributo en la tablaATRIBUTOScon tag definido, normalizados comoattr_nombre_del_tag _geo: objeto{lat, lng}para búsquedas por distancia con_geoRadius()orden_efectivo: calculado en Python comopre_orden if orden_final == 0 else orden_final, permite ordenar correctamente sin lógica condicional en Meilisearch