--- kind: epic slug: test-foundation title: Test foundation — Vitest bootstrap and CI gate plan_slug: multitenant-saas-hardening status: ready priority: P1 tenant_id: global cursor_epic_id: null updated_at: "2026-06-01" --- # Epic objective Get the repo to a place where `pnpm test` is a real command and a PR can't merge with broken lint/types/tests. Today there is no test runner (`AGENTS.md` is explicit about this) and no CI workflow. ## In scope / out of scope **In scope** - Add Vitest to the workspaces that need it most: `packages/database`, `packages/shared`, `packages/ai`. - Add a `pnpm test` script wired through Turborepo so cached test runs work. - Add `.github/workflows/ci.yml` running `pnpm lint && pnpm type-check && pnpm test` on PRs. **Out of scope** - Testing React components. Component testing in Next.js + React 19 + RSC is its own rabbit hole; defer until there's a real motivating bug. - End-to-end (Playwright) tests. Same reason. ## Related tasks | Task | Link | |------|------| | Bootstrap Vitest and GitHub Actions CI | `./Task-bootstrap-vitest-and-ci.md` | ## Dependencies - Depends on: `Task-fix-lint-and-shared-types` from `Plan-daily-driver-finish` (CI needs lint + type-check to be green). ## Acceptance criteria - [ ] `pnpm test` runs Vitest across at least 3 packages. - [ ] CI workflow gates PRs on lint + type-check + test. - [ ] At least 3 real tests exist (one in each chosen package) that catch a real regression if their target code is broken. ## Proposed timeline | Phase | Window | Notes | |-------|--------|-------| | Vitest + first tests | Day 1 | Set up runner, write seed tests. | | CI workflow | Day 2 | Pin Node 20, run lint/type/test on PR. |