- Replace bun:test with Vitest across all 22 test files
- Create @sofa/test package with shared setup and DB test helpers
- setup.ts: vi.mock for @sofa/db/client, Bun.randomUUIDv7 polyfill
- db.ts: in-memory SQLite via better-sqlite3, seed helpers
- Add per-project vitest configs (packages/core, apps/web)
- Add root vitest.config.ts with projects and v8 coverage
- Set up @vitest/browser + Playwright for web component tests
- Move validateBackupDatabase from core/backup.ts to @sofa/db/client
- Derive required backup tables from schema instead of hard-coded list
- Update CI workflow with Playwright install and Codecov upload
- Update CLAUDE.md documentation for Vitest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the static `https://sofa.example.com/api/v1` server entry with a variable-based URL (`{protocol}://{host}:{port}/api/v1`) so the spec works against any instance out of the box. Also move the output path from `docs/openapi.json` to `docs/public/openapi.json` so the file is served as a static asset by the docs site.
Extract spec generation into `openapi-spec.ts` with a `generateOpenApiSpec` function that registers common `$ref` schemas (Title, Person, Episode, Season, etc.) to deduplicate inline definitions across the spec. Add a `/api/v1/spec.json` interceptor that returns the fully normalized document, and point the Scalar docs UI at it instead of the plugin's raw generator output.
Also strip oRPC's impossible `{ not: {} }` void placeholders from request/response bodies via `normalizeOpenApiSpec`, and fix the handler registration so both `/api/v1` and `/api/v1/*` routes are matched.
Generate an OpenAPI 3.1 spec from the oRPC contract at build time
using @orpc/openapi, then use fumadocs-openapi to render interactive
API reference pages grouped by tag (Titles, Episodes, Seasons, etc.).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>