PDF-010H - B2B Runtime Dry-Run Design¶
Fecha: 2026-06-23
Estado: DISENO + DRY-RUN / SIN WRITES / SIN RUNTIME / B2B_RUNTIME_NOT_IMPLEMENTED
portal_visible = yes
Scope: tenant
tenant_id: alpuntodeventa
Destino funcional: SOURCE-001 Clientes + SOURCE-002 Productos -> WooCommerce La Directa
Owner: Gabi / Carlos Canu
A. SAFE POINT inicial¶
| Control | Resultado |
|---|---|
git status -sb |
## main...origin/main |
git rev-parse HEAD |
d17fb945b0dc724c390b4fc3723b1fd9b5553e8f |
git rev-parse origin/main |
d17fb945b0dc724c390b4fc3723b1fd9b5553e8f |
git log -3 --oneline |
d17fb94 docs: add pdf-010g b2b commercial price rules approval; 979c919 docs: add pdf-010f b2b commercial pricing design; bd9fe78 docs: add pdf-010e b2b customer price dry-run |
git diff --check inicial |
PASS |
Safe point esperado confirmado:
HEADcoincide cond17fb945b0dc724c390b4fc3723b1fd9b5553e8f.origin/maincoincide cond17fb945b0dc724c390b4fc3723b1fd9b5553e8f.- repo limpio al inicio.
- ultimo commit esperado confirmado.
Alcance de este gate:
- disenar runtime B2B futuro;
- simular catalogo, carrito, checkout y orden sin ejecutar runtime;
- no tocar WooCommerce API;
- no tocar PostgreSQL con writes;
- no ejecutar SQL write;
- no crear clientes ni productos;
- no modificar precios reales;
- no instalar plugins ni modificar theme;
- no ejecutar sync, scheduler, cron ni pipelines;
- no hacer push, deploy ni commit.
B. Documentacion leida¶
Documentacion base revisada:
docs/tenants/alpuntodeventa/business-observer/production/PDF-010A-B2B-PRICE-LISTS-CUSTOMER-SYNC-CONTRACT.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-010B-B2B-PRICE-LIST-AUTHORITY-READ-ONLY-VALIDATION.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-010D-SOURCE-001-VCLIENTES-READ-ONLY-SNAPSHOT.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-010E-B2B-CUSTOMER-PRICE-DRY-RUN.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-010F-B2B-COMMERCIAL-PRICE-RULES-SERVER-SIDE-PRICING-DESIGN.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-010G-B2B-COMMERCIAL-PRICE-RULES-APPROVAL.mddocs/tenants/alpuntodeventa/business-observer/production/PDF-009M-WOOCOMMERCE-PRODUCT-DRAFT-PILOT-WRITE.mddocs/PROJECT-STATE.mddocs/ROADMAP.mddocs/governance/ACTIVE-CONTEXT.mddocs/tenants/alpuntodeventa/business-observer/production/README.mdmkdocs.yml
C. Diseno matching wc_customer_id -> sgc_customer_id¶
Objetivo futuro: vincular el usuario WooCommerce logueado con el cliente SGC sin crear clientes ni inferir automaticamente por datos debiles.
Autoridad fuerte:
sgc_customer_iddebe provenir deSOURCE-001.Codigocanonicalizado.wc_customer_ides identificador externo WooCommerce.- el mapping valido debe quedar persistido en OpenClaw/PostgreSQL en un gate futuro autorizado.
Fuente candidate principal:
- metadata de usuario WooCommerce con una clave futura candidate, por ejemplo
_apv_sgc_customer_id. - esa metadata debe apuntar a un unico
sgc_customer_idactivo y auditable. - en este gate no se lee ni escribe metadata real de WooCommerce.
Fallbacks solo como candidatos de conciliacion:
- email normalizado;
- CUIT / tax id normalizado;
- WhatsApp / telefono normalizado.
Reglas:
- email, CUIT y WhatsApp no son claves unicas primarias.
- si una senal candidata matchea mas de un cliente SGC, el caso queda
BLOCKED_CUSTOMER_MAPPING. - si un
wc_customer_idapunta a mas de unsgc_customer_id, quedaBLOCKED_CUSTOMER_MAPPING. - si un
sgc_customer_idactivo queda asociado a mas de unwc_customer_id, quedaPENDING_REVIEW_CUSTOMER_MAPPING, salvo regla futura explicita. - cliente suspendido o de baja se bloquea antes de resolver precio.
D. Customer matching matrix¶
| Caso | Fuente candidate | Resultado | Regla |
|---|---|---|---|
wc_customer_id con metadata _apv_sgc_customer_id unica |
metadata Woo usuario | MAPPING_OK |
aplicar si SGC existe y esta activo |
| metadata apunta a cliente inexistente | metadata Woo usuario | BLOCKED_CUSTOMER_MAPPING |
no aplicar precio B2B |
| metadata apunta a cliente suspendido/de baja | metadata Woo usuario + SOURCE-001 Estado | BLOCKED_CUSTOMER_STATUS |
bloquear antes de precio |
| sin metadata, email unico candidate | PENDING_REVIEW_CUSTOMER_MAPPING |
no automatico; requiere conciliacion | |
| sin metadata, CUIT unico candidate | CUIT | PENDING_REVIEW_CUSTOMER_MAPPING |
sensible; no automatico |
| sin metadata, WhatsApp unico candidate | PENDING_REVIEW_CUSTOMER_MAPPING |
no automatico | |
| email/CUIT/WhatsApp duplicado | fallback candidates | BLOCKED_CUSTOMER_MAPPING |
no elegir cliente por inferencia |
| sin ninguna senal | ninguna | BLOCKED_CUSTOMER_MAPPING |
no aplicar precio B2B |
E. Diseno catalogo B2B¶
Regla vigente aprobada por PDF-010G:
- visitante no logueado ve
regular_pricevigente en WooCommerce. regular_pricevigente queda respaldado porPrecioListaFinal.PrecioL1no es default publico.- cliente logueado activo con mapping valido usa precio segun
Lista_Precio. Lista_Precio 1..9 -> PrecioL1..PrecioL9quedaAPPROVED.
Flujo candidate de catalogo:
- Detectar si el usuario esta logueado.
- Si no esta logueado, mostrar
regular_price. - Si esta logueado, resolver
wc_customer_id -> sgc_customer_id. - Validar
Estado = CLIENTE ACTIVO. - Normalizar
Lista_Precio naprice_list_code = Ln. - Resolver precio por
sku + price_list_code. - Si el precio falta, es nulo o
<= 0, devolverBLOCKED_PRICE_MISSING. - No reemplazar silenciosamente por
regular_pricecuando el cliente B2B ya esta identificado.
F. Catalog price matrix¶
| Actor | Estado cliente | Lista | SKU | Precio visual candidate | Resultado |
|---|---|---|---|---|---|
| visitante | no aplica | no aplica | 2442 |
regular_price = 2020.901 |
PUBLIC_DEFAULT |
| cliente activo | CLIENTE ACTIVO |
1 / L1 |
2442 |
PrecioL1 = 2020.900 |
B2B_PRICE_OK |
| cliente activo | CLIENTE ACTIVO |
5 / L5 |
2442 |
PrecioL5 = 2020.900 |
B2B_PRICE_OK |
| cliente suspendido | CLIENTE SUSPENDIDO |
cualquier lista | 2442 |
no aplicar | BLOCKED_CUSTOMER_STATUS |
| cliente de baja | CLIENTE DE BAJA |
cualquier lista | 2442 |
no aplicar | BLOCKED_CUSTOMER_STATUS |
| cliente activo | CLIENTE ACTIVO |
1 / L1 |
3995 |
0.000 |
BLOCKED_PRICE_MISSING |
| cliente activo | CLIENTE ACTIVO |
5 / L5 |
4010 |
0.000 |
BLOCKED_PRICE_MISSING |
G. Diseno carrito server-side¶
Regla: el carrito nunca debe confiar solamente en el precio visual del catalogo.
Flujo candidate:
- En cada recalculo de carrito, detectar usuario y
wc_customer_id. - Resolver mapping vigente
wc_customer_id -> sgc_customer_id. - Validar cliente activo.
- Para cada item, resolver
sku. - Resolver
price_list_codedesdeLista_Precio. - Obtener
applied_pricedesdesku + price_list_code. - Comparar contra cualquier precio visual recibido solo como referencia.
- Reemplazar el precio de linea en servidor.
- Guardar metadata candidate de item/carrito.
- Bloquear carrito si hay inconsistencia no recuperable.
Metadata candidate por item/carrito:
skusgc_customer_ido referencia interna no sensibleprice_list_codeprice_sourceapplied_priceregular_price_referencesource_hashpricing_status
H. Cart recalculation matrix¶
| Caso | Entrada carrito | Recalculo server-side | Metadata candidate | Resultado |
|---|---|---|---|---|
| visitante con SKU valido | sku=2442 |
usar regular_price |
price_source=PUBLIC_DEFAULT |
CART_PRICE_OK |
| cliente L1 activo | sku=2442 |
aplicar PrecioL1 |
price_list_code=L1, price_source=SOURCE-002 |
CART_PRICE_OK |
| cliente L5 activo | sku=2442 |
aplicar PrecioL5 |
price_list_code=L5, price_source=SOURCE-002 |
CART_PRICE_OK |
| cliente suspendido/de baja | cualquier SKU | no aplicar precio | pricing_status=BLOCKED_CUSTOMER_STATUS |
CART_BLOCKED |
cliente activo + SKU 3995 |
sku=3995 |
precio 0.000 |
pricing_status=BLOCKED_PRICE_MISSING |
CART_BLOCKED |
| cliente activo + mapping duplicado | cualquier SKU | no calcular | pricing_status=BLOCKED_CUSTOMER_MAPPING |
CART_BLOCKED |
I. Diseno checkout/orden¶
Regla: checkout debe validar nuevamente antes de crear la orden.
Flujo candidate:
- Releer usuario, mapping y estado cliente.
- Releer lista vigente.
- Recalcular cada linea por
sku + price_list_code. - Comparar contra metadata de carrito.
- Bloquear la orden si cambio la lista, falta precio, cambia
source_hashde forma no aceptada o el cliente ya no esta activo. - Crear orden solo si todas las lineas pasan validacion.
- Guardar evidencia por linea.
Metadata minima por linea de orden:
skuprice_list_codeapplied_priceregular_price_referencesource_hash
Metadata adicional recomendada:
pricing_modeprice_sourcesgc_customer_refcalculated_atpricing_status
J. Checkout/order metadata matrix¶
| Campo | Nivel | Fuente candidate | Requerido | Regla |
|---|---|---|---|---|
sku |
linea | producto Woo / SOURCE-002 | si | identifica precio aplicado |
price_list_code |
linea | SOURCE-001 Lista_Precio normalizada |
si | L1..L9 para B2B |
applied_price |
linea | SOURCE-002 PrecioLn |
si | precio final cobrado |
regular_price_reference |
linea | Woo regular_price / PrecioListaFinal |
si | referencia publica/default |
source_hash |
linea | snapshot/fuente OpenClaw | si | trazabilidad e invalidacion |
price_source |
linea/carrito | OpenClaw/PostgreSQL futuro | recomendado | no exponer costos/margenes |
pricing_status |
linea/carrito/orden | motor pricing futuro | recomendado | OK o bloqueo explicito |
sgc_customer_ref |
orden | mapping B2B | recomendado | referencia no sensible |
K. Dry-run de muestra¶
La simulacion usa evidencia documental previa, sin leer WooCommerce API, sin consultar PostgreSQL y sin ejecutar runtime.
Clientes sanitizados SOURCE-001 usados como referencia:
| Cliente sanitizado | Estado | Lista_Precio | price_list_code | Resultado sample |
|---|---|---|---|---|
SOURCE-001-L1-ACTIVE-CANDIDATE |
CLIENTE ACTIVO |
1 |
L1 |
B2B_PRICE_OK simulado |
SOURCE-001-L5-ACTIVE-CANDIDATE |
CLIENTE ACTIVO |
5 |
L5 |
B2B_PRICE_OK simulado |
SOURCE-001-SUSPENDED-CANDIDATE |
CLIENTE SUSPENDIDO |
1..9 |
Ln |
BLOCKED_CUSTOMER_STATUS |
SOURCE-001-INACTIVE-CANDIDATE |
CLIENTE DE BAJA |
1..9 |
Ln |
BLOCKED_CUSTOMER_STATUS |
SKUs piloto de PDF-009M:
| SKU | Producto | regular_price | PrecioL1 | PrecioL5 | Resultado |
|---|---|---|---|---|---|
2442 |
Pudding de Choco c/chip x300 grs |
2020.901 | 2020.900 | 2020.900 | PRICE_OK |
2443 |
Pudding Gales C/Nuez x300 grs |
2020.901 | 2020.900 | 2020.900 | PRICE_OK |
2444 |
Pudding Limon c/ semilla de Amapolla x300 grs |
2020.901 | 2020.900 | 2020.900 | PRICE_OK |
2847 |
Pudding Naranja c/ cascara x350 grs |
2020.901 | 2020.900 | 2020.900 | PRICE_OK |
2446 |
Pudding Vainila capa frutos secos x300 grs |
2020.901 | 2020.900 | 2020.900 | PRICE_OK |
2814 |
Chips Papas x 80gr Alwa |
1081.151 | 1081.150 | 1081.150 | PRICE_OK |
2815 |
Chips Batata x 80gr Alwa |
1081.151 | 1081.150 | 1081.150 | PRICE_OK |
2816 |
Pochoclo dulce x 75gr Alwa |
946.940 | 946.940 | 946.940 | PRICE_OK |
3514 |
Nachos con Chia x80gr Alwa |
1153.947 | 1153.950 | 1153.950 | PRICE_OK |
0269 |
Arrocitas C/Sal x 101gr Ce |
1015.718 | 1015.720 | 1015.720 | PRICE_OK |
Casos negativos:
| SKU | Producto | PrecioListaFinal | PrecioL1..PrecioL9 | Resultado |
|---|---|---|---|---|
3995 |
Saldos Clientes |
0.000 | todos 0.000 |
BLOCKED_PRICE_MISSING |
4010 |
Asesoramiento de servicios de marketing |
0.000 | todos 0.000 |
BLOCKED_PRICE_MISSING |
L. Dry-run runtime B2B¶
| Escenario | Cliente | SKU | Catalogo | Carrito | Checkout/orden |
|---|---|---|---|---|---|
| visitante | no logueado | 2442 |
PUBLIC_DEFAULT 2020.901 |
CART_PRICE_OK con regular |
orden publica sin price_list_code B2B |
| cliente Lista_Precio 1 | SOURCE-001-L1-ACTIVE-CANDIDATE |
2442 |
PrecioL1 2020.900 |
recalcula L1 server-side |
guarda sku, L1, 2020.900, regular ref, hash |
| cliente Lista_Precio 5 | SOURCE-001-L5-ACTIVE-CANDIDATE |
2442 |
PrecioL5 2020.900 |
recalcula L5 server-side |
guarda sku, L5, 2020.900, regular ref, hash |
| cliente suspendido | SOURCE-001-SUSPENDED-CANDIDATE |
2442 |
bloqueado | carrito bloqueado | orden bloqueada |
| cliente de baja | SOURCE-001-INACTIVE-CANDIDATE |
2442 |
bloqueado | carrito bloqueado | orden bloqueada |
| precio faltante L1 | SOURCE-001-L1-ACTIVE-CANDIDATE |
3995 |
BLOCKED_PRICE_MISSING |
carrito bloqueado | orden bloqueada |
| precio faltante L5 | SOURCE-001-L5-ACTIVE-CANDIDATE |
4010 |
BLOCKED_PRICE_MISSING |
carrito bloqueado | orden bloqueada |
M. Blocked cases matrix¶
| Bloqueo | Donde se detecta | Resultado | Regla |
|---|---|---|---|
BLOCKED_CUSTOMER_MAPPING |
catalogo/carrito/checkout | no aplicar B2B | mapping ausente, ambiguo o duplicado |
BLOCKED_CUSTOMER_STATUS |
catalogo/carrito/checkout | bloquear venta B2B | CLIENTE SUSPENDIDO o CLIENTE DE BAJA |
BLOCKED_PRICE_LIST |
catalogo/carrito/checkout | bloquear linea/pedido | lista ausente o fuera de 1..9 |
BLOCKED_PRICE_MISSING |
catalogo/carrito/checkout | bloquear linea/pedido | precio nulo, ausente o <= 0 |
BLOCKED_ORDER_INCONSISTENCY |
checkout | bloquear orden | precio/hash/lista difiere del recalculo final |
PUBLIC_DEFAULT |
catalogo/carrito publico | permitir flujo publico | visitante usa regular_price |
N. Impacto documental¶
Este documento:
- traduce las reglas aprobadas de
PDF-010Ga diseno runtime B2B; - define matching seguro
wc_customer_id -> sgc_customer_id; - define catalogo, carrito, checkout y metadata de orden;
- simula visitantes, clientes
Lista_Precio 1, clientesLista_Precio 5, clientes suspendidos/de baja y SKUs sin precio; - no implementa runtime;
- no habilita writes.
O. Archivos creados/modificados¶
Creado:
docs/tenants/alpuntodeventa/business-observer/production/PDF-010H-B2B-RUNTIME-DRY-RUN-DESIGN.md
Actualizados:
docs/tenants/alpuntodeventa/business-observer/production/README.mddocs/PROJECT-STATE.mddocs/ROADMAP.mddocs/governance/ACTIVE-CONTEXT.mdmkdocs.yml
Impacto:
- publica el gate documental
PDF-010Hen el Knowledge Portal; - actualiza estado y roadmap para reflejar que el proximo paso B2B ya tiene diseno/dry-run de runtime;
- no modifica codigo, runtime, WooCommerce ni PostgreSQL.
P. Validaciones requeridas¶
Validaciones de cierre de este gate:
git diff --check.\.venv-portal\Scripts\mkdocs.exe build --strict
Q. Estado final Git¶
Estado esperado al cierre:
- cambios documentales locales sin commit;
- sin push;
- sin deploy.
R. Recomendacion de commit¶
Si la revision humana aprueba este gate documental, commit sugerido:
docs: add pdf-010h b2b runtime dry-run design
No hacer commit sin autorizacion posterior.
S. Proximo paso recomendado¶
Abrir gate separado de implementacion tecnica sin writes iniciales:
- definir tabla o store real de mapping
wc_customer_id -> sgc_customer_id; - definir hook/plugin o capa headless para catalogo, carrito y checkout;
- preparar tests unitarios y dry-run local del motor de pricing;
- ejecutar cualquier read real de WooCommerce o PostgreSQL solo con autorizacion explicita;
- ejecutar cualquier write solo en gate posterior separado.
T. Restricciones preservadas¶
Durante este gate:
- no se toco WooCommerce API;
- no se toco PostgreSQL con writes;
- no se ejecuto SQL write;
- no se crearon clientes;
- no se crearon productos;
- no se modificaron precios reales;
- no se instalaron plugins;
- no se modifico theme;
- no se modifico runtime;
- no se imprimieron secretos;
- no se hizo push;
- no se hizo deploy;
- no se ejecuto sync;
- no se activo scheduler, cron ni pipelines.