1.7 KiB
1.7 KiB
F-138 — Criterios de aceptación
AC1 — Sembrado inmediato de precio
Tras crear una variante, GET /pricing/variants/:variantId devuelve 200 (no 404) con una fila default: netUnitAmountCents = 0, vatRate = 'general', currency = 'EUR'.
- Unit:
CreateProductVariant.executellama aPricingService.seedVariantPrice(variant.id)trasvariants.create. - Itest (skip sin DB): POST
/products/:id/variants→ GET/pricing/variants/:variantId= 200.
AC2 — Idempotente (re-sembbrado no-op)
Si la fila de precio ya existe, re-sembrar no lanza ni duplica: ON CONFLICT (variant_id) DO NOTHING.
- Unit: segunda llamada a
seedVariantPriceno arroja;seedCallscontiene el id una sola vez (o ambas, sin error).
AC3 — Best-effort (no rompe la creación)
Si seedVariantPrice lanza, CreateProductVariant.execute sigue devolviendo la variante creada (no propaga el error).
- Unit: con
FakePricingService.seedShouldThrow = true,executedevuelve elProductVariantsin lanzar.
AC4 — Los 3 call sites crean la variante con precio
Los 3 puntos que crean variantes dejan fila de precio:
POST /products(autovarianteSKU-MV-{id}).GET /products/:id/variants(lazy, admin).POST /products/:id/variants.
- Todos comparten la misma instancia
createVariant(inyectapricing) → todos sembran.
Gates
- reviewer: arquitectura limpia (pricing owning su tabla; inyección de servicio público; build-app ordering safe).
- security: SQL con parámetro (
$1), literales'general'/0/NULL(no user input); no inyección. - qa: tests unitarios 3/3 verdes;
npm testno rompe; tsc 0 errores; verify.sh green.