feat(F-096): completed feature
This commit is contained in:
14
work/artifacts/F-096/implementer.md
Normal file
14
work/artifacts/F-096/implementer.md
Normal 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)
|
||||
15
work/artifacts/F-096/leader-close.json
Normal file
15
work/artifacts/F-096/leader-close.json
Normal 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"
|
||||
}
|
||||
15
work/artifacts/F-096/qa.json
Normal file
15
work/artifacts/F-096/qa.json
Normal 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"
|
||||
}
|
||||
13
work/artifacts/F-096/reviewer.json
Normal file
13
work/artifacts/F-096/reviewer.json
Normal 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"
|
||||
}
|
||||
14
work/artifacts/F-096/security.json
Normal file
14
work/artifacts/F-096/security.json
Normal 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"
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user