feat(F-096): completed feature

This commit is contained in:
chattie
2026-08-20 22:12:01 +02:00
parent 4b60db026b
commit 5561776627
14 changed files with 298 additions and 67 deletions

View File

@@ -0,0 +1,14 @@
# F-096 — Implementer evidence
## Changes
- Added AI settings to admin Ajustes: provider, OpenAI-compatible base URL, model, API key, and separate SEO title/description prompts with `{{name}}`, `{{description}}`, and `{{brand}}` variables.
- API keys are never returned by GET settings; only `aiApiKeyConfigured` is exposed.
- Added authenticated `POST /products/:id/generate-seo`, which calls the configured chat-completions endpoint only for empty SEO fields and persists generated values.
- ProductEditor calls generation after save when either SEO field is empty; manually entered values are preserved.
## Validation
- Root `npm run typecheck` → exit 0
- Admin `npx tsc --noEmit` → exit 0
- Admin ESLint on touched files → 0 errors (warnings only)

View File

@@ -0,0 +1,15 @@
{
"feature_id": "F-096",
"agent": "leader",
"verdict": "APPROVED",
"summary": "F-096 adds configurable OpenAI-compatible AI SEO generation for empty product SEO fields without overwriting manual values.",
"evidence": [
"reviewer.json verdict=APPROVED",
"security.json verdict=APPROVED",
"qa.json verdict=APPROVED",
"Backend and admin production builds exit 0",
"Root tests: 133 passed, 56 skipped",
"scripts/verify.sh exit 0"
],
"timestamp": "2026-08-20T20:12:20Z"
}

View File

@@ -0,0 +1,15 @@
{
"feature_id": "F-096",
"agent": "qa",
"verdict": "APPROVED",
"summary": "AI settings and empty SEO generation pass typechecks, builds, tests, and harness verification.",
"evidence": [
"Root npm run typecheck exit 0",
"Root npm run build exit 0",
"Admin npx tsc --noEmit exit 0",
"Admin npm run build exit 0",
"Root tests: 133 passed, 56 skipped",
"scripts/verify.sh exit 0"
],
"timestamp": "2026-08-20T20:12:10Z"
}

View File

@@ -0,0 +1,13 @@
{
"feature_id": "F-096",
"agent": "reviewer",
"verdict": "APPROVED",
"summary": "Settings expose the requested AI configuration and field-specific prompts; product SEO generation is explicit about filling only empty fields.",
"evidence": [
"Ajustes includes provider, base URL, model, API key, and separate SEO prompts",
"POST /products/:id/generate-seo checks each field independently before generation",
"ProductEditor invokes generation after save only when a field is empty",
"Manual SEO values are not overwritten"
],
"timestamp": "2026-08-20T20:11:00Z"
}

View File

@@ -0,0 +1,14 @@
{
"feature_id": "F-096",
"agent": "security",
"verdict": "APPROVED",
"summary": "The AI key stays server-side and is omitted from settings responses; generation is admin-authenticated and only writes empty SEO fields.",
"evidence": [
"GET settings returns aiApiKey as empty and only exposes aiApiKeyConfigured",
"AI provider calls occur in the backend with the key in an Authorization header",
"Generation endpoint requires admin authentication",
"No client-side provider call or API key exposure",
"Generated output is length-bounded before persistence"
],
"timestamp": "2026-08-20T20:11:20Z"
}

View File

@@ -1,14 +1,22 @@
# Feature actual
## Feature activa: F-095 (in_progress) — Download remote image URL before attaching product image
## Feature activa: F-096 (in_progress) — Configure AI model and generate missing product SEO fields
Backlog: 163 features (153 done, 9 pending, 1 in_progress).
Backlog: 164 features (154 done, 9 pending, 1 in_progress).
Últimas features cerradas: **F-080**, **F-081**, **F-082**, **F-083**, **F-084**, **F-085**, **F-086**, **F-087**.
## Incidencia actual (2026-08-20)
Añadir una imagen por URL devuelve 400 porque el flujo hace un PATCH vacío del producto y adjunta directamente la URL remota. F-095 descargará la imagen validada a uploads locales antes de adjuntarla.
Ajustes no permite configurar un modelo IA, API key ni prompts específicos para SEO. Los campos SEO vacíos no se generan automáticamente. F-096 añade la configuración y generación sin sobrescribir valores manuales.
## Última incidencia resuelta (2026-08-20)
F-095 cerrada con todos los gates aprobados. Las imágenes URL se descargan y almacenan en uploads locales antes de adjuntarse.
## Incidencia anterior (2026-08-20)
Añadir una imagen por URL devolvía 400 porque el flujo hacía un PATCH vacío del producto y adjuntaba directamente la URL remota.
## Última incidencia resuelta (2026-08-20)

View File

@@ -1,69 +1,13 @@
{
"feature_id": "F-095",
"feature_id": "F-096",
"stage": "close",
"agent": "leader",
"action": "Validate F-095 gates and close remote image importer",
"action": "Validate F-096 gates and close AI SEO generation",
"state": "running",
"next_agent": "leader",
"waiting_for": "verify.sh green",
"updated_at": "2026-08-20T20:05:44Z",
"updated_at": "2026-08-20T20:11:50Z",
"timeline": [
{
"ts": "2026-08-20T19:55:40Z",
"agent": "leader",
"stage": "intake",
"state": "running",
"message": "Triage inventory search limited to product name; add EAN matching"
},
{
"ts": "2026-08-20T19:55:51Z",
"agent": "implementer",
"stage": "build",
"state": "running",
"message": "Extend admin catalog list query with partial EAN matching and update inventory search label"
},
{
"ts": "2026-08-20T19:57:04Z",
"agent": "reviewer",
"stage": "review_gate",
"state": "running",
"message": "Review inventory EAN/name search query and UI label"
},
{
"ts": "2026-08-20T19:57:14Z",
"agent": "security",
"stage": "security_gate",
"state": "running",
"message": "Check EAN search query parameterization and scope"
},
{
"ts": "2026-08-20T19:57:23Z",
"agent": "qa",
"stage": "qa_gate",
"state": "running",
"message": "Run inventory search checks and verify"
},
{
"ts": "2026-08-20T19:57:34Z",
"agent": "leader",
"stage": "close",
"state": "running",
"message": "Validate F-093 gates and close inventory EAN/name search"
},
{
"ts": "2026-08-20T19:58:08Z",
"agent": "leader",
"stage": "close",
"state": "done",
"message": "F-093 cerrado: búsqueda de Inventario por EAN o nombre"
},
{
"ts": "2026-08-20T19:58:26Z",
"agent": "leader",
"stage": "intake",
"state": "running",
"message": "Triage missing variant creation UI and explanation in Publish tab"
},
{
"ts": "2026-08-20T19:58:57Z",
"agent": "implementer",
@@ -147,6 +91,62 @@
"stage": "close",
"state": "running",
"message": "Validate F-095 gates and close remote image importer"
},
{
"ts": "2026-08-20T20:06:13Z",
"agent": "leader",
"stage": "close",
"state": "done",
"message": "F-095 cerrado: imágenes URL descargadas y almacenadas localmente"
},
{
"ts": "2026-08-20T20:07:05Z",
"agent": "leader",
"stage": "close",
"state": "done",
"message": "F-095 cerrado: importación de imágenes URL con descarga segura"
},
{
"ts": "2026-08-20T20:07:19Z",
"agent": "leader",
"stage": "intake",
"state": "running",
"message": "Triage AI configuration fields and generation of empty product SEO fields"
},
{
"ts": "2026-08-20T20:07:49Z",
"agent": "implementer",
"stage": "build",
"state": "running",
"message": "Add AI settings, OpenAI-compatible SEO generation endpoint, and empty-field product editor trigger"
},
{
"ts": "2026-08-20T20:10:53Z",
"agent": "reviewer",
"stage": "review_gate",
"state": "running",
"message": "Review AI settings, empty SEO generation, and manual-value preservation"
},
{
"ts": "2026-08-20T20:11:07Z",
"agent": "security",
"stage": "security_gate",
"state": "running",
"message": "Check AI key handling, provider calls, prompt scope, and response exposure"
},
{
"ts": "2026-08-20T20:11:20Z",
"agent": "qa",
"stage": "qa_gate",
"state": "running",
"message": "Run AI settings/product SEO typechecks, tests, build, and verify"
},
{
"ts": "2026-08-20T20:11:50Z",
"agent": "leader",
"stage": "close",
"state": "running",
"message": "Validate F-096 gates and close AI SEO generation"
}
]
}