73 lines
2.5 KiB
Markdown
73 lines
2.5 KiB
Markdown
# 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 `ean` column
|
|
|
|
### 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_grams` to `VariantRow` interface
|
|
- Added `['weightGrams', 'weight_grams']` to `UPDATABLE` array
|
|
- Updated `create()` to INSERT `weight_grams`
|
|
- Updated `toVariant()` to map `weight_grams → weightGrams`
|
|
|
|
### 4. `project/src/modules/catalog/api/catalog.routes.ts`
|
|
|
|
- Added `weightGrams` to `newVariantSchema` (zod, optional, integer >= 1)
|
|
- Added `weightGrams` to `serializeVariant()` output
|
|
|
|
### 5. `project/src/modules/checkout/application/checkout-service.ts`
|
|
|
|
- Extended `getCartWeightKg` parameter type to include `variantId`
|
|
- Updated call site to pass full `cart.items` (no mapping needed)
|
|
|
|
### 6. `project/src/modules/checkout/api/checkout.routes.ts`
|
|
|
|
- Rewrote `getCartWeightKg` to:
|
|
- Fetch variant-level `weight_grams` from `catalog_product_variants`
|
|
- Fetch product-level `unit_weight_kg` as fallback
|
|
- Prefer variant weight (g → kg) when available
|
|
- Fall back to product weight (kg) when variant weight is null
|
|
|
|
### 7. `project/frontend/src/lib/api.ts`
|
|
|
|
- Added `weightGrams: number | null` to `ProductVariant` interface
|
|
|
|
### 8. `project/frontend/src/types/api.ts`
|
|
|
|
- Added `expirationDate?: string` to `Product` interface
|
|
|
|
### 9. `project/frontend/src/app/products/[slug]/page.tsx`
|
|
|
|
Added expiry date and weight display in the price box:
|
|
- `Caduca: {date}` — when `product.expirationDate` is set
|
|
- `Peso: {X.Y kg}` or `Peso: {X g}` — from `primaryVariant.weightGrams`
|
|
|
|
### Existing (no changes needed)
|
|
|
|
- `catalog_products.expiration_date` — already exists from migration 038
|
|
- `catalog_products.unit_weight_kg` — already exists as fallback
|
|
- `ShippingService` — already takes `cartWeightKg` and filters by `maxWeightKg`
|
|
- `serializeProduct()` — already serializes `expirationDate`
|
|
|
|
## 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 |
|