Task #24: Older scans created before description generation existed showed an
empty "Was macht dieser Skill?" section. Users can now trigger description
generation for any existing scan from the report.
Changes:
- OpenAPI: added POST /scans/{id}/description (operationId generateScanDescription)
returning ScanDetail (200), ApiError (404 not found, 422 cannot generate).
Regenerated api-zod and api-client-react via codegen.
- api-server (routes/scans.ts): new route loads the scan, its stored files, the
enabled provider and prompts, reconstructs ParsedFile[] from scan_files
(binary files -> empty content/isBinary), calls existing
generateSkillDescription(), persists description and returns full ScanDetail.
Clean 422 errors when no provider / no token / generation yields nothing; the
scan is never mutated on failure.
- skillguard (scan-report.tsx): the description card now always renders; when no
description exists it shows a "Beschreibung erzeugen" button wired to the new
mutation, with loading state, toast feedback, and query cache update on success.
Incidental fix: the dev/test database was missing the `scans.description` column
(schema drift from the earlier description task). Ran drizzle-kit push to sync;
this unblocked 5 previously failing api-server tests. All 59 tests now pass and
full typecheck is green.
Rebase: one conflict in scan-report.tsx import line — main added the `ShieldAlert`
icon (new KI-disclaimer Alert), this branch added `Loader2`. Resolved by keeping
both icons; the rest of the file (disclaimer Alert + new description card) merged
cleanly. No semantic divergence.
Replit-Task-Id: 0610af4f-aa62-434e-abcd-d742081b6459