PDF-009H - Frontend Facets Product Display Contract¶
Fecha: 2026-06-22
Estado: FRONTEND DATA CONTRACT / DISENO DOCUMENTAL / SIN WRITES / CANDIDATE
portal_visible = yes
Scope: tenant
tenant_id: alpuntodeventa
Destino funcional: La Directa WooCommerce
Owner: Gabi / Carlos Canu
A. SAFE POINT inicial¶
| Control | Resultado |
|---|---|
git status -sb |
## main...origin/main |
git rev-parse HEAD |
5363b01c82329d24fed43292604d00112e4c2d9e |
git rev-parse origin/main |
5363b01c82329d24fed43292604d00112e4c2d9e |
git log -3 --oneline |
5363b01 docs: add pdf-009g woocommerce mapping candidate; b86a05e docs: align pdf-009f post-deploy state; c756b3c docs: add pdf-009f woocommerce final payload dry-run |
git diff --check inicial |
PASS con warnings de normalizacion LF/CRLF en archivos ya modificados |
Safe point esperado confirmado: HEAD local y origin/main iniciaron alineados
en 5363b01c82329d24fed43292604d00112e4c2d9e, con cambios documentales
pendientes y PDF-009H aun sin commit.
B. Estado documental leido¶
Documentos leidos obligatorios:
docs/PROJECT-STATE.mddocs/ROADMAP.mddocs/governance/ACTIVE-CONTEXT.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-009G-WOOCOMMERCE-CATEGORIES-IMAGES-ATTRIBUTES-MAPPING-CANDIDATE.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-009F-WOOCOMMERCE-FINAL-PAYLOAD-DRY-RUN.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-009E-WOOCOMMERCE-PRODUCT-RULES-PRE-WRITE-CANDIDATE.mddocs/tenants/alpuntodeventa/business-observer/SOURCE-002-FUTURE-LAYER-MAPPING.md
Confirmacion documental:
PDF-009Gquedo publicado y desplegado como mapping candidate.- WooCommerce
La Directasigue documentado sin productos cargados. - WooCommerce tenia solo category
Uncategorizedid=15y0atributos globales. - No hay writes habilitados para categorias, atributos, imagenes ni productos.
meta_datano debe usarse para filtros, busqueda u ordenamiento masivo.
C. Objetivo del contrato frontend¶
Este documento fija que campos del producto deben verse en el frontend y que campos pueden participar en facetas o filtros masivos antes de cualquier creacion de atributos, categorias, imagenes o productos en WooCommerce.
Regla central:
- si un dato se usa como filtro masivo, debe vivir en atributo o taxonomia optimizada;
- si un dato solo se renderiza, puede vivir como
meta_datao campo display privado con control de performance; - no usar
meta_datacomo base de filtros masivos. - en todo lo relacionado con WooCommerce se debe priorizar maxima performance: WooCommerce debe recibir payloads listos, cacheables y sin resoluciones dinamicas costosas desde el frontend.
C.1. WooCommerce Maximum Performance Rule¶
Regla permanente para SOURCE-002 Productos -> WooCommerce La Directa:
- no convertir WooCommerce en ERP;
- no enviar a WooCommerce costos, proveedor, descuentos internos, margenes, listas multiples, historiales economicos ni datos sensibles;
- no usar
meta_datapara filtros masivos, busqueda masiva ni ordenamiento masivo; - resolver filtros frontend con atributos globales o taxonomias WooCommerce optimizadas;
- mantener campos display sin facetas cuando no sean dimensiones de filtro;
- evitar queries N+1 en listados, cards, fichas, imagen principal, marca, pack y minimo de venta;
- preparar payloads listos antes del render frontend;
- si el frontend es headless/API publica, exponer payloads acotados, cacheables y sin datos sensibles;
- stock sync frecuente debe usar payload minimo de stock y no debe tocar
imagenes,
Marca,Articulo,Unidades_x_Bulto,CantVtaMin, categorias ni campos display; - normalizacion de catalogo, imagenes y metadata editorial pertenece a catalog sync controlado o gate futuro, no a stock sync frecuente.
D. Matriz frontend de filtros/display¶
| Campo fuente | Campo WooCommerce destino | Card/listado | Ficha individual | Filtro | Busqueda | Ordenamiento | Destino tecnico recomendado | Riesgo performance | Decision |
|---|---|---|---|---|---|---|---|---|---|
SKU |
sku |
opcional interno | opcional interno | no | si, como lookup exacto o soporte operativo | no | campo nativo WooCommerce sku; control canonico en PostgreSQL/OpenClaw |
bajo | READY: identidad tecnica, no faceta comercial. |
Articulo |
name |
si | si | no | si | opcional por relevancia/texto, no como regla principal | campo nativo WooCommerce name |
bajo | READY: nombre visible y buscable, no filtro. |
Marca |
atributo global pa_marca o atributo global equivalente |
si | si | si | si | opcional por nombre de marca si el frontend lo requiere | atributo global WooCommerce filtrable, visible y optimizado | bajo si es taxonomia/atributo; alto si se usa meta query | READY_CANDIDATE: requiere gate de creacion de atributo global. |
Category |
product_cat padre |
si, si el diseno lo muestra | si | si | si | opcional por taxonomia | taxonomia nativa WooCommerce product_cat |
bajo | READY_CONCEPT / PENDING_CATEGORY_GATE. |
SubCategoria |
product_cat hija |
si, si el diseno lo muestra | si | si | si | opcional por taxonomia | taxonomia nativa WooCommerce product_cat |
bajo | READY_CONCEPT / PENDING_CATEGORY_GATE. |
Unidades_x_Bulto |
campo display privado o meta_data.units_per_pack |
si | si | no | no | no | meta_data privada minima o campo display server-side |
bajo si se carga junto al producto; medio si genera N+1 | READY: visible, no filtro, no taxonomia. |
CantVtaMin |
campo display privado o meta_data.min_sale_quantity |
si | si | no | no | no | meta_data privada minima o campo display server-side |
bajo si se carga junto al producto; medio si genera N+1 | READY: visible, no filtro, no taxonomia. |
CantVentaAgrupada |
campo display privado o meta_data.sale_pack_quantity |
opcional | si, si negocio lo muestra | no | no | no | meta_data privada minima o campo display server-side |
bajo si se carga junto al producto | READY_OPTIONAL: display operativo, no faceta. |
Images |
images[] WooCommerce |
si | si | no | no | no | campo Images candidate en tabla de productos PostgreSQL/OpenClaw, tipo jsonb, precomputado y ordenado |
bajo si viaja listo; alto si se resuelve dinamicamente o genera N+1 | READY_CANDIDATE: render visible, no filtro; imagenes cargadas manualmente en Woo Admin y descubiertas en modo read-only. |
Stock |
stock_quantity, stock_status, manage_stock |
si, como disponibilidad | si | no en esta fase | no | opcional por disponibilidad nativa, no por meta | campos nativos WooCommerce de stock | bajo | READY: stock frecuente no debe tocar display fields. |
PrecioListaFinal |
regular_price |
si | si | no en este contrato | si por busqueda no; por rango solo con gate separado | opcional por precio nativo | campo nativo WooCommerce regular_price |
bajo para orden nativo; medio si se agregan rangos mal indexados | READY: precio visible; filtro/rango requiere gate separado. |
PrecioOfertaFinal |
sale_price con guard comercial |
si si aplica | si si aplica | no | no | opcional por precio nativo | campo nativo WooCommerce sale_price |
bajo | PENDING_RULE: oferta protegida por vigencia y aprobacion. |
PesoxUnidad |
weight |
no por defecto | opcional | no | no | no | campo nativo WooCommerce weight |
bajo | READY_OPTIONAL: dato tecnico/display, no faceta inicial. |
| costos/proveedor/margenes/listas multiples | no enviar a WooCommerce | no | no | no | no | no | PostgreSQL only |
n/a | BLOCKED_POLICY: no exponer en frontend publico. |
D.1. Matriz frontend final¶
| Campo | Destino tecnico final candidate | Render card/ficha | Filtro frontend |
|---|---|---|---|
Articulo |
WooCommerce native name |
si | no |
Marca |
atributo global/taxonomia filtrable | si | si |
Unidades_x_Bulto |
display field / meta_data controlada |
si | no |
CantVtaMin |
display field / meta_data controlada |
si | no |
Images |
PostgreSQL/OpenClaw Images jsonb + WooCommerce images[] |
si | no |
E. Reglas obligatorias¶
| Regla | Decision |
|---|---|
Articulo -> WooCommerce name |
Visible en card/listado y ficha individual; buscable por texto; no filtro. |
Marca |
Debe renderizarse en card/listado y ficha individual, y debe usarse como filtro frontend. |
Marca como filtro |
Debe ir a atributo global/taxonomia WooCommerce optimizada; no a meta_data para filtrar. |
Unidades_x_Bulto |
Visible en card/listado y ficha individual; no filtro; no taxonomia. |
CantVtaMin |
Visible en card/listado y ficha individual; no filtro; no taxonomia. |
Images |
Visible en card/listado y ficha individual; no filtro; no taxonomia; no meta query. |
Unidades_x_Bulto y CantVtaMin |
No deben implementarse como filtros ni como taxonomias. |
| Campos display | Ningun campo display debe crear filtros, busquedas masivas u ordenamientos por meta_data. |
meta_data |
No usar para filtros masivos, busqueda masiva u ordenamiento masivo. |
| Datos solo display | Pueden ir a meta_data o campo display privado con control de performance. |
| Datos filtro | Deben ir a atributo/taxonomia optimizada. |
F. Contrato Images jsonb¶
Images queda definido como campo candidate permanente para la tabla de
productos usada por PostgreSQL/OpenClaw hacia WooCommerce.
Destino recomendado:
- tabla de productos PostgreSQL/OpenClaw candidate para WooCommerce;
- columna
Images; - tipo recomendado
jsonb; - estructura JSON ordenada y validable;
- alternativa futura: tabla hija normalizada si volumen, indices, auditoria o performance operativa lo exigen en un gate posterior.
No usar pgvector para Images: las imagenes del catalogo no son embeddings
ni vectores semanticos en este contrato. Son un payload estructurado de
galeria, con URLs, imagen destacada y orden estable.
Las imagenes no vienen desde SGC. En esta fase, las imagenes se cargan
manualmente desde WooCommerce Admin en cada articulo:
- imagen principal;
- imagenes de galeria.
Formato candidate:
json
[
{
"media_id": 321,
"url": "https://ladirecta.com.ar/wp-content/uploads/0135-producto-principal.jpg",
"is_featured": true,
"sort_order": 0,
"title_current": "IMG_001",
"title_expected": "SKU 0135 - Nombre Producto - Principal",
"alt_current": "",
"alt_expected": "Nombre Producto SKU 0135",
"status": "NEEDS_NORMALIZATION"
}
]
Reglas:
- cada producto debe recomendar una sola imagen featured;
media_idse guarda si esta disponible desde WooCommerce discovery;- la imagen featured debe mapearse primero hacia WooCommerce
images[], conposition=0; - las imagenes no featured forman la galeria y se ordenan por
sort_orderestable; title_expecteddebe normalizar titulos de medios incluyendo SKU y nombre del articulo;alt_expecteddebe normalizar alt text para SEO y busqueda interna;statusdebe permitir auditoria de normalizacion, adjuntos, duplicados y limpieza;Images[].urldebe llegar ya resuelto antes del write WooCommerce;- el frontend no debe resolver, consultar ni ordenar galerias en tiempo real;
- este contrato no autoriza subir, modificar ni borrar imagenes.
Mapping hacia WooCommerce:
| Origen PostgreSQL/OpenClaw | Destino WooCommerce | Regla |
|---|---|---|
Images[].media_id |
images[].id si se usa update futuro por media existente |
Solo si existe y fue descubierto en modo read-only. |
Images[].url |
images[].src |
URL lista para consumir por WooCommerce. |
Images[].is_featured=true |
primera entrada de images[] |
Debe ser unica y quedar con position=0. |
Images[].is_featured=false |
entradas siguientes de images[] |
Galeria ordenada por sort_order ascendente. |
Images[].sort_order |
images[].position |
Featured 0; galeria estable 1..n. |
Images[].title_expected |
media title candidate | Requiere gate futuro explicito para update de metadata. |
Images[].alt_expected |
media alt text candidate | Requiere gate futuro explicito para update de metadata. |
Images[].status |
reporte OpenClaw | Auditoria y limpieza candidate, sin borrado automatico. |
G. Matriz especifica Images¶
| Campo | Tipo | Destino | Se renderiza en front | Se usa como filtro | Impacto performance | Decision |
|---|---|---|---|---|---|---|
Images[].url |
text dentro de jsonb |
PostgreSQL/OpenClaw Images; WooCommerce images[].src |
si | no | bajo si el payload llega listo; alto si se consulta en runtime por producto | READY_CANDIDATE: URL precomputada, sin resolucion frontend. |
Images[].is_featured |
boolean dentro de jsonb |
PostgreSQL/OpenClaw Images; orden de images[] WooCommerce |
si, como imagen principal | no | bajo si se valida una sola featured; medio si hay conflictos y reordenamiento dinamico | READY_CANDIDATE: una sola featured recomendada. |
Images[].sort_order |
integer dentro de jsonb |
PostgreSQL/OpenClaw Images; WooCommerce images[].position |
si, como orden de galeria | no | bajo si viene estable; alto si el front ordena dinamicamente | READY_CANDIDATE: orden estable precomputado. |
Estados de auditoria de imagenes:
READYNEEDS_NORMALIZATIONMISSING_SKU_IN_TITLEMISSING_ALT_TEXTUNATTACHED_BUT_RECENTUNATTACHED_OLDDUPLICATE_CANDIDATESAFE_DELETE_CANDIDATEBLOCKED_REVIEW_REQUIRED
G.1. WooCommerce Media Governance Use Case¶
Flujo documental candidate:
A. Usuario carga imagenes manualmente desde WooCommerce Admin en cada articulo: imagen principal e imagenes de galeria.
B. OpenClaw/Woo read-only discovery detecta imagenes asociadas a producto/SKU, sin modificar WooCommerce.
C. PostgreSQL/OpenClaw guarda la estructura Images jsonb como coleccion
ordenada con url, media_id si esta disponible, is_featured,
sort_order, metadata actual, metadata esperada y status.
D. OpenClaw genera normalizacion candidate de title_expected y
alt_expected, incluyendo SKU y nombre de articulo.
E. OpenClaw genera reporte de media cleanup para detectar imagenes huerfanas, duplicadas o no usadas.
F. No se borran imagenes automaticamente.
G. Cualquier update futuro de media metadata, title, alt text, adjuntos, galeria o cleanup requiere gate explicito separado.
G.2. Politica de limpieza de media library¶
Reglas obligatorias:
- mantener depurada la galeria de medios mediante reportes y revision humana;
- no borrar imagenes automaticamente;
- no borrar imagenes usadas por productos;
- no borrar imagenes usadas por multiples productos;
- revisar manualmente imagenes huerfanas;
- detectar duplicados, huerfanas y no usadas mediante reporte;
SAFE_DELETE_CANDIDATEno equivale a autorizacion de borrado;- borrar solo con autorizacion explicita futura;
- conservar trazabilidad
media_id,skuyproduct_id; - cualquier limpieza de media library requiere revision/autorizacion explicita.
H. Decision candidata¶
Marcarequiere un gate posterior de creacion/aprobacion de atributo global WooCommerce, por ejemplopa_marca, antes de usarla como filtro masivo.Unidades_x_BultoyCantVtaMinpueden viajar comometa_dataprivada o campos display privados si el frontend los carga junto con el producto.Imagesdebe vivir inicialmente comojsonbordenado en PostgreSQL/OpenClaw y mapearse a WooCommerceimages[]como payload listo.- Si el volumen de imagenes, auditoria, deduplicacion o consultas operativas lo
justifican, abrir gate futuro para tabla hija normalizada
product_imageso equivalente. - Si el frontend consume API publica/headless, abrir gate separado de exposicion segura para decidir exactamente que campos display salen, con que nombres y bajo que permisos/cache.
- Si el frontend usa templates WooCommerce/PHP, renderizar
Unidades_x_BultoyCantVtaMinserver-side sin exponer datos sensibles. - Ninguna decision de este documento autoriza crear atributos, categorias, imagenes ni productos.
I. Performance¶
Reglas de performance:
- maxima performance WooCommerce es regla permanente para todo este frente;
- filtros deben usar taxonomias o atributos WooCommerce, no meta queries pesadas;
Marcafiltrable debe resolverse como atributo global/taxonomia optimizada;Unidades_x_BultoyCantVtaMindeben cargarse junto al producto para evitar consultas N+1;Imagesdebe precalcularse antes del write y llegar como payload listo;- no resolver imagenes en tiempo real desde el front;
- no consultar ni ordenar galeria dinamicamente en card/listado o ficha;
- evitar queries N+1 para renderizar card/listado, incluyendo imagen principal, marca, pack y minimo de venta;
- si se usa headless/API publica, los campos display deben tener payload acotado y cacheable;
- stock frecuente no debe tocar
Marca,Articulo,Unidades_x_Bulto,CantVtaMin,Images, categorias, imagenes ni descripciones; - catalog sync controlado si puede actualizar datos display lentos cuando haya gate de catalogo;
- catalog sync controlado puede actualizar
Images; stock sync frecuente no debe tocar imagenes; - WooCommerce debe recibir el payload de producto listo, sin depender de transformaciones caras durante render frontend;
- no ordenar listados por
Unidades_x_BultoniCantVtaMinsalvo gate futuro con indice/estrategia especifica; - no convertir WooCommerce en ERP ni mover costos, proveedor, descuentos, margenes, listas multiples o datos sensibles al frontend.
J. Casos READY¶
| Caso | Estado | Motivo |
|---|---|---|
Articulo visible |
READY |
Campo nativo name, visible en card y ficha. |
Articulo buscable |
READY |
Busqueda textual normal; no faceta. |
Marca visible |
READY_CANDIDATE |
Dato comercial visible requerido por usuario. |
Marca filtrable |
READY_CANDIDATE / PENDING_ATTRIBUTE_GATE |
Debe existir atributo global WooCommerce antes del uso real. |
Unidades_x_Bulto display |
READY |
Dato operativo visible; no filtro. |
CantVtaMin display |
READY |
Dato comercial visible; no filtro. |
Images display |
READY_CANDIDATE |
Coleccion visible, no filtro; deriva de imagenes cargadas manualmente en Woo Admin y descubiertas en modo read-only. |
Images -> WooCommerce images[] |
READY_CANDIDATE |
Mapping candidate con featured primero y galeria ordenada. |
meta_data minima display |
READY_WITH_GUARD |
Permitida solo para render; no para facetas masivas. |
K. Reglas PENDING¶
| Pendiente | Por que falta | Efecto |
|---|---|---|
Crear atributo global Marca |
WooCommerce tiene 0 atributos globales y no hay writes habilitados. |
Bloquea filtro real por marca hasta write gate. |
| Slug/nombre final de atributo | Falta aprobacion final, por ejemplo pa_marca. |
Bloquea contrato tecnico final de API/UI. |
| Exposicion API/headless de display fields | Falta saber si el frontend consumira API publica/headless o templates PHP. | Puede requerir gate de seguridad/cache. |
| Formato visual de pack/minimo | Falta diseno UI final: etiqueta, pluralizacion y unidad. | No bloquea contrato de datos. |
| Regla de carrito para minimo de venta | CantVtaMin visible no implica enforcement de carrito. |
Requiere gate funcional separado. |
| Discovery real de imagenes | PDF-009G detecto 0 columnas de imagen en SOURCE-002; las imagenes no vienen desde SGC. |
Requiere discovery read-only de Woo media/productos y reporte antes de cualquier update futuro. |
Validacion fisica de Images |
Falta gate DDL/modelo fisico. | Bloquea implementacion SQL real; no bloquea contrato candidate. |
L. Riesgos performance¶
| Riesgo | Severidad | Mitigacion |
|---|---|---|
Filtrar Marca por meta_data |
alta | Crear/usar atributo global WooCommerce filtrable. |
Convertir Unidades_x_Bulto o CantVtaMin en taxonomias |
media | Mantenerlos como display fields sin faceta. |
| N+1 al renderizar campos display | media | Cargar meta_data/display fields en el mismo fetch del producto o render server-side. |
| N+1 al renderizar imagen principal o galeria | alta | Precalcular Images y entregar payload listo/cacheable. |
| Resolver u ordenar imagenes desde el frontend | alta | Orden estable por sort_order antes del write WooCommerce. |
| Headless con payload demasiado ancho | media | Exponer solo campos display aprobados y cacheables. |
| Stock sync frecuente actualizando catalogo completo | alta | Mantener payload minimo de stock. |
| Stock sync frecuente tocando imagenes | alta | Separar stock sync de catalog sync; imagenes solo en catalog sync controlado. |
| Ordenamiento por campos display sin indice | media | No habilitar ordenamiento por pack/minimo en esta fase. |
M. Criterios de implementacion futura¶
Antes de cualquier implementacion real:
- SAFE POINT nuevo limpio.
- Write gate explicito si se crea atributo global
Marca. - Aprobacion de slug/nombre final del atributo.
- Confirmacion del tipo de frontend: templates WooCommerce/PHP o headless/API publica.
- Confirmacion de payload publico sin costos, proveedor, margenes, descuentos, listas multiples ni datos sensibles.
- Validacion de que filtros usan taxonomias/atributos y no
meta_data. - Validacion de que display fields no generan N+1.
- Gate DDL/modelo fisico para
Images jsonbo tabla hija normalizada. - Discovery read-only de media library y reporte de normalizacion/cleanup antes de cualquier update futuro de media metadata o limpieza.
N. Decision¶
PDF-009H deja el contrato frontend en estado candidate:
Articulose renderiza comonamey no es filtro.Marcase renderiza y es filtro, pero requiere atributo global WooCommerce optimizado antes del uso real.Unidades_x_BultoyCantVtaMinse renderizan en card/listado y ficha, pero no son filtros, no son taxonomias y no deben sostener busqueda u ordenamiento masivo.Imagesse renderiza en card/listado y ficha, no es filtro y debe almacenarse como coleccion ordenada candidatejsonben PostgreSQL/OpenClaw, mapeada a WooCommerceimages[]con featured primero y galeria estable.pgvectorqueda descartado paraImages; tabla hija normalizada queda como alternativa futura si performance/volumen/auditoria lo exige.meta_dataqueda permitida solo para datos display acotados y no sensibles, con control de performance.
O. Proximo paso recomendado¶
Abrir gate separado para Marca como atributo global WooCommerce y confirmar:
- nombre/slug del atributo global;
- visibilidad publica y uso en filtros;
- si el frontend sera WooCommerce/PHP o headless/API publica;
- estrategia de carga/cache para
Unidades_x_BultoyCantVtaMin; - contrato fisico de
Images(jsonbinicial vs tabla hija futura); - discovery read-only de imagenes cargadas manualmente en Woo Admin y reporte de normalizacion/cleanup;
- que no se habilitan writes de productos, categorias, imagenes ni sync hasta un write gate posterior.
P. Cierre de restricciones¶
Durante este gate solo se hicieron cambios documentales locales en archivos
del repositorio. No se modifico WooCommerce, no se modifico La Directa, no se
crearon atributos, no se crearon categorias, no se subieron imagenes, no se
crearon productos, no se actualizaron productos, no se toco .env, no se
imprimieron secretos, no se toco PostgreSQL, no se ejecuto SQL, no se hizo
push, no se hizo deploy, no se ejecuto sync, no se ejecuto scheduler, no se
ejecuto cron y no se ejecutaron pipelines.