diff --git a/docs/README.md b/docs/README.md index f2aba05..ac96a0a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,6 +11,10 @@ This is the entry point to all project documentation. It is maintained automatic ## Sections +### Daily development + +- [development.md](development.md) — repo layout, prerequisites, initial setup, daily commands, conventional commit cycle. Day-to-day reference for working on the project. + ### Onboarding & environment Setup guides for new contributors: diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000..eeac1da --- /dev/null +++ b/docs/development.md @@ -0,0 +1,275 @@ +# Development guide + +This document is the day-to-day reference for working on `apf_portal`. It covers the repo layout, the prerequisites, the initial setup from a fresh clone, and the commands you'll run during a typical development cycle. It is meant to grow — add sections as the team's workflow does. + +For decision rationale, see the [ADRs](decisions/). For onboarding the local environment (terminal, Node, pnpm), see [setup/](setup/). + +--- + +## 1. Repo layout + +``` +apf_portal/ +├── .gitea/workflows/ # CI pipelines (ADR-0015) +│ ├── ci.yml # per-PR + push to main: check / scan / commits / perf / a11y +│ └── security-scheduled.yml # weekly full-tree scan + prod Lighthouse +├── .github/ # Nx AI-tooling skills, prompts, agents (Nx-managed) +├── .husky/ # local git hooks (ADR-0007) +│ ├── pre-commit # → pnpm exec lint-staged +│ └── commit-msg # → pnpm exec commitlint +├── apps/ +│ ├── portal-shell/ # Angular 21 SPA (zoneless, standalone, Signals, Vitest, SCSS) +│ │ ├── public/ # static assets +│ │ ├── src/ # entry, app config, routes, styles +│ │ ├── postcss.config.js # Tailwind PostCSS plugin +│ │ └── project.json # Nx project config (build, serve, test, lint targets) +│ ├── portal-shell-e2e/ # Playwright e2e for portal-shell +│ ├── portal-bff/ # NestJS 11 BFF (Express adapter, ValidationPipe, Jest) +│ │ ├── src/ # main, app module, controllers, services +│ │ ├── prisma/schema.prisma # Prisma 7 schema (postgresql) +│ │ ├── prisma.config.ts # Prisma 7 TS config (loads DATABASE_URL from .env) +│ │ ├── .env.example # env-vars catalog (committed); .env stays gitignored +│ │ └── project.json +│ └── portal-bff-e2e/ # Jest e2e for portal-bff +├── libs/ +│ ├── feature// # vertical feature libs (e.g. feature-auth) +│ └── shared// # cross-cutting libs (tokens, ui, util) +├── docs/ +│ ├── README.md # doc index +│ ├── decisions/ # ADRs (MADR 4.0.0) +│ ├── setup/ # local-environment onboarding (Zsh, pnpm, Nx workspace) +│ └── development.md # this file +├── notes/ # personal scratchpad (gitignored) +├── CLAUDE.md # project rules + architecture summary +├── commitlint.config.cjs # Conventional Commits config +├── eslint.config.mjs # workspace ESLint with module boundaries +├── lighthouserc.js # Lighthouse CI thresholds (ADR-0017) +├── nx.json # Nx workspace config +├── package.json # workspace deps + scripts +├── pnpm-workspace.yaml # apps/* + libs/** +├── tsconfig.base.json # shared TS strict config +└── vitest.workspace.ts # Vitest workspace projects +``` + +The conventions that govern this layout are recorded in: + +- [ADR-0002](decisions/0002-adopt-nx-monorepo-apps-preset.md) — Nx workspace shape +- [ADR-0003](decisions/0003-workspace-and-app-naming-convention.md) — naming convention (`portal-shell`, `portal-bff`, `feature-`, `shared-`) +- [ADR-0007](decisions/0007-pre-commit-hooks-and-conventional-commits.md) — local hooks +- [ADR-0015](decisions/0015-cicd-gitea-actions.md) — CI/CD shape + +--- + +## 2. Prerequisites + +A working dev machine for `apf_portal` needs: + +| Tool | Why | How | +| -------------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **WSL 2 + Debian** (Windows) or Linux/macOS native | All commands assume a POSIX shell | see [setup/01](setup/01-wsl-terminal-setup.md) | +| **Node.js 24** (latest LTS) | Runtime, pinned in `.nvmrc` | `nvm install 24 && nvm use` (see [setup/02](setup/02-dev-web-stack.md)) | +| **pnpm 10+** | Mandatory package manager (no npm/yarn lockfile) | `corepack enable && corepack prepare pnpm@latest --activate` | +| **Git ≥ 2.40** | Husky 9 + signed commits eventually | usually default | +| **mkcert** | Local HTTPS for cookie-prefix `__Host-` (ADR-0009) | `apt install mkcert` then `mkcert -install` | +| **Trivy** _(optional, locally)_ | Dep vuln scan when running `ci:scan` locally; CI uses an action | `apt install trivy` or [trivy install docs](https://trivy.dev/) | +| **gitleaks** _(optional, locally)_ | Same pattern; CI uses an action | `apt install gitleaks` or [gitleaks install docs](https://github.com/gitleaks/gitleaks#installing) | +| **Docker** | For Postgres + Redis containers in dev (until on-prem infra ADR lands) | Docker Desktop on Windows, Docker Engine on Linux | + +Work inside the WSL filesystem (`~/Works/...`), never `/mnt/c/...` — the latter has severe I/O penalties that break Nx caching. + +--- + +## 3. Initial setup from a fresh clone + +```bash +git clone gitea@git.unespace.com:julien/apf_portal.git +cd apf_portal + +# Install deps (also runs `husky` to wire git hooks) +pnpm install + +# Generate the Prisma client (until you set up the DB it errors on +# missing DATABASE_URL — that's expected; the generation only reads +# the schema, not the DB). +cd apps/portal-bff && pnpm exec prisma generate && cd ../.. + +# Sanity check +pnpm nx run-many -t lint test build +``` + +For the BFF to actually run end-to-end, you'll also need: + +```bash +# .env from .env.example, then fill in DATABASE_URL with your local Postgres +cp apps/portal-bff/.env.example apps/portal-bff/.env + +# Local Postgres via Docker (one-liner; will be replaced by a Docker Compose file in a later doc) +docker run -d --name apf-postgres -p 5432:5432 \ + -e POSTGRES_USER=portal -e POSTGRES_PASSWORD=portal -e POSTGRES_DB=portal_dev \ + postgres:17-alpine +``` + +A proper local-dev infra spec (Postgres HA-like, Redis, OTel collector) will land with the on-prem infrastructure ADR; in the meantime the one-liner above is sufficient to run the BFF. + +--- + +## 4. Daily commands + +### Run the apps + +```bash +pnpm nx serve portal-shell # http://localhost:4200 (Angular dev server) +pnpm nx serve portal-bff # http://localhost:3000/api (NestJS) +``` + +Both can run in parallel in two terminals; the SPA proxies API calls to the BFF in dev. + +### Test + +```bash +pnpm nx test portal-shell # Vitest (single run; --configuration=watch for watch mode) +pnpm nx test portal-bff # Jest + +pnpm nx run-many -t test # all projects +pnpm nx affected -t test # only projects affected since main +``` + +Run a single Vitest file: + +```bash +pnpm nx test portal-shell --testFile=src/app/app.spec.ts +``` + +### Lint, type-check, format + +```bash +pnpm nx lint portal-shell # one project +pnpm nx run-many -t lint # all projects +pnpm nx affected -t lint # affected only +pnpm nx affected -t lint --fix # auto-fix where possible + +pnpm nx affected -t type-check # explicit type-check (independent of test/build) + +pnpm nx format:write # apply Prettier +pnpm nx format:check # CI-style verification +``` + +### Build + +```bash +pnpm nx build portal-shell # development build +pnpm nx build portal-shell --configuration=production # production build +pnpm nx run-many -t build +pnpm nx affected -t build +``` + +### Generate + +```bash +# Component in portal-shell +pnpm nx g @nx/angular:component --project=portal-shell --standalone + +# Service / controller / module in portal-bff +pnpm nx g @nx/nest:service --project=portal-bff +pnpm nx g @nx/nest:controller --project=portal-bff + +# New shared lib (TS-only, consumable by both apps) +pnpm nx g @nx/js:library --name=shared- --directory=libs/shared/ \ + --bundler=tsc --unitTestRunner=vitest \ + --tags="scope:shared,type:shared" --no-interactive + +# New Angular feature lib (front-only) +pnpm nx g @nx/angular:library --name=feature- --directory=libs/feature/ \ + --standalone=true --unitTestRunner=vitest-analog \ + --tags="scope:portal-shell,type:feature" --no-interactive +``` + +> Sweep generated files for `process.env.X` (dot notation) → `process.env['X']` (bracket notation), required by the strict-TS option `noPropertyAccessFromIndexSignature: true`. The Nx generators don't emit bracket form. + +### Prisma + +```bash +# Regenerate the typed client after schema changes +cd apps/portal-bff && pnpm exec prisma generate && cd ../.. + +# Create and apply a migration in dev +cd apps/portal-bff && pnpm exec prisma migrate dev --name && cd ../.. + +# Deploy migrations in prod (run by deploy pipeline, not locally) +cd apps/portal-bff && pnpm exec prisma migrate deploy && cd ../.. + +# Inspect the dev DB +cd apps/portal-bff && pnpm exec prisma studio && cd ../.. +``` + +### CI scripts (runnable locally) + +Mirror what the CI does on every PR: + +```bash +pnpm ci:check # nx affected -t format:check lint test build +pnpm ci:audit # pnpm audit --audit-level=moderate +pnpm ci:commits # commitlint on the PR commit range (uses $COMMIT_LINT_FROM, defaults to origin/main) +pnpm ci:perf # production build + Lighthouse CI against the static-served bundle +``` + +`ci:scan` (Trivy + gitleaks) is currently invoked from CI YAML rather than as a `pnpm` script — those tools are Go binaries without clean npm wrappers. Run them locally if you've installed the binaries. + +--- + +## 5. Conventional commit cycle + +1. Branch from `main` with a short slug: + + ```bash + git switch -c feat/portal-shell/auth-login # or fix/..., chore/..., docs/... + ``` + +2. Commit using **Conventional Commits**. The local `commit-msg` hook (commitlint) rejects anything else. + + ``` + feat(portal-shell): add login flow stub + fix(portal-bff): correct env var bracket access + chore: bump @nx/* to 22.7.2 + docs(decisions): add ADR-0018 for security baseline + ``` + + `pre-commit` runs `lint-staged` → Prettier on staged files. Lint and tests stay in CI. + +3. Push and open a PR against `main`. The CI runs: + - `check` (lint, type-check, test, build on affected) + - `scan` (audit, Trivy, gitleaks) + - `commits` (commitlint on the PR commit range) + - `perf` (Lighthouse on the production bundle) + - `a11y` (axe-core; placeholder until first real screens) + + All five must be green to merge. PR title must itself be a Conventional Commits message — it becomes the squash-merge subject ([ADR-0015](decisions/0015-cicd-gitea-actions.md)). + +4. Squash-merge into `main`. Branch is auto-deleted. Linear history maintained. + +5. To cut a release: tag `vX.Y.Z` on `main`. The `release.yml` workflow will pick it up (currently a stub; populated alongside the on-prem deploy ADR). + +--- + +## 6. Where to look + +| Question | Doc | +| ------------------------------------------- | ---------------------------------------------------------------------------- | +| Project rules and the why behind them | [CLAUDE.md](../CLAUDE.md) | +| All ADRs (decisions index) | [docs/decisions/README.md](decisions/README.md) | +| Initial environment setup (Zsh, Node, pnpm) | [docs/setup/](setup/) | +| RSSI briefing for ASVS / HDS / etc. | `notes/asvs-level-decision-briefing-rssi.md` (gitignored, personal) | +| The dev-team rationale for the UI stack | `notes/argumentaire-stack-ui-spartan-cdk-tailwind.md` (gitignored, personal) | + +--- + +## 7. To be added + +This doc is intentionally not exhaustive on day one. Sections that will land as the project grows: + +- **Local infra recipe** — Docker Compose for Postgres + Redis + (later) OTel Collector. +- **Auth dev-loop** — once the Microsoft 365 Developer tenant is provisioned, the workflow for testing OIDC locally. +- **Component patterns** — the in-house spartan-style components (CDK + Tailwind) as they ship, with a11y notes per component. +- **Debugging tips** — Angular DevTools, NestJS inspector, Prisma query log, OTel trace inspection. +- **Release workflow** — once the on-prem deploy ADR lands. +- **Renovate / dep update policy** — when Renovate is configured.