2.5 KiB
2.5 KiB
F-193 — Implementer Evidence
Feature
Show product expiry and shipping weight on storefront + authoritative variant weight in shipping.
Changes
1. project/migrations/057_product_variant_weight_and_expiry.js (new)
Adds weight_grams column to catalog_product_variants:
integer, nullable, no default- CHECK:
weight_grams IS NULL OR weight_grams > 0 - After
eancolumn
2. project/src/modules/catalog/domain/variant.ts
Added weightGrams to ProductVariant, NewProductVariant, and ProductVariantPatch.
3. project/src/modules/catalog/infrastructure/pg-variant-repository.ts
- Added
weight_gramstoVariantRowinterface - Added
['weightGrams', 'weight_grams']toUPDATABLEarray - Updated
create()to INSERTweight_grams - Updated
toVariant()to mapweight_grams → weightGrams
4. project/src/modules/catalog/api/catalog.routes.ts
- Added
weightGramstonewVariantSchema(zod, optional, integer >= 1) - Added
weightGramstoserializeVariant()output
5. project/src/modules/checkout/application/checkout-service.ts
- Extended
getCartWeightKgparameter type to includevariantId - Updated call site to pass full
cart.items(no mapping needed)
6. project/src/modules/checkout/api/checkout.routes.ts
- Rewrote
getCartWeightKgto:- Fetch variant-level
weight_gramsfromcatalog_product_variants - Fetch product-level
unit_weight_kgas fallback - Prefer variant weight (g → kg) when available
- Fall back to product weight (kg) when variant weight is null
- Fetch variant-level
7. project/frontend/src/lib/api.ts
- Added
weightGrams: number | nulltoProductVariantinterface
8. project/frontend/src/types/api.ts
- Added
expirationDate?: stringtoProductinterface
9. project/frontend/src/app/products/[slug]/page.tsx
Added expiry date and weight display in the price box:
Caduca: {date}— whenproduct.expirationDateis setPeso: {X.Y kg}orPeso: {X g}— fromprimaryVariant.weightGrams
Existing (no changes needed)
catalog_products.expiration_date— already exists from migration 038catalog_products.unit_weight_kg— already exists as fallbackShippingService— already takescartWeightKgand filters bymaxWeightKgserializeProduct()— already serializesexpirationDate
Verification
| Check | Result |
|---|---|
npx tsc --noEmit (backend) |
0 errors |
npx tsc --noEmit (frontend) |
0 errors |
npm test (backend) |
269 passed, 96 skipped |
./scripts/verify.sh |
OK |