chore: rename project from adastra_portal to apf_portal
The host organisation - APF France Handicap - was confirmed on 2026-04-30. Update all in-repo references to use apf_portal (snake_case in prose) and apf-portal (kebab-case workspace name and repo URL). Touched: CLAUDE.md, ADRs 0001/0002/0003/0015, and the Nx bootstrap setup guide. The historical name is preserved as a single sentence in ADR-0003 as a self-validating example of the function-prefixed naming convention designed exactly for this scenario - the apps (portal-shell, portal-bff) and the lib conventions (feature-<name>, shared-<scope>) were unaffected by the rename, which was the explicit point of ADR-0003. Memory state aligned out-of-band: project_adastra.md retired, project_apf_portal.md created with the expanded APF context (host org, health + financial data scope, ASVS L3 pending RSSI input, UI stack decision spartan-ng + CDK + Tailwind, expanded phase-3 status). Pending follow-ups (user-side, not in this commit): - rename the Gitea repo julien/adastra_portal -> julien/apf_portal - git remote set-url origin gitea@git.unespace.com:julien/apf_portal.git - optionally rename the local working directory ~/Works/adastra_portal/ -> ~/Works/apf_portal/
This commit is contained in:
@@ -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.
|
- **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.
|
- **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.)
|
- **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.
|
- **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.
|
- **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.
|
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).
|
- **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-<name>` and `shared-<scope>` — 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-<name>` and `shared-<scope>` — 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).
|
- **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).
|
- **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).
|
- **Persistence:** PostgreSQL (latest stable major) via Prisma — see [ADR-0006](decisions/0006-persistence-postgresql-prisma.md).
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ tags: [process]
|
|||||||
|
|
||||||
## Context and Problem Statement
|
## 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?
|
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?
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ tags: [infrastructure, frontend, backend]
|
|||||||
|
|
||||||
## Context and Problem Statement
|
## 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?
|
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
|
### 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.
|
* `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.
|
* CI runs `pnpm nx affected -t lint test build` on every push.
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ tags: [process]
|
|||||||
|
|
||||||
## Context and Problem Statement
|
## 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?
|
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
|
## Considered Options
|
||||||
|
|
||||||
* **Defaults** — `my-workspace`, `web`. (Rejected up-front.)
|
* **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.)
|
* **Function-prefixed** — `portal-shell`, `portal-bff`. (Chosen.)
|
||||||
* **Generic** — `shell`, `bff`. Risk of org-wide collision; reduced readability.
|
* **Generic** — `shell`, `bff`. Risk of org-wide collision; reduced readability.
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ Chosen option: **function-prefixed naming**.
|
|||||||
|
|
||||||
| Scope | Name | Rationale |
|
| 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 |
|
| Frontend app | `portal-shell` | "shell" describes the function — the Angular host that loads features |
|
||||||
| Backend app | `portal-bff` | explicit role: backend-for-frontend |
|
| Backend app | `portal-bff` | explicit role: backend-for-frontend |
|
||||||
| Feature libraries | `feature-<name>` | e.g. `feature-auth`, `feature-billing` |
|
| Feature libraries | `feature-<name>` | e.g. `feature-auth`, `feature-billing` |
|
||||||
| Shared libraries | `shared-<scope>` | e.g. `shared-ui`, `shared-data-access`, `shared-util` |
|
| Shared libraries | `shared-<scope>` | 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
|
### Consequences
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ tags: [infrastructure, process]
|
|||||||
|
|
||||||
## Context and Problem Statement
|
## 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).
|
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).
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
> **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
|
## 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-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).
|
- `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).
|
- 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).
|
- 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/`.
|
- 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
|
```bash
|
||||||
# 1. Generate a clean Nx workspace next to the repo
|
# 1. Generate a clean Nx workspace next to the repo
|
||||||
cd ~/dev # or any scratch location outside 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 \
|
--preset=apps \
|
||||||
--pm=pnpm \
|
--pm=pnpm \
|
||||||
--ci=skip \
|
--ci=skip \
|
||||||
--useGitHub=false
|
--useGitHub=false
|
||||||
|
|
||||||
# 2. Copy the workspace files into the existing repo
|
# 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 \
|
cp -v package.json pnpm-workspace.yaml nx.json tsconfig.base.json \
|
||||||
.prettierrc .prettierignore .editorconfig \
|
.prettierrc .prettierignore .editorconfig \
|
||||||
eslint.config.mjs \
|
eslint.config.mjs \
|
||||||
~/Works/adastra_portal/
|
~/Works/apf_portal/
|
||||||
|
|
||||||
# 3. Drop the scratch workspace
|
# 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.
|
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:
|
Verify:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/Works/adastra_portal
|
cd ~/Works/apf_portal
|
||||||
pnpm install
|
pnpm install
|
||||||
ls nx.json package.json tsconfig.base.json
|
ls nx.json package.json tsconfig.base.json
|
||||||
```
|
```
|
||||||
@@ -314,7 +314,7 @@ module.exports = { extends: ['@commitlint/config-conventional'] };
|
|||||||
|
|
||||||
## 9) CI/CD
|
## 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
|
```bash
|
||||||
pnpm nx affected -t lint test build
|
pnpm nx affected -t lint test build
|
||||||
|
|||||||
Reference in New Issue
Block a user