Files
gridpilot.gg/plans/systematic-plan.md
Marc Mintel 9894c4a841
Some checks failed
CI / lint-typecheck (pull_request) Failing after 13s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
code quality
2026-01-27 16:30:03 +01:00

11 KiB
Raw Blame History

Route Plan — small-to-big verification route (excluding apps/companion) Ground rules (why this route works) Never run broad npm test/all-suites early. We always scope by area and by config. Each phase has a single ownership boundary (core → adapters → api → website → tests → E2E). If something fails, stop and fix at the smallest scope, then re-run only that phase. Phase 0 — Baseline + failure artifacts Artifacts folder

mkdir -p artifacts/verify export VERIFY_RUN_ID=$(date -u +%Y%m%dT%H%M%SZ) export VERIFY_OUT=artifacts/verify/$VERIFY_RUN_ID mkdir -p $VERIFY_OUT

Standard failure capture format (use consistently)

ESLint: JSON report TypeScript: plain text log Vitest: JSON report (when supported) Playwright: HTML report + traces/videos on failure (config-dependent) Note: root scripts exist for typechecking targets in package.jsonpackage.json, but we will run per-area tsc directly to keep scope small.

Phase 1 — Verify core/ in isolation 1.1 Typecheck (core only) npx tsc --noEmit -p core/tsconfig.json 2>&1 | tee $VERIFY_OUT/core.tsc.log

Exit criteria: tsc exits 0; no TypeScript errors.

1.2 Lint (core only) npx eslint core --ext .ts,.tsx --max-warnings 0 -f json -o $VERIFY_OUT/core.eslint.json

Exit criteria: ESLint exits 0; report contains 0 errors.

1.3 Unit tests (core only; filtered) Vitest includes core by default via vitest.config.ts.

npx vitest run --config vitest.config.ts core --reporter=default

If you want machine-readable output:

npx vitest run --config vitest.config.ts core --reporter=json --outputFile=$VERIFY_OUT/core.vitest.json

Exit criteria: all tests under core/**/.{test,spec}. pass.

Minimal subset strategy: pass core as the filter argument so Vitest only runs tests whose paths match core.

Failure reporting for Code mode (copy/paste template)

Command: (paste exact command) Failing file(s): (from output) First error: (topmost stack) Suspected layer: (domain/service/adapter) Repro scope: re-run with npx vitest run --config vitest.config.ts path/to/file.test.ts Phase 2 — Verify adapters/ in isolation 2.1 Typecheck (adapters only) npx tsc --noEmit -p adapters/tsconfig.json 2>&1 | tee $VERIFY_OUT/adapters.tsc.log

Exit criteria: tsc exits 0.

2.2 Lint (adapters only) npx eslint adapters --ext .ts,.tsx --max-warnings 0 -f json -o $VERIFY_OUT/adapters.eslint.json

Exit criteria: ESLint exits 0.

2.3 Unit tests (adapters only; filtered) npx vitest run --config vitest.config.ts adapters --reporter=default

Optional JSON:

npx vitest run --config vitest.config.ts adapters --reporter=json --outputFile=$VERIFY_OUT/adapters.vitest.json

Exit criteria: all tests under adapters/**/.{test,spec}. pass.

Minimal subset strategy: pass adapters as Vitest filter.

Phase 3 — Verify apps/api/ in isolation 3.1 Typecheck (API only) npx tsc --noEmit -p apps/api/tsconfig.json 2>&1 | tee $VERIFY_OUT/api.tsc.log

Exit criteria: tsc exits 0.

3.2 Lint (API source only) Root lint script targets apps/api/src in package.json.

npm run lint --silent

optional: also capture JSON

npx eslint apps/api/src --ext .ts,.tsx --max-warnings 0 -f json -o $VERIFY_OUT/api.eslint.json

Exit criteria: ESLint exits 0.

3.3 API tests (Vitest, API config) Config: vitest.api.config.ts

npm run api:test --silent

equivalent:

npx vitest run --config vitest.api.config.ts

Optional JSON:

npx vitest run --config vitest.api.config.ts --reporter=json --outputFile=$VERIFY_OUT/api.vitest.json

Exit criteria: all tests matched by vitest.api.config.ts pass.

3.4 API contract validation (smallest meaningful contract test) Script points at a single file in package.json.

npm run test:api:contracts --silent

Exit criteria: contract validation test passes.

Minimal subset strategy

Use the API-specific config so we never accidentally pick up website/core/adapters suites. Prefer the single-file contract validation script first. Phase 4 — Verify apps/website/ in isolation 4.1 Website lint (workspace only) Workspace script in package.json.

npm run website:lint --silent

optional JSON capture

( cd apps/website && npx eslint . --ext .ts,.tsx --max-warnings 0 -f json -o ../../$VERIFY_OUT/website.eslint.json )

Exit criteria: ESLint exits 0.

4.2 Website type-check (workspace only) Workspace script in package.json.

npm run website:type-check --silent 2>&1 | tee $VERIFY_OUT/website.tsc.log

Exit criteria: TypeScript exits 0.

4.3 Website unit/integration tests (Vitest website config) Config: vitest.website.config.ts

npx vitest run --config vitest.website.config.ts --reporter=default

Optional JSON:

npx vitest run --config vitest.website.config.ts --reporter=json --outputFile=$VERIFY_OUT/website.vitest.json

Exit criteria: all tests included by vitest.website.config.ts pass.

Minimal subset strategy

Use the website-specific config so we dont drag in unrelated tests/integration/* suites. If only one failing file: re-run with npx vitest run --config vitest.website.config.ts path/to/failing.test.ts. Phase 5 — Verify tests/ (non-E2E suites) 5.1 Typecheck test harness (tests only) Script exists in package.json.

npm run test:types --silent 2>&1 | tee $VERIFY_OUT/tests.tsc.log

Exit criteria: tsc exits 0.

5.2 Unit tests (tests/unit only) Script exists in package.json.

npm run test:unit --silent

Optional scoped rerun:

npx vitest run tests/unit --reporter=json --outputFile=$VERIFY_OUT/tests.unit.vitest.json

Exit criteria: unit suite passes.

5.3 Integration tests (tests/integration only) Script exists in package.json.

npm run test:integration --silent

Optional JSON:

npx vitest run tests/integration --reporter=json --outputFile=$VERIFY_OUT/tests.integration.vitest.json

Exit criteria: integration suite passes.

5.4 Contract tests (targeted) Contract runner exists in package.jsonpackage.json.

npm run test:contracts --silent npm run test:contract:compatibility --silent

Exit criteria: contract suite + compatibility checks pass.

Phase 6 — Website integration via Playwright (auth/session/route guards) Config: playwright.website-integration.config.ts

6.1 Bring up docker E2E environment (website + api + db) Scripts exist in package.jsonpackage.json.

npm run docker:e2e:up

6.2 Run website integration tests npx playwright test -c playwright.website-integration.config.ts

Artifacts:

npx playwright show-report playwright-report || true

Exit criteria: all Playwright tests pass with 0 retries (configs set retries 0 in playwright.website-integration.config.ts).

6.3 Tear down npm run docker:e2e:down

Phase 7 — API smoke via Playwright Config: playwright.api.config.ts

7.1 Start docker E2E environment npm run docker:e2e:up

7.2 Run API smoke suite (config-targeted) npx playwright test -c playwright.api.config.ts

Exit criteria: all smoke tests pass; auth setup passes via playwright.api.config.ts.

7.3 Tear down npm run docker:e2e:down

Phase 8 — Full website page-render E2E (Docker) Config: playwright.website.config.ts

8.1 Bring up docker E2E environment npm run docker:e2e:up

8.2 Run containerized website E2E Root script exists in package.json.

npm run smoke:website:docker --silent

equivalent:

npx playwright test -c playwright.website.config.ts

Exit criteria

all tests pass no console/runtime errors (the suites stated purpose in playwright.website.config.tsplaywright.website.config.ts) 8.3 Tear down npm run docker:e2e:down

Phase 9 — Placeholder E2E inventory + implementation plan (must be completed at the end) 9.1 Identify placeholder tests (mechanical rule) Current placeholders are primarily *.spec.ts under tests/e2e/ containing TODO blocks (example: tests/e2e/media/avatar.spec.ts).

Inventory command (produces a reviewable list):

rg -n "TODO: Implement test|TODO: Implement authentication" tests/e2e > $VERIFY_OUT/e2e.placeholders.txt

Exit criteria: inventory file exists and is reviewed; every placeholder file is accounted for.

9.2 Decide runner + wiring (so these tests actually run) Observation: your active runners are:

Vitest E2E for *.e2e.test.ts via vitest.e2e.config.ts Playwright for website/api via playwright.website.config.ts and playwright.api.config.ts The placeholder files are *.spec.ts and appear to be Playwright-style UI specs. To make them “working,” they must:

have deterministic auth + data seeding, and be included by a Playwright configs testDir/testMatch. Plan (small-to-big, no scope explosion):

Create one shared Playwright fixture for auth + seed (driver/admin/sponsor), then reuse it. Enable one directory at a time (e.g., tests/e2e/onboarding/*), keeping the blast radius small. Promote stable subsets into CI only after theyre reliable locally. 9.3 Implement placeholders without expanding scope prematurely Rules of engagement:

First implement the lowest-dependency happy paths (navigation + render assertions), then add mutations (create/update/delete). Use stable selectors (data-testid) and avoid brittle text-only selectors. For each spec file: ensure every test(...) contains at least one real assertion and no TODO blocks. Per-directory implementation order (smallest external dependency first):

tests/e2e/dashboard/* (mostly navigation + visibility) tests/e2e/onboarding/* (auth + wizard flows) tests/e2e/profile/* tests/e2e/leagues/* tests/e2e/teams/* tests/e2e/media/* (uploads last; requires fixtures and storage) 9.4 Identify missing coverage/gaps against product expectations Alignment sources:

Product expectations in docs/concept/CONCEPT.md and role-specific behavior in docs/concept/ADMINS.md, docs/concept/DRIVERS.md, docs/concept/TEAMS.md, docs/concept/RACING.md. Gap-finding method:

Build a checklist of feature promises from those concept docs. Map each promise to at least one E2E spec file. If a promise has no spec file, add a single targeted E2E spec (do not add broad new suites). Exit criteria (hard):

rg -n "TODO: Implement" tests/e2e returns 0 results. All placeholder-derived specs are included in a Playwright config and pass in the docker E2E environment. Phase 10 — Optional final aggregate (only after everything above is green) Only now is it acceptable to run broader aggregations:

npm run verify in package.json (note: it currently runs lint + typecheck targets + unit + integration). Suggested tracking checklist (Orchestrator TODO) Use the checklist already captured in the orchestrator list, driven phase-by-phase:

Run Phase 1 commands; fix failures in core/ only. Run Phase 2; fix failures in adapters/ only. Run Phase 3; fix failures in apps/api/ only. Run Phase 4; fix failures in apps/website/ only. Run Phase 5; fix failures under tests/ only. Run Phase 68; fix failures by the nearest boundary (website vs api). Run Phase 9 last; implement every placeholder spec until rg TODO is empty and suites pass. This route plan is complete and ready for execution in Code mode.