import { defineConfig } from "vitest/config";

// Pin test discovery to the repo's own tests/ tree. Without this, vitest's
// default globs also pick up copies of the repo inside .claude/worktrees/
// (created by background agent sessions), silently doubling the suite.
export default defineConfig({
  test: {
    include: ["tests/**/*.test.ts"],
    // Builds one migrated+seeded template database per run (and sweeps stale
    // ones left by crashed runs); createTestDb() copies it per test file
    // instead of replaying every migration. See tests/helpers/global-setup.ts.
    globalSetup: ["tests/helpers/global-setup.ts"],
    // "default" is the human-readable run output; keeping it in the list is
    // mandatory, because naming any reporter replaces the default list rather
    // than adding to it.
    //
    // The second one is a gate, not a report. It compares the files this run
    // SCHEDULED against the files that came back with a result and fails the
    // run if any went missing — the case where a worker process dies and
    // vitest prints "61 passed (62)" with thirty tests quietly absent from the
    // totals. See tests/helpers/completeness-reporter.ts; the reasoning for why
    // vitest's own exit code is not enough on its own is written out there.
    reporters: ["default", "./tests/helpers/completeness-reporter.ts"],
    // beforeAll/afterAll hooks copy and drop a database apiece. Under parallel
    // workers that legitimately exceeds vitest's 10s hook default, which shows
    // up as "Hook timed out" on a suite whose tests all passed. The work is
    // I/O, not a hang — give it the same budget the per-file beforeAll calls
    // already ask for rather than letting load masquerade as failure.
    hookTimeout: 60_000,
    // The same argument, for tests rather than hooks, and it became true the
    // day Docker was removed.
    //
    // vitest's default testTimeout is 5 SECONDS. That was survivable against
    // the container, where opening a PostgreSQL connection on Linux costs
    // single-digit milliseconds. The bundled cluster this product now ships is
    // an order of magnitude dearer — measured on Windows 11 on 2026-08-08:
    //
    //     5 connections opened serially   2042 ms   (~408 ms each)
    //     20 connections opened at once   5732 ms
    //
    // (~400ms is a Windows fact: the postmaster forks a real postgres.exe per
    // backend, antivirus inspects each one, and scram-sha-256 then does its key
    // derivation. See the note on CONNECTION_TIMEOUT_MILLIS in server/src/db.ts,
    // which was the same discovery from the application's side.)
    //
    // A test that opens a handful of connections and does real posting work
    // therefore spends seconds on connection setup alone, and the whole suite
    // runs 2-4x slower than it did against Docker. Left at 5s, ordinary tests
    // fail with "Test timed out in 5000ms" — observed on
    // tests/invariants/inventory.test.ts and tests/server/setup.test.ts in a
    // full run against the bundled cluster, on a machine where each of them
    // passes comfortably when run alone.
    //
    // This does not weaken a single assertion; a timeout is a budget for I/O,
    // not a claim about the books. Thirty seconds is generous enough that load
    // cannot masquerade as failure and short enough that a genuine hang still
    // gets caught. Tests that need longer already ask for it explicitly (the
    // 60s/90s provisioning budgets), and those are unaffected.
    testTimeout: 30_000,
  },
});
