# F-079 — Implementer evidence ## What was implemented The `/products` admin listing was rendering `—` for every brand cell because the backend `PgProductRepository` never hydrated the `brand` field on `Product`. The frontend column, the TS type and the placeholder were already in place; only the repository needed to denormalize brand info. ### Files changed - `project/src/modules/catalog/infrastructure/pg-product-repository.ts` - `ProductRow` adds `brand_name: string | null` and `brand_slug: string | null`. - `PRODUCT_COLUMNS` selects `b.name AS brand_name, b.slug AS brand_slug` so every query that uses the constant now joins brands. - `findById`, `findActiveBySlug` and `listAll` (both branches of `listAll`) now `LEFT JOIN brands_brands b ON b.id = p.brand_id` and include `b.name, b.slug` in the `GROUP BY`. - `toProduct(row)` emits `brand: { id, name, slug }` only when `brand_id`, `brand_name` and `brand_slug` are all non-null. Otherwise the field is omitted, so the frontend placeholder still kicks in. - `project/src/modules/catalog/domain/product.ts` - Added `ProductBrandSummary` interface and an optional `brand?: ProductBrandSummary` field on `Product`, matching the existing admin type. ## Validation - `npx tsc --noEmit` (whole project) → exit 0 - `npx eslint` on changed files → exit 0 - `npx vitest run src/modules/catalog/tests/` → 4 files / 9 tests passed ## Acceptance trace - "Each row in /products listing shows the brand name (or `—` when not assigned)" → `toProduct` now hydrates `brand.name`; missing brand → field undefined → existing `?? '—'` placeholder. - "Brand column header is present and aligned" → unchanged from prior to fix. - "Empty brand renders as a placeholder, not raw null/undefined" → frontend `p.brand?.name ?? '—'` is unchanged and now receives a defined object whenever `brand_id` is set. - "verify.sh is green" → green per local `npx tsc`, `npx eslint`, `npx vitest run`.