# Scripts ## sync-model-prices.ts Wekelijks handmatig draaibaar script dat de tabel `model_prices` synchroniseert. Haalt de actuele Claude 4.x modellijst op via `GET /v1/models` (Anthropic API) en upsert de prijzen vanuit een hardcoded `PRICE_TABLE` in het script. Anthropic biedt geen prijs-API; bij elke prijswijziging update je de tabel in [`scripts/sync-model-prices.ts`](./sync-model-prices.ts). ### Prerequisites | What | How | |---|---| | `ANTHROPIC_API_KEY` in `.env.local` | Genereer op [console.anthropic.com](https://console.anthropic.com/) → API Keys. Free Evaluation tier is voldoende — `/v1/models` is een gratis metadata-call. | | `DATABASE_URL` in `.env.local` | Standaard Scrum4Me-setup. | ### Gebruik ```bash # Eerst droog draaien — toont wat er zou gebeuren, schrijft niets npm run db:sync-model-prices -- --dry-run # Echt synchroniseren npm run db:sync-model-prices ``` ### Output ``` Fetching /v1/models from Anthropic API... → 12 models received, 4 match Claude 4.x filter Syncing prices: ✓ claude-opus-4-7 (unchanged) ✓ claude-sonnet-4-6 (unchanged) ✓ claude-haiku-4-5-20251001 (unchanged) ⚠ claude-sonnet-4-9 (geen prijs in PRICE_TABLE — ...) Result: 0 created, 0 updated, 3 unchanged, 1 skipped ``` ### Bij een nieuw model (`⚠ skipped`) 1. Open de Anthropic [pricing-pagina](https://platform.claude.com/docs/en/about-claude/pricing). 2. Voeg het model toe aan `PRICE_TABLE` in [`scripts/sync-model-prices.ts`](./sync-model-prices.ts): ```ts 'claude-sonnet-4-9': { input: 3.0, output: 15.0 }, ``` 3. Draai het script opnieuw. ### Edge cases - **API geeft 401**: controleer `ANTHROPIC_API_KEY`. - **API geeft 5xx**: script doet 1× retry met 2s delay, daarna falen. - **Model in DB maar niet meer in API**: wordt niet verwijderd — alleen gelogd, zodat oude `claude_jobs` rijen kostberekening blijven hebben. --- ## test-api.sh Runs curl-based tests against all 7 Scrum4Me API endpoints. Covers happy paths, auth (401), demo-block (403), and input validation (400). ### Prerequisites | What | How | |---|---| | Database seeded | `npx prisma db seed` | | Dev server running | `npm run dev` | | `curl` installed | `curl --version` | ### Step 1 — Get a token for lars 1. Open `http://localhost:3000` in your browser 2. Log in as `lars` / `scrum4me123` 3. Go to **Settings → API Tokens** 4. Click **New token**, give it any label 5. Copy the token — it is shown only once Open `scripts/test-api.sh` and paste it into `TOKEN=""`. ### Step 2 — Find your IDs You need four IDs. The easiest way is to use the API itself: ```bash # 1. Get PRODUCT_ID — run this after setting TOKEN curl -s -H "Authorization: Bearer " http://localhost:3000/api/products | grep -o '"id":"[^"]*"' | head -1 # 2. SPRINT_ID — look in the database or the UI (Sprint → copy ID from the URL) # 3. STORY_ID — open a story in the Sprint Board, copy the ID from the URL or the activity log # 4. TASK_ID — open a task, copy its ID ``` Or query the database directly: ```bash # With psql / Neon CLI: SELECT id FROM "Sprint" WHERE status = 'ACTIVE' LIMIT 1; SELECT id FROM "Story" WHERE status = 'IN_SPRINT' LIMIT 1; SELECT id FROM "Task" WHERE story_id = '' LIMIT 1; ``` Paste the four values into the variables at the top of `test-api.sh`. ### Step 3 — (Optional) Get a demo token for 403 tests The 403 demo-block tests are skipped unless you set `DEMO_TOKEN`. 1. Log out, log in as `demo` / `demo1234` 2. Go to **Settings → API Tokens**, create a token 3. Paste it into `DEMO_TOKEN=""` in `test-api.sh` ### Step 4 — Run ```bash bash scripts/test-api.sh ``` Expected output when all IDs are set and a demo token is provided: ``` ============================================================ Scrum4Me API Test Suite Base URL : http://localhost:3000 Token : scrum4me... (lars) Demo : demo1234... (403 tests active) ============================================================ ── GET /api/products ────────────────────────────────────────────── PASS TC-P-09 happy path (lars) PASS TC-P-01 no token → 401 PASS TC-P-02 invalid token → 401 ── GET /api/products/:id/next-story ─────────────────────────────── PASS TC-NS-08 happy path (lars, 200 or 404 both valid) PASS TC-NS-01 no token → 401 ... ============================================================ Results: 30 passed, 0 failed ============================================================ ``` ### Notes - **product_id is required** for `POST /api/todos`. The Zod schema enforces `z.string().min(1)`. Sending a todo without a product_id returns 400. - **TC-NS-08** accepts both 200 and 404. After a fresh seed lars has no active sprint, so 404 is the expected response unless you create a sprint and add stories to it. - **Reorder test (TC-RO-10)** uses a single task ID. A reorder with one element is valid (sort_order is updated to 1). - The todos happy-path test appends `$(date +%s)` to the title to avoid duplicate-title issues on repeated runs.