25 lines
1.6 KiB
Markdown
25 lines
1.6 KiB
Markdown
# F-100 — Generación automática de SKU desde el título
|
|
|
|
## Backend
|
|
- `src/modules/catalog/domain/sku.ts` (helper puro):
|
|
- `generateSkuFromTitle(title)`: normaliza mayúsculas, diacríticos, separadores; produce `MV-<SLUG>` (max 100 chars).
|
|
- `uniqueSku(base, existing)`: añade `-2`, `-3`, … hasta encontrar uno libre; truncando a 100 chars.
|
|
- `src/modules/catalog/tests/sku.test.ts` (9 tests): normalización, acentos, `&`, hyphens, longitud, mayúsculas, lowercase collisions, truncado.
|
|
- `src/modules/catalog/domain/ports.ts` + `pg-variant-repository.ts`: nuevo `listAllSkus()` para reutilizar en la creación.
|
|
- `src/modules/catalog/api/catalog.routes.ts`:
|
|
- `POST /products/sku:generate` (admin): recibe `{ title }` y devuelve `{ sku }` único.
|
|
- `POST /products`: la variante por defecto ahora se crea con `generateSkuFromTitle(product.name)` + `uniqueSku` en vez de `SKU-MV-${uuid}`.
|
|
- `GET /products/:id/variants` (lazy migration): igualmente usa SKU derivado del título.
|
|
|
|
## Admin UI (apps/admin)
|
|
- `lib/api-client.ts`: `productsApi.generateSku(title)`.
|
|
- `features/products/components/sections/PriceStockSection.tsx`:
|
|
- Nuevo bloque "SKU" con input editable (validación `^[A-Za-z0-9-]+$`), botón `↻` para regenerar sugerencia.
|
|
- Guardado en blur/Enter; mensajes: `✓` / `SKU duplicado` / `SKU inválido`.
|
|
|
|
## Evidencia
|
|
- `npm run typecheck` (backend) OK.
|
|
- `npm test`: 169 passed / 0 failed (9 nuevos).
|
|
- `apps/admin tsc --noEmit` OK.
|
|
- Smoke: `POST /products/sku:generate { "title": "Aceite de Oliva Virgen Extra" }` → `{ "sku": "MV-ACEITE-DE-OLIVA-VIRGEN-EXTRA" }`.
|