feat(F-079): completed feature
This commit is contained in:
35
work/artifacts/F-079/architect.md
Normal file
35
work/artifacts/F-079/architect.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# F-079 — Architect: Product list /products does not show brand
|
||||
|
||||
## Root cause
|
||||
|
||||
The admin `/products` page already renders a `Marca` column with `{p.brand?.name ?? '—'}`, and the `Product` TS type already declares an optional `brand: { id, name, slug }`. However, the backend `PgProductRepository` never populates that field: `PRODUCT_COLUMNS` does not LEFT JOIN `brands_brands`, and `toProduct(row)` only emits `brandId: row.brand_id` without a denormalized `brand` object. So every row in the list renders `—` regardless of whether a brand is assigned.
|
||||
|
||||
## Design
|
||||
|
||||
Single change set in the repository:
|
||||
|
||||
1. **`ProductRow` interface** gains optional fields `brand_name: string | null` and `brand_slug: string | null`.
|
||||
2. **`PRODUCT_COLUMNS`** is replaced with a subquery (`PRODUCT_BASE_COLUMNS`) that LEFT JOINs `brands_brands` and selects `b.name AS brand_name, b.slug AS brand_slug`. Existing queries (`findById`, `findActiveBySlug`, `listAll`) keep their semantics but read the new column set.
|
||||
3. **`toProduct(row)`** emits `brand` only when `brand_id IS NOT NULL`:
|
||||
```ts
|
||||
brand: row.brand_id
|
||||
? { id: row.brand_id, name: row.brand_name ?? '', slug: row.brand_slug ?? '' }
|
||||
: undefined,
|
||||
```
|
||||
When `brand_id` is null the frontend falls back to the existing `—` placeholder.
|
||||
|
||||
## No new tables, no API contract change.
|
||||
|
||||
Frontend is already prepared (the column, the type and the placeholder all exist). After the change:
|
||||
- Products with a brand: column shows the brand name.
|
||||
- Products without a brand: column shows `—` (placeholder behavior is unchanged).
|
||||
|
||||
## Risk
|
||||
|
||||
Low. Pure read-side change. Existing tests on the repository must still pass.
|
||||
|
||||
## Acceptance mapping
|
||||
- "Each row in /products listing shows the brand name" → toProduct now hydrates `brand.name`.
|
||||
- "Brand column header is present" → already in page.tsx.
|
||||
- "Empty brand renders as a placeholder" → existing `p.brand?.name ?? '—'` handles it.
|
||||
- "verify.sh is green" → no test regression expected.
|
||||
Reference in New Issue
Block a user