mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 05:43:12 +00:00
55 lines
4.3 KiB
Markdown
55 lines
4.3 KiB
Markdown
|
|
# QUALITY_GATES.md — executable frontend gates
|
|||
|
|
|
|||
|
|
The single command that runs **every** gate, locally and in CI:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
npm run verify
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`verify` chains: `format:check` → `lint` → `build` (`tsc -b && vite build`) →
|
|||
|
|
`test` (`vitest run`) → `governance`. A task is not done until this is green.
|
|||
|
|
|
|||
|
|
## Gate matrix
|
|||
|
|
|
|||
|
|
| Gate | Command / rule source | Enforced by | Scope |
|
|||
|
|
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------ |
|
|||
|
|
| Formatting | `npm run format:check` (Prettier) | `verify` + lint-staged | Whole repo |
|
|||
|
|
| Lint, zero warnings | `npm run lint` → `eslint . --max-warnings=0` | `verify` + CI | Governed TS/TSX (`eslint.config.js`) |
|
|||
|
|
| Type-check + production build | `npm run build` → `tsc -b && vite build` | `verify` + CI | Whole app |
|
|||
|
|
| Unit tests | `npm test` → `vitest run` | `verify` + CI | `src/test/**`, `config/**/*.test.ts` |
|
|||
|
|
| Conditional rendering (no `: null`) | `no-restricted-syntax` in `eslint.config.js` | lint | Governed TSX |
|
|||
|
|
| Boolean-only JSX `&&` | `seahaven/no-non-boolean-jsx-and` (type-aware) in `eslint-rules/` | lint | Governed TSX |
|
|||
|
|
| Shared `Text` typography | `no-restricted-syntax` (raw `p`/`h1`–`h6`) + `seahaven/no-vp-error-outside-text` | lint | Governed TSX |
|
|||
|
|
| Hooks correctness | `eslint-plugin-react-hooks` recommended (incl. `exhaustive-deps`) under zero-warnings | lint | Governed TS/TSX |
|
|||
|
|
| Godfile ratchet (file length) | `scripts/governance-check.mjs` + `scripts/governance-baseline.json` | `governance` | `src/**`, `config/**` (non-test) |
|
|||
|
|
| Changed-file maintainability | `scripts/governance-check.mjs` → ESLint (`complexity`, `max-lines-per-function`, `max-params`, `max-depth`) | `governance` | Changed TS/TSX vs base ref |
|
|||
|
|
|
|||
|
|
## No-false-pass guarantees
|
|||
|
|
|
|||
|
|
- **`--max-warnings=0`** — a warning is a failure. There is no "warning-only"
|
|||
|
|
backlog; rules ship green (see AGENTS.md → How to add a convention).
|
|||
|
|
- **Type-aware rules fail closed** — `seahaven/no-non-boolean-jsx-and` reports
|
|||
|
|
when type services are unavailable rather than silently claiming safety.
|
|||
|
|
- **Godfile ratchet is monotonic** — any new file over the cap, new baseline
|
|||
|
|
entry, global cap increase, per-file cap increase, or growth beyond a frozen
|
|||
|
|
legacy cap fails. Only cap reductions and entry removals are allowed.
|
|||
|
|
- **Changed-file maintainability fails closed without a valid base** — in CI the
|
|||
|
|
base ref is derived from `GITHUB_BASE_REF` (PR) or `github.event.before`
|
|||
|
|
(push). An absent or unresolvable base is a failure, not a pass.
|
|||
|
|
|
|||
|
|
## Where the gates run
|
|||
|
|
|
|||
|
|
- **Locally:** `npm run verify`. `lint-staged` (via Husky) re-runs ESLint +
|
|||
|
|
Prettier on staged files at commit; commitlint enforces Conventional Commits.
|
|||
|
|
- **CI ([`.github/workflows/ci.yaml`](.github/workflows/ci.yaml)):** the org
|
|||
|
|
reusable workflow (`ci-typescript-frontend.yaml`, Node 24) runs
|
|||
|
|
format/lint/build/tests, **and** a repo-owned `governance` job runs
|
|||
|
|
`npm run verify` so the maintainability ratchets are guaranteed from this
|
|||
|
|
repository regardless of the reusable workflow.
|
|||
|
|
|
|||
|
|
## Toolchain pin
|
|||
|
|
|
|||
|
|
Node ≥ 22.22.1 (CI uses Node 24); npm 11.16.0 via `packageManager` (use
|
|||
|
|
`corepack npm …` if your default `npm` is older). The lockfile is
|
|||
|
|
`package-lock.json` v3; install with `npm ci`.
|