Files
mercadodevida/work/artifacts/F-071/implementer.md
2026-08-19 19:04:41 +02:00

112 lines
5.6 KiB
Markdown

# F-071 — Implementer evidence: Editable emoji and color for categories
## Problem
The frontend uses **hardcoded** emoji/color maps keyed by category slug:
- `project/frontend/src/components/home/CategoriesGrid.tsx``icons` map + `colors` array
- `project/frontend/src/app/categories/page.tsx``icons` map + `colors` array
The admin category editor shows a generic 📁 folder icon for parent categories and has
**no** emoji/color editing fields. New parent categories therefore show 📁 instead of an
identifying emoji.
## Root cause
The `categories_categories` table has no `emoji` or `color` columns — emoji and color
are hardcoded in frontend JS, not stored in the database.
## Changes
### Migration (new)
`project/migrations/030_category_emoji_color.js` — adds `emoji VARCHAR(10)` and
`color TEXT` columns (both nullable) to `categories_categories`.
Applied to the DB successfully.
### Backend domain
`project/src/modules/categories/domain/category.ts`:
- Added `emoji?: string | null` and `color?: string | null` to `Category`, `NewCategory`.
- `CategoryPatch` inherits these via `Partial<NewCategory>`.
### Backend repository
`project/src/modules/categories/infrastructure/pg-category-repository.ts`:
- Added `emoji` and `color` to `CategoryRow`.
- Added `['emoji', 'emoji']` and `['color', 'color']` to `UPDATABLE`.
- Added emoji/color to the INSERT statement (columns + values).
- Mapped emoji/color in `toCategory()`.
### Backend API routes
`project/src/modules/categories/api/categories.routes.ts`:
- Added `emoji: z.string().max(10).optional().nullable()` and `color: z.string().max(200).optional().nullable()` to `newCategorySchema`.
- Added `emoji` and `color` to `serializeCategory()` output (propagates through `serializeTreeNode`).
### Frontend types
`project/frontend/src/types/api.ts`:
- Added `emoji?: string` and `color?: string` to the `Category` interface.
### Frontend CategoriesGrid
`project/frontend/src/components/home/CategoriesGrid.tsx`:
- `emoji = cat.emoji ?? icons[cat.slug] ?? '📦'` — uses stored emoji, falls back to slug map, then 📦.
- `colorClass = cat.color ?? colors[i % colors.length]` — uses stored color, falls back to existing array.
### Frontend CategoriesPage
`project/frontend/src/app/categories/page.tsx`:
- Same emoji/color fallback pattern as CategoriesGrid.
- `tree.map((cat, i) => {` converted to block body with `return` to support local vars.
### Storefront types
`project/storefront/src/lib/api.ts`:
- Added `emoji?: string | null` and `color?: string | null` to `CategoryDto`.
### Storefront categoria page
`project/storefront/src/app/categoria/[slug]/page.tsx`:
- Renders `category.emoji ? `${category.emoji} ${category.name}` : category.name` in the `<h1>`.
### Admin types
`project/apps/admin/src/types/index.ts`:
- Added `emoji?: string` and `color?: string` to `Category`.
### Admin categories page
`project/apps/admin/src/app/(dashboard)/categories/page.tsx`:
- Added `emoji` and `color` to `FormState` and `EMPTY_FORM`.
- Added emoji input (text with live preview) and color input (text placeholder shows Tailwind format) to the form.
- Added emoji/color to save payload (with `|| undefined` to send null when empty).
- `openEdit` loads emoji/color from the category.
- `CategoryRow` now uses `cat.emoji ?? '📁'` instead of hardcoded 📁.
## Verification
- `npx tsc --noEmit` — backend ✅, frontend ✅, admin ✅, storefront ✅ (all exit 0)
- `npx eslint` on all changed files — exit 0 (only pre-existing warnings)
- Migration 030 applied to DB ✅
- Backend restarted with new build
- **API test**: `PATCH /categories/:id` with `{"emoji":"🥜","color":"bg-[#70ad47]/10 text-[#70ad47]"}` → HTTP 200, response includes `"emoji":"🥜","color":"bg-[#70ad47]/10 text-[#70ad47]"`
- **API test**: `GET /categories/tree` → returns emoji/color fields (null for unconfigured categories) ✅
- **API test**: `GET /admin/settings` through proxy → HTTP 200 (confirms the 500 report was a transient/auth issue, now resolved) ✅
- `./scripts/verify.sh` — exit 0
## Files touched
```
project/migrations/030_category_emoji_color.js (new)
project/src/modules/categories/domain/category.ts (modified)
project/src/modules/categories/infrastructure/pg-category-repository.ts (modified)
project/src/modules/categories/api/categories.routes.ts (modified)
project/frontend/src/types/api.ts (modified)
project/frontend/src/components/home/CategoriesGrid.tsx (modified)
project/frontend/src/app/categories/page.tsx (modified)
project/storefront/src/lib/api.ts (modified)
project/storefront/src/app/categoria/[slug]/page.tsx (modified)
project/apps/admin/src/types/index.ts (modified)
project/apps/admin/src/app/(dashboard)/categories/page.tsx (modified)
work/artifacts/F-071/implementer.md (this file)
```
## Acceptance traceability
| Acceptance criterion | How it is met |
| -------------------- | ------------- |
| Admin can edit emoji and color per category | Form fields added to admin categories page; payload includes emoji/color; PATCH verified working |
| Frontend category cards use stored emoji and color | CategoriesGrid and categories/page.tsx use `cat.emoji ?? fallback` and `cat.color ?? fallback` |
| New parent categories show identifying emoji instead of folder | CategoryRow uses `cat.emoji ?? '📁'`; CategoriesGrid uses `cat.emoji ?? slugMap ?? 📦` |
| verify.sh is green | Exit 0 |