docs: refresh CI + lint/format docs (Phase 8 + Phase 13)
CI / fast-checks (pull_request) Successful in 1m23s
CI / api (pull_request) Successful in 1m0s
CI / harness (pull_request) Successful in 3m27s

This commit is contained in:
Lucas Berger
2026-06-11 22:21:23 -04:00
parent 63ae0c69d4
commit 213aeba347
5 changed files with 378 additions and 60 deletions
+95 -44
View File
@@ -100,37 +100,104 @@ Vite serves the PWA with HMR on the configured dev port. The PWA's API calls tar
### Root workspace scripts
| Command | Description |
| ---------------- | ------------------------------------------------------------- |
| `pnpm dev:api` | Start API dev watcher (`node --watch dist/index.js`) |
| `pnpm dev:pwa` | Start Vite dev server for the PWA |
| `pnpm build` | Build both `apps/api` (tsc) and `apps/pwa` (tsc + vite build) |
| `pnpm test` | Run API test suite (`vitest run` in `apps/api`) |
| `pnpm lint` | Run lint in all workspaces (`pnpm -r lint`) |
| `pnpm typecheck` | Run `tsc --noEmit` in all workspaces |
| Command | Description |
| ------------------- | ------------------------------------------------------------- |
| `pnpm dev:api` | Start API dev watcher (`node --watch dist/index.js`) |
| `pnpm dev:pwa` | Start Vite dev server for the PWA |
| `pnpm build` | Build both `apps/api` (tsc) and `apps/pwa` (tsc + vite build) |
| `pnpm test` | Run API test suite (`vitest run` in `apps/api`) |
| `pnpm test:e2e` | Run Playwright e2e harness (`apps/pwa`) |
| `pnpm lint` | ESLint across all workspaces (`pnpm -r --if-present lint`) |
| `pnpm format` | Reformat all files with Prettier (`prettier --write .`) |
| `pnpm format:check` | Check formatting without writing (`prettier --check .`) |
| `pnpm typecheck` | `tsc --noEmit` in all workspaces |
### `apps/api` scripts
| Command | Description |
| ------------------------------------------- | ------------------------------------------- |
| `pnpm --filter @familysync/api build` | Compile TypeScript (`tsc`) → `dist/` |
| `pnpm --filter @familysync/api dev` | Start `node --watch dist/index.js` |
| `pnpm --filter @familysync/api start` | Start `node dist/index.js` (no watch) |
| `pnpm --filter @familysync/api test` | Run vitest once (`vitest run`) |
| `pnpm --filter @familysync/api test:watch` | Run vitest in watch mode |
| `pnpm --filter @familysync/api typecheck` | `tsc --noEmit` |
| `pnpm --filter @familysync/api db:generate` | Generate SQL migrations from schema changes |
| `pnpm --filter @familysync/api db:migrate` | Apply pending migrations to the database |
| Command | Description |
| ------------------------------------------- | ----------------------------------------------- |
| `pnpm --filter @familysync/api build` | Compile TypeScript (`tsc`) → `dist/` |
| `pnpm --filter @familysync/api dev` | Start `node --watch dist/index.js` |
| `pnpm --filter @familysync/api start` | Start `node dist/index.js` (no watch) |
| `pnpm --filter @familysync/api test` | Run vitest once (`vitest run`) |
| `pnpm --filter @familysync/api test:watch` | Run vitest in watch mode |
| `pnpm --filter @familysync/api lint` | ESLint `src/` and `tests/` (`--max-warnings 0`) |
| `pnpm --filter @familysync/api typecheck` | `tsc --noEmit` |
| `pnpm --filter @familysync/api db:generate` | Generate SQL migrations from schema changes |
| `pnpm --filter @familysync/api db:migrate` | Apply pending migrations to the database |
### `apps/pwa` scripts
| Command | Description |
| ----------------------------------------- | ---------------------------------- |
| `pnpm --filter @familysync/pwa dev` | Start Vite dev server with HMR |
| `pnpm --filter @familysync/pwa build` | `tsc && vite build``dist/` |
| `pnpm --filter @familysync/pwa preview` | Serve the production build locally |
| `pnpm --filter @familysync/pwa typecheck` | `tsc --noEmit` |
| `pnpm --filter @familysync/pwa test` | Run vitest once |
| Command | Description |
| ----------------------------------------------- | ----------------------------------------------------------- |
| `pnpm --filter @familysync/pwa dev` | Start Vite dev server with HMR |
| `pnpm --filter @familysync/pwa build` | `tsc && vite build``dist/` |
| `pnpm --filter @familysync/pwa preview` | Serve the production build locally |
| `pnpm --filter @familysync/pwa lint` | ESLint `src/` and `e2e/` (`--max-warnings 0`) |
| `pnpm --filter @familysync/pwa typecheck` | `tsc --noEmit` + `tsc --project tsconfig.e2e.json --noEmit` |
| `pnpm --filter @familysync/pwa test` | Run vitest once |
| `pnpm --filter @familysync/pwa test:e2e` | Run Playwright e2e tests |
| `pnpm --filter @familysync/pwa test:e2e:headed` | Playwright in headed mode (visible browser) |
| `pnpm --filter @familysync/pwa test:e2e:ui` | Playwright UI mode |
## Code Quality — Run Before Every Push
CI gates every PR to `main` on these checks. Run them locally before pushing to avoid a CI round-trip.
```bash
pnpm lint # ESLint --max-warnings 0 across apps/api (src/ + tests/) and apps/pwa (src/ + e2e/)
pnpm format:check # Prettier formatting check (use `pnpm format` to auto-fix)
pnpm typecheck # tsc --noEmit in both apps (includes apps/pwa tsconfig.e2e.json)
```
### ESLint
Config: `eslint.config.js` (root, flat ESLint 9 format). The config covers:
- **All `apps/**/\*.{ts,tsx}`** — `js.configs.recommended`+`tseslint.configs.recommendedTypeChecked`with`projectService: true`(type-aware rules, auto-discovers all`tsconfig.json` files)
- **`apps/pwa/**/\*.{ts,tsx}`additionally** —`eslint-plugin-react`+`eslint-plugin-react-hooks` (React 19 flat config; React Compiler rules disabled — this codebase does not use the Compiler)
- **Tool configs + test dirs** (`drizzle.config.ts`, `vitest.config.ts`, `apps/api/tests/**`, `apps/pwa/e2e/**`) — type-aware rules disabled via `disableTypeChecked` (these files are outside the main tsconfig projects)
- **Prettier integration** — `eslint-config-prettier` last in the config disables all formatting rules that conflict with Prettier
`--max-warnings 0` is enforced: warnings count as failures. **Blanket `eslint-disable` comments are not permitted** — every suppression requires a justification comment.
### Prettier
Config: `.prettierrc` (root). Settings: `singleQuote: true`, `semi: true`, `tabWidth: 2`, `trailingComma: "all"`, `printWidth: 100`.
```bash
pnpm format # write fixes in place
pnpm format:check # check only (used in CI)
```
The `.prettierignore` file at the repo root excludes build output and generated files.
## TypeScript Strict Checks
Both workspaces use `"strict": true` in their `tsconfig.json`. The build step (`tsc`) catches type errors in `apps/api` (since it emits output). For `apps/pwa`, Vite uses esbuild to transpile and does not perform type checking — **vitest will pass even when there are type errors in the PWA**. Always run the typecheck script explicitly:
```bash
# Check both workspaces
pnpm typecheck
# Or individually
pnpm --filter @familysync/api typecheck
pnpm --filter @familysync/pwa typecheck # also checks tsconfig.e2e.json
```
Run `pnpm typecheck` before opening a PR to catch errors that vitest and Vite builds will silently miss.
## CI Pipeline Overview
Every PR to `main` runs three parallel jobs (`.gitea/workflows/ci.yml`):
| Job | Checks |
| ------------- | ---------------------------------------------------------------------------------------------------- |
| `fast-checks` | `pnpm lint``pnpm format:check``pnpm typecheck``pnpm --filter @familysync/pwa test` |
| `api` | DB migrations + `pnpm --filter @familysync/api test` (vitest against a MariaDB 11 service container) |
| `harness` | DB migrations + API build + Playwright e2e (WebKit + Chromium) with `DEV_AUTH_BYPASS=true` |
All three jobs must pass before a PR can merge. See [docs/TESTING.md](TESTING.md) for test suite details.
## Drizzle Migration Workflow
@@ -162,25 +229,6 @@ DB_HOST=127.0.0.1 pnpm --filter @familysync/api db:migrate
Migration files live in `apps/api/src/db/migrations/` and are committed to version control.
## TypeScript Strict Checks
Both workspaces use `"strict": true` in their `tsconfig.json`. The build step (`tsc`) catches type errors in `apps/api` (since it emits output). For `apps/pwa`, Vite uses esbuild to transpile and does not perform type checking — **vitest will pass even when there are type errors in the PWA**. Always run the typecheck script explicitly:
```bash
# Check both workspaces
pnpm typecheck
# Or individually
pnpm --filter @familysync/api typecheck
pnpm --filter @familysync/pwa typecheck
```
Run `pnpm typecheck` before opening a PR to catch errors that vitest and Vite builds will silently miss.
## Code Style
ESLint and Prettier are listed as the intended linting and formatting tools. Check for config files in each workspace and confirm the `lint` script is wired before running `pnpm lint`. <!-- VERIFY: ESLint and Prettier configs are present in apps/api and apps/pwa -->
## Docker Compose Dev Stack
```bash
@@ -216,3 +264,6 @@ The vitest config sets `fileParallelism: false` to prevent concurrent test files
**TypeScript errors missed during development**
Vite/esbuild strips types; type errors will not surface in `vitest run` or `vite build` output. Run `pnpm typecheck` explicitly to catch them.
**`pnpm lint` warns about ESLint version**
ESLint is pinned to 9.39.4. Do not upgrade to ESLint 10 until `eslint-plugin-react` resolves the `getFilename is not a function` incompatibility (`jsx-eslint#3977`).