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

303 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.