Files
mercadodevida/project/specs/FEATURE_GAP_MATRIX.md
2026-08-17 22:23:10 +02:00

221 lines
9.0 KiB
Markdown

# FEATURE GAP MATRIX
**Project**: MercadoDeVida vNext
**Inspected**: 2026-08-17
**Backend**: project/src/ | **Storefront**: project/frontend/src/ | **Admin**: project/apps/admin/src/
---
## FEATURE A — Expiration Tracking
| Aspect | Status | Details |
|--------|--------|---------|
| Product model | ⚠️ PARTIAL | Has `ProductState`, no `expiration_tracking_enabled` |
| Inventory model | ⚠️ PARTIAL | `inventory_stock` at variant level only; no lots |
| Inventory repository | ✅ EXISTS | `PgInventoryRepository` (variant-level) |
| Lot model | ❌ MISSING | `inventory_lots` table does not exist |
| Lot repository | ❌ MISSING | No lot-level persistence |
| LotService | ❌ MISSING | Domain service for FEFO + expiry validation |
| InventoryService extended | ❌ MISSING | Delegates to LotService for expiry products |
| Checkout integration | ✅ EXISTS | Uses `InventoryServicePort` — boundary correct |
| GET /inventory/lots | ❌ MISSING | Need this route |
| POST /inventory/lots | ❌ MISSING | Need this route |
| PATCH /inventory/lots/:id | ❌ MISSING | Need this route |
| DELETE /inventory/lots/:id | ❌ MISSING | Need this route |
| GET /inventory/lots with filter | ❌ MISSING | Need ?filter=expiring\|expired\|all |
| Admin product editor | ⚠️ PARTIAL | Has General/Pricing/Inventory/Images/SEO/Publish tabs; no expiry toggle |
| Admin inventory view | ⚠️ PARTIAL | Shows variant stock; no lots |
| Admin expiry filters | ❌ MISSING | Need filter tabs in /admin/inventory |
| Audit for lot mutations | ⚠️ PARTIAL | `AuditLogger` exists; new operation types needed |
| Feature flag | ✅ EXISTS | `FLAG_EXPIRY_TRACKING` can be used |
| DB migration | ❌ MISSING | inventory_lots table, column on catalog_products |
**Backend blockers**: None — can implement in isolation
**DB blocker**: EXP-DB-001 must run before EXP-BE-005 (InventoryService extension)
---
## FEATURE B — Brand Migration
| Aspect | Status | Details |
|--------|--------|---------|
| Tailwind @theme tokens | ✅ EXISTS | `--color-primary: #2D6A4F`, `--color-accent: #E76F51`, fonts set |
| Google Fonts (Inter + Playfair) | ✅ EXISTS | Loaded in globals.css |
| businessConfig | ❌ MISSING | No single source of truth for company info |
| Official logo | ❌ MISSING | Not downloaded; no file in /public/images |
| Header component | ✅ EXISTS | Has logo slot; needs actual logo + businessConfig |
| Footer component | ✅ EXISTS | Needs businessConfig + social links |
| /about page | ✅ EXISTS | Has placeholder content; needs legacy migration |
| /contact page | ✅ EXISTS | Has placeholder content; needs real contact info |
| /shipping page | ✅ EXISTS | Needs enhancement with real policy |
| /terms page | ✅ EXISTS | Needs legacy migration + legal review |
| /privacy page | ✅ EXISTS | Needs creation from scratch |
| /cookies page | ✅ EXISTS | Needs creation from scratch |
| /legal page | ⚠️ PARTIAL | May not exist |
| Legacy redirect map | ⚠️ PARTIAL | Partially mapped; needs full sitemap extraction |
| next.config.ts redirects | ⚠️ PARTIAL | Some routes exist; needs completion + product slugs |
| sitemap.ts | ✅ EXISTS | Needs updating to include migrated routes |
| robots.ts | ✅ EXISTS | Needs updating for new site structure |
| Admin sidebar logo | ⚠️ PARTIAL | Has inline SVG; needs real logo |
| Admin branding | ✅ EXISTS | Same tokens as storefront |
**Backend blockers**: None
**⚠️ Warning**: Legal pages require human review before publishing
---
## FEATURE C — Bulk Update
| Aspect | Status | Details |
|--------|--------|---------|
| BulkOperationHandler port | ❌ MISSING | Interface for pluggable handlers |
| Price handlers (5 ops) | ❌ MISSING | SET, INCREASE/DECREASE (%, fixed) |
| Category handlers (3 ops) | ❌ MISSING | ADD, REMOVE, REPLACE |
| BulkService orchestrator | ❌ MISSING | preview() + execute() + audit |
| BulkProductRepository | ❌ MISSING | Batch read with pricing join |
| Bulk API routes | ❌ MISSING | POST /admin/bulk/preview, POST /admin/bulk/execute |
| PricingService | ✅ EXISTS | `netUnitAmountCents`, VAT calculation |
| ProductRepository | ✅ EXISTS | Has `update(id, patch)` |
| Category API | ✅ EXISTS | Categories managed via product.categoryIds |
| AuditLogger | ✅ EXISTS | `security_audit_log` table exists |
| RBAC | ✅ EXISTS | `permissions.ts` with `products.bulk_update` can be added |
| Feature flag | ✅ EXISTS | `FLAG_ADMIN_BULK_UPDATE` can be used |
| Admin product list | ✅ EXISTS | Checkbox selection is feasible |
| Admin bulk update page | ❌ MISSING | New /admin/bulk-update route |
| Navigation entry | ⚠️ PARTIAL | Need to add to NAV_ITEMS |
**Backend blockers**: None — all components can be built in isolation
**⚠️ Critical**: No bulk update should be exposed without confirmation UI
---
## API Changes Required
### New Endpoints (Backend)
| Endpoint | Method | Auth | Purpose |
|----------|--------|------|---------|
| `/inventory/lots` | GET | admin | List lots with filter |
| `/inventory/lots` | POST | admin | Create lot |
| `/inventory/lots/:id` | PATCH | admin | Update lot |
| `/inventory/lots/:id` | DELETE | admin | Delete lot |
| `/admin/bulk/preview` | POST | admin | Dry-run bulk operation |
| `/admin/bulk/execute` | POST | admin | Execute bulk operation |
### Modified Endpoints
| Endpoint | Change | Reason |
|---------|--------|--------|
| `GET /products/:id` | + `expiration_tracking_enabled` field | Product expiry policy |
| `PATCH /products/:id` | + accepts `expiration_tracking_enabled` | Set product expiry policy |
| `PUT /inventory/:variantId/stock` | Consider deprecating in favor of lots | For expiry products |
### No Changes Required
- `POST /cart`, `POST /checkout` — use InventoryServicePort unchanged
- `GET /products/search` — unchanged
- `GET /categories/tree` — unchanged
- `GET /brands` — unchanged
---
## Database Changes Required
### New Tables
| Table | Purpose |
|-------|---------|
| `inventory_lots` | Per-arrival stock with expiration date |
| `inventory_lot_movements` | Optional: movement tracking per lot |
### Modified Tables
| Table | Change | Default |
|-------|--------|---------|
| `catalog_products` | + `expiration_tracking_enabled boolean` | `false` |
| `inventory_movements` | + `lot_id uuid` (nullable) | `NULL` |
| `inventory_movements` | + new operation types | — |
### Indexes
| Index | Table | Columns |
|-------|-------|---------|
| `inventory_lots_variant_id_idx` | `inventory_lots` | `variant_id` |
| `inventory_lots_expiration_idx` | `inventory_lots` | `expiration_date` (partial) |
---
## STOREFRONT Changes
### Expected: NONE
**Expiration**: Checkout uses `InventoryServicePort` unchanged. No lot querying from frontend. No expiration display requirement from product team.
**Branding**: Storefront touches every visual component (Header, Footer, pages). Changes scoped to: tokens, logo, static pages, redirects.
**Bulk Update**: ZERO storefront changes. Bulk update is an Admin-only feature. Storefront automatically reflects updated prices/categories because it reads from the same backend.
---
## Cross-Feature Impact
```
FEATURE A (Expiration)
┌─ EXP-BE-005 (InventoryService extension)
│ └─ Checkout uses InventoryServicePort → NO CHANGE to checkout code
│ └─ Unit test regression required
└─ EXP-ADM-002/003/004 (Admin lot UI)
└─ Uses new lot API routes
FEATURE B (Branding)
┌─ Token updates may touch frontend + admin globals.css
│ └─ Build verification required on both apps
└─ Redirects in next.config.ts
└─ May conflict with existing routes → verify no overlap
FEATURE C (Bulk Update)
┌─ Bulk write to catalog_products (prices, categories)
│ └─ Storefront reads same DB → no code change needed
└─ New admin route /admin/bulk-update
└─ No conflict with existing routes
```
---
## Implementation Order
```
1. EXPIRATION
├─ BE: EXP-BE-001 (product column) ──┐
├─ BE: EXP-BE-002 (lot model) ──────────┼── parallel
└─ DB: EXP-DB-001 (run migrations) ────┘
2. EXPIRATION
├─ BE: EXP-BE-003 (LotService) ────────▶ EXP-BE-004 (lot routes)
│ │
└─ BE: EXP-BE-005 (InventoryService) ◀──────┘
3. BRAND + BULK (parallel)
├─ BRAND: BRAND-FE-001..003 (assets, config) ──▶ BRAND-FE-004..009 (pages, redirects)
└─ BULK: BULK-BE-001..008 (all backend) ──────────────────▶ BULK-ADM-001..005
4. ALL FEATURES
├─ QA: EXP-QA-001 + BULK-QA-001 (E2E regression)
├─ BRAND: Legal pages human review
└─ FLAGS: Flip feature flags when ready
```
---
## Feature Flags Needed
| Flag | Feature | Default |
|------|---------|---------|
| `expiration_tracking` | Expiration tracking (lot model + FEFO) | `false` |
| `admin_bulk_update` | Bulk update module in admin | `false` |
Branding has no feature flag — purely additive changes that cannot break existing functionality.