diff --git a/CLAUDE.md b/CLAUDE.md index f016070..02b059b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ These constraints were set by the project lead at kickoff. They apply to every c - **Scale & quality bar.** Treat this as a large-scale portal for a sizable organization, not a prototype. No bricolage, no exotic stacks. **Default to stable, recognized, battle-tested choices.** Cutting-edge / "à la pointe" alternatives must always be evaluated alongside the stable option, but are only adopted when the trade-off is captured in an ADR (drivers, risk, exit strategy). Pre-1.0 dependencies and one-maintainer projects are rejected unless an ADR justifies the exception. - **Security, performance, accessibility.** All three are first-class concerns from day one — never bolted on. Architecture, dependency, and feature decisions must explicitly consider their impact on these axes and document the trade-offs. -- **Project name.** Currently `adastra_portal`, provisional. Do not hardcode it outside repo/workspace-level metadata so a rename stays a one-line change. +- **Project name.** Currently `apf_portal`, provisional. Do not hardcode it outside repo/workspace-level metadata so a rename stays a one-line change. - **Language.** All code, identifiers, comments, documentation, commit messages, and PR descriptions are written in **English**. (Conversation with the project lead happens in French — but artifacts shipped in the repo are English-only.) - **Commits / PRs.** Never add a `Co-Authored-By: Claude` trailer or a `🤖 Generated with Claude Code` footer to commits or PR bodies. - **Be a peer, not a typist.** Challenge requests when a better approach exists; surface trade-offs frankly. Don't silently execute a suboptimal directive — propose, then execute the agreed plan. @@ -32,7 +32,7 @@ These constraints were set by the project lead at kickoff. They apply to every c The structural choices are recorded as ADRs and summarized below. Any change to these requires updating the corresponding ADR. - **Workspace:** Nx monorepo with the `apps` preset, managed by pnpm — see [ADR-0002](decisions/0002-adopt-nx-monorepo-apps-preset.md). -- **Naming:** workspace `adastra-portal`; apps `portal-shell` (frontend) and `portal-bff` (backend); libs `feature-` and `shared-` — see [ADR-0003](decisions/0003-workspace-and-app-naming-convention.md). +- **Naming:** workspace `apf-portal`; apps `portal-shell` (frontend) and `portal-bff` (backend); libs `feature-` and `shared-` — see [ADR-0003](decisions/0003-workspace-and-app-naming-convention.md). - **Frontend (`portal-shell`):** Angular at the latest LTS major — standalone APIs, zoneless change detection, Signals, **CSR only (no SSR)**, Vitest, SCSS — see [ADR-0004](decisions/0004-frontend-stack-angular-csr-zoneless-signals.md). - **Backend (`portal-bff`):** NestJS at the latest stable major, mounted on the Express adapter (Fastify adapter swappable later) — see [ADR-0005](decisions/0005-backend-stack-nestjs.md). - **Persistence:** PostgreSQL (latest stable major) via Prisma — see [ADR-0006](decisions/0006-persistence-postgresql-prisma.md). diff --git a/decisions/0001-use-adrs-to-record-architectural-decisions.md b/decisions/0001-use-adrs-to-record-architectural-decisions.md index e30630b..a1c6fe0 100644 --- a/decisions/0001-use-adrs-to-record-architectural-decisions.md +++ b/decisions/0001-use-adrs-to-record-architectural-decisions.md @@ -9,7 +9,7 @@ tags: [process] ## Context and Problem Statement -Architecturally-significant decisions will be taken throughout the lifecycle of `adastra-portal`. Without a written, durable trace of *why* a decision was made — context, drivers, alternatives, trade-offs — that knowledge fades within months. New contributors re-litigate settled debates, the rationale of constraints (security, performance, accessibility) gets lost, and reversing a choice later becomes risky because nobody remembers what it was protecting against. +Architecturally-significant decisions will be taken throughout the lifecycle of `apf-portal`. Without a written, durable trace of *why* a decision was made — context, drivers, alternatives, trade-offs — that knowledge fades within months. New contributors re-litigate settled debates, the rationale of constraints (security, performance, accessibility) gets lost, and reversing a choice later becomes risky because nobody remembers what it was protecting against. How do we record decisions in a way that is light enough to be sustained, durable enough to outlive contributor turnover, and integrated into the development workflow? diff --git a/decisions/0002-adopt-nx-monorepo-apps-preset.md b/decisions/0002-adopt-nx-monorepo-apps-preset.md index ab193c9..9d79fd8 100644 --- a/decisions/0002-adopt-nx-monorepo-apps-preset.md +++ b/decisions/0002-adopt-nx-monorepo-apps-preset.md @@ -9,7 +9,7 @@ tags: [infrastructure, frontend, backend] ## Context and Problem Statement -`adastra-portal` will host two cooperating runtime artifacts from day one — an Angular SPA frontend and a Node.js BFF backend — and is expected to grow with feature libraries shared between them (auth, data-access, UI primitives). Strongly-typed contracts must travel from back to front without round-tripping through a published package, dependency hygiene must be enforceable, and CI must run only on what changed. +`apf-portal` will host two cooperating runtime artifacts from day one — an Angular SPA frontend and a Node.js BFF backend — and is expected to grow with feature libraries shared between them (auth, data-access, UI primitives). Strongly-typed contracts must travel from back to front without round-tripping through a published package, dependency hygiene must be enforceable, and CI must run only on what changed. How do we structure the repository so both apps coexist with shared libraries, builds and tests run incrementally, and the tooling is mainstream enough to be supported long-term? @@ -51,7 +51,7 @@ Plugins enabled at bootstrap: `@nx/angular`, `@nx/nest`, `@nx/eslint`, `@nx/vite ### Confirmation -* Workspace is bootstrapped with `pnpm dlx create-nx-workspace@latest adastra-portal --preset=apps --pm=pnpm`. +* Workspace is bootstrapped with `pnpm dlx create-nx-workspace@latest apf-portal --preset=apps --pm=pnpm`. * `nx.json` has `@nx/eslint/enforce-module-boundaries` enabled and configured against the project tags. * CI runs `pnpm nx affected -t lint test build` on every push. diff --git a/decisions/0003-workspace-and-app-naming-convention.md b/decisions/0003-workspace-and-app-naming-convention.md index 3efc257..869cba2 100644 --- a/decisions/0003-workspace-and-app-naming-convention.md +++ b/decisions/0003-workspace-and-app-naming-convention.md @@ -9,7 +9,7 @@ tags: [process] ## Context and Problem Statement -Default Nx scaffolding offers placeholder names like `my-workspace` and `web`, which are unacceptable for a long-lived enterprise project. Naming has to survive two foreseeable changes: the product's marketing name may evolve (the working title `adastra_portal` is provisional), and the project may sit alongside other R&D projects in the same Gitea organization, where collisions on generic names like `web` or `api` would cause confusion. +Default Nx scaffolding offers placeholder names like `my-workspace` and `web`, which are unacceptable for a long-lived enterprise project. Naming has to survive two foreseeable changes: the product's marketing name may evolve (the working title `apf_portal` is provisional), and the project may sit alongside other R&D projects in the same Gitea organization, where collisions on generic names like `web` or `api` would cause confusion. What naming convention do we adopt for the workspace, the apps, and future libraries so names are explicit, function-anchored, and stable against rebranding? @@ -24,7 +24,7 @@ What naming convention do we adopt for the workspace, the apps, and future libra ## Considered Options * **Defaults** — `my-workspace`, `web`. (Rejected up-front.) -* **Brand-anchored** — `adastra-front`, `adastra-back`. Fragile to rebranding. +* **Brand-anchored** — `apf-front`, `apf-back`. Fragile to further rebranding. * **Function-prefixed** — `portal-shell`, `portal-bff`. (Chosen.) * **Generic** — `shell`, `bff`. Risk of org-wide collision; reduced readability. @@ -34,13 +34,13 @@ Chosen option: **function-prefixed naming**. | Scope | Name | Rationale | | --- | --- | --- | -| Workspace / repo / npm package root | `adastra-portal` | matches the Gitea repository name; the only place a brand-ish name lives, so a rebrand is a one-line change | +| Workspace / repo / npm package root | `apf-portal` | matches the Gitea repository name; the only place a brand-ish name lives, so a rebrand is a one-line change | | Frontend app | `portal-shell` | "shell" describes the function — the Angular host that loads features | | Backend app | `portal-bff` | explicit role: backend-for-frontend | | Feature libraries | `feature-` | e.g. `feature-auth`, `feature-billing` | | Shared libraries | `shared-` | e.g. `shared-ui`, `shared-data-access`, `shared-util` | -The `portal-` prefix encodes the *function* (a portal). Even if the brand `Adastra` is renamed, "portal" remains accurate. The brand-ish token `adastra` is confined to the workspace root and a tiny number of metadata files (root `package.json`, repo URL). +The `portal-` prefix encodes the *function* (a portal). The host organisation's brand can change without invalidating "portal" — the project was originally proposed as `adastra_portal` and renamed to `apf_portal` on 2026-04-30 once the host organisation (APF France Handicap) was confirmed; the apps `portal-shell` / `portal-bff` were unaffected by the rename, validating this convention. The brand-ish token `apf` is confined to the workspace root and a tiny number of metadata files (root `package.json`, repo URL). ### Consequences diff --git a/decisions/0015-cicd-gitea-actions.md b/decisions/0015-cicd-gitea-actions.md index 738ad57..dd7c395 100644 --- a/decisions/0015-cicd-gitea-actions.md +++ b/decisions/0015-cicd-gitea-actions.md @@ -9,7 +9,7 @@ tags: [infrastructure, process] ## Context and Problem Statement -The repository currently lives on Gitea (`gitea@git.unespace.com:julien/adastra_portal.git`). The organisation plans to migrate to GitLab on a 6–18-month horizon. The pipeline shape we adopt now must be (a) operational on Gitea immediately, (b) low-cost to migrate later, and (c) consistent with the project's anti-bricolage and security-first values. +The repository currently lives on Gitea (`gitea@git.unespace.com:julien/apf_portal.git`). The organisation plans to migrate to GitLab on a 6–18-month horizon. The pipeline shape we adopt now must be (a) operational on Gitea immediately, (b) low-cost to migrate later, and (c) consistent with the project's anti-bricolage and security-first values. We also need to fix the branch model, the merge strategy, the required gates, the protection rules on `main`, and the location of the orchestration logic — all of these have first-order effects on the Nx scaffold (`package.json` scripts, lint configs, branch tags, conventional-commits validation surface). diff --git a/docs/setup/03-angular-nx-monorepo.md b/docs/setup/03-angular-nx-monorepo.md index 4134bd8..63d3f53 100644 --- a/docs/setup/03-angular-nx-monorepo.md +++ b/docs/setup/03-angular-nx-monorepo.md @@ -1,10 +1,10 @@ -# 🏗️ Bootstrap the Nx monorepo for adastra-portal +# 🏗️ Bootstrap the Nx monorepo for apf-portal > **Status.** Aligned with phase-1 ADRs ([0002](../../decisions/0002-adopt-nx-monorepo-apps-preset.md), [0003](../../decisions/0003-workspace-and-app-naming-convention.md), [0004](../../decisions/0004-frontend-stack-angular-csr-zoneless-signals.md), [0005](../../decisions/0005-backend-stack-nestjs.md), [0006](../../decisions/0006-persistence-postgresql-prisma.md)). Replaces the original placeholder-based draft. ## Goal -Scaffold the `adastra-portal` Nx monorepo containing: +Scaffold the `apf-portal` Nx monorepo containing: - `apps/portal-shell` — Angular SPA frontend (CSR, standalone, zoneless, Signals, Vitest, SCSS, strict TS). - `apps/portal-bff` — NestJS BFF backend (Express adapter, global `ValidationPipe`, Jest test runner). @@ -19,7 +19,7 @@ Out of scope here (covered by later phases): authentication (Entra ID), sessions - WSL + Zsh — see [01-wsl-terminal-setup.md](01-wsl-terminal-setup.md). - Node.js latest LTS + pnpm via corepack — see [02-dev-web-stack.md](02-dev-web-stack.md). - Working tree under the WSL filesystem (`~/dev/`, `~/Works/`), never `/mnt/c/`. -- The repository `adastra-portal` already exists locally with the ADRs and docs committed (you are reading one of them). +- The repository `apf-portal` already exists locally with the ADRs and docs committed (you are reading one of them). --- @@ -30,21 +30,21 @@ The repository already carries documentation, ADRs, `.vscode/`, and `.gitignore` ```bash # 1. Generate a clean Nx workspace next to the repo cd ~/dev # or any scratch location outside the repo -pnpm dlx create-nx-workspace@latest adastra-portal-bootstrap \ +pnpm dlx create-nx-workspace@latest apf-portal-bootstrap \ --preset=apps \ --pm=pnpm \ --ci=skip \ --useGitHub=false # 2. Copy the workspace files into the existing repo -cd adastra-portal-bootstrap +cd apf-portal-bootstrap cp -v package.json pnpm-workspace.yaml nx.json tsconfig.base.json \ .prettierrc .prettierignore .editorconfig \ eslint.config.mjs \ - ~/Works/adastra_portal/ + ~/Works/apf_portal/ # 3. Drop the scratch workspace -cd ~ && rm -rf ~/dev/adastra-portal-bootstrap +cd ~ && rm -rf ~/dev/apf-portal-bootstrap ``` The `apps` preset is generic — it does not privilege a runtime ([ADR-0002](../../decisions/0002-adopt-nx-monorepo-apps-preset.md)). Plugins are added in step 2. @@ -52,7 +52,7 @@ The `apps` preset is generic — it does not privilege a runtime ([ADR-0002](../ Verify: ```bash -cd ~/Works/adastra_portal +cd ~/Works/apf_portal pnpm install ls nx.json package.json tsconfig.base.json ``` @@ -314,7 +314,7 @@ module.exports = { extends: ['@commitlint/config-conventional'] }; ## 9) CI/CD -The pipeline targets the Gitea repository (`gitea@git.unespace.com:julien/adastra_portal.git`). Pipeline shape (Gitea Actions vs. third-party runner) and branch protection are deferred to phase-3 ADRs (planned: ADR-0017). Locally, the equivalent of the future CI check is: +The pipeline targets the Gitea repository (`gitea@git.unespace.com:julien/apf_portal.git`). Pipeline shape (Gitea Actions vs. third-party runner) and branch protection are deferred to phase-3 ADRs (planned: ADR-0017). Locally, the equivalent of the future CI check is: ```bash pnpm nx affected -t lint test build