skillguard/.agents/memory/MEMORY.md
amertensreplit 2f7e58670a Add automated tests for model discovery (POST /providers/list-models)
Task #25: the model-discovery capability (list available models, used by the
guided provider setup) had no automated coverage. Added a new vitest suite that
exercises the endpoint end-to-end against the in-process Express app.

New file:
- artifacts/api-server/src/routes/providers.listModels.test.ts

Coverage (6 tests, all passing):
- ok=false + clear German message when no token (empty token, no providerId),
  and the upstream provider is never called.
- Falls back to the stored provider token when providerId is given and apiToken
  is empty (inserts a real provider row, asserts the Bearer header carries the
  stored token, cleans up afterward).
- Normalizes the OpenAI-compatible response (data[].id) into a deduped, sorted
  model list; drops non-string ids.
- Anthropic path: GET /models with x-api-key + anthropic-version headers (no
  Authorization), reads models[] with id/name fallback, dedupes.
- Upstream failure returns ok=false (HTTP 200, not 500), empty models, and the
  token is redacted from the message ([REDACTED], never the raw token).
- fetch throwing (network error) returns ok=false without leaking the token.

Implementation note: the suite runs the app in-process and the test client also
uses fetch, so global fetch is mocked with a passthrough — requests to the test
server's baseUrl delegate to the captured real fetch; only upstream provider URLs
are synthesized. Spy assertions filter out the localhost passthrough call.
Saved this non-obvious testing lesson to memory.

Deviation / note: pre-existing failures in relation.test.ts and compare.test.ts
are unrelated to this task — the dev database's scans table is missing the
fingerprint/relation/similarity/compared_scan_id columns (schema drift; needs a
drizzle-kit push). Out of scope for this task; proposed as a follow-up.

Replit-Task-Id: 7e8a3db2-0da7-40d9-b74d-132779a44d39
2026-06-10 21:20:17 +00:00

7 lines
1.4 KiB
Markdown

- [lucide-react icon name collisions](lucide-icon-name-collisions.md) — `Badge`/`Activity` from lucide collide with shadcn/ui Badge and React 19 Activity; import Badge from ui, Activity from lucide.
- [OpenAI gpt-5 temperature](openai-temperature-gpt5.md) — gpt-5* reject `temperature != 1`; omit temperature in OpenAI-compatible clients or AI analysis silently fails.
- [NDJSON streaming on Replit](ndjson-streaming-express-replit.md) — use `res.on("close")`+`writableFinished` (NOT `req.on("close")`); persist on disconnect; proxy doesn't buffer; gate fallback to avoid dup rows.
- [Skill fingerprint & relation matching](skill-fingerprint-matching.md) — don't put display name in fingerprint path; match modified by file-path Jaccard (hash-Jaccard misses single-file edits), report content-aware similarity.
- [Testing api-server from shell](api-server-local-curl.md) — external `$REPLIT_DEV_DOMAIN/api` curl returns HTTP 000; curl `http://localhost:<PORT>/api` instead (port from workflow log).
- [Stale codegen & unapplied migrations](skillguard-stale-codegen-and-migrations.md) — "field already in API" tasks: dev/test DB + lib `dist/*.d.ts` lag; run drizzle push + `tsc -b` the lib.
- [Mocking fetch in api-server route tests](api-server-fetch-mocking-in-tests.md) — route tests run app in-process; delegate localhost requests to real fetch, only synthesize upstream; filter spy calls by URL.