chore: initialize repository with project rules, docs, and phase-1 ADRs
Set up the foundation for the adastra-portal project: - CLAUDE.md captures durable project rules (quality bar, security/perf/a11y as first-class, language, commit conventions, ADR proactivity). - docs/ and decisions/ scaffolding with maintained indexes (docs/README.md and decisions/README.md), MADR 4.0.0 template, and tag vocabulary. - Phase-1 ADRs (0001-0006) lock structural choices: ADR usage, Nx monorepo with the apps preset, naming convention (adastra-portal / portal-shell / portal-bff), Angular CSR/zoneless/Signals/Vitest, NestJS over Express, PostgreSQL with Prisma. - docs/setup/ guides translated to English. - .gitignore covers Node/Nx artifacts and the personal notes/ scratchpad. The Nx workspace itself is not yet bootstrapped; that step is gated on a revised setup guide aligned with the ADRs.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-04-29
|
||||
decision-makers: R&D Lead
|
||||
tags: [infrastructure, frontend, backend]
|
||||
---
|
||||
|
||||
# Adopt Nx monorepo with the `apps` preset
|
||||
|
||||
## 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.
|
||||
|
||||
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?
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
* Two cooperating runtimes (Angular + NestJS), both TypeScript, sharing types and contracts on the wire.
|
||||
* Need for incremental, cached builds and tests on what changed (`affected`-style workflow).
|
||||
* Long-term enterprise track record — no exotic stack.
|
||||
* Compatibility with `pnpm` (already mandated by project setup).
|
||||
* Enforceable dependency boundaries between apps and libs.
|
||||
|
||||
## Considered Options
|
||||
|
||||
* **Polyrepos** — separate repository per runtime.
|
||||
* **Nx with the `apps` preset** — generic multi-tech workspace, plugins added as needed (`@nx/angular`, `@nx/nest`).
|
||||
* **Nx with the `angular-monorepo` preset** — front-first preset, BFF grafted on later.
|
||||
* **Turborepo + pnpm workspaces** — lighter alternative to Nx.
|
||||
* **pnpm workspaces alone** — manual orchestration, no monorepo tool.
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: **Nx monorepo with the `apps` preset, managed by pnpm**.
|
||||
|
||||
The workspace will host:
|
||||
- `apps/portal-shell` — Angular SPA frontend (see [ADR-0004](0004-frontend-stack-angular-csr-zoneless-signals.md));
|
||||
- `apps/portal-bff` — NestJS BFF backend (see [ADR-0005](0005-backend-stack-nestjs.md));
|
||||
- `libs/shared/<scope>` and `libs/feature/<name>` for shared and feature code (see [ADR-0003](0003-workspace-and-app-naming-convention.md)).
|
||||
|
||||
Plugins enabled at bootstrap: `@nx/angular`, `@nx/nest`, `@nx/eslint`, `@nx/vite` (Vitest).
|
||||
|
||||
### Consequences
|
||||
|
||||
* Good, because front and back share types, lint config, formatter, and test runner with no extra plumbing.
|
||||
* Good, because Nx's project graph + `affected` make CI fast and frugal as the codebase grows.
|
||||
* Good, because the `apps` preset stays neutral — neither runtime is privileged in workspace structure.
|
||||
* Good, because Nx is mainstream, used by major enterprises, and actively maintained by Nrwl.
|
||||
* Bad, because Nx adds a non-trivial conceptual surface (executors, generators, project graph) — a one-time learning cost.
|
||||
* Bad, because monorepos require discipline to keep dependency boundaries clean — mitigated by Nx's `enforce-module-boundaries` lint rule.
|
||||
|
||||
### Confirmation
|
||||
|
||||
* Workspace is bootstrapped with `pnpm dlx create-nx-workspace@latest adastra-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.
|
||||
|
||||
## Pros and Cons of the Options
|
||||
|
||||
### Polyrepos
|
||||
|
||||
* Good, because each runtime has independent versioning and CI scope.
|
||||
* Bad, because sharing TypeScript types across repos requires a published package (overhead, version drift).
|
||||
* Bad, because cross-cutting changes (e.g. adjusting an auth claim shape) touch two repos and two PRs.
|
||||
|
||||
### Nx with `apps` preset (chosen)
|
||||
|
||||
* Good, because runtime-agnostic — Angular and Node coexist as peers.
|
||||
* Good, because Nx provides build orchestration, caching, generators, and lint boundaries out of the box.
|
||||
|
||||
### Nx with `angular-monorepo` preset
|
||||
|
||||
* Good, because faster initial setup for a front-first project.
|
||||
* Bad, because the preset implies the project is "an Angular workspace" — the BFF feels grafted, the workspace `package.json` ends up biased toward Angular tooling.
|
||||
|
||||
### Turborepo
|
||||
|
||||
* Good, because lighter, no codegen surface.
|
||||
* Neutral, because caching/affected is comparable.
|
||||
* Bad, because no first-class Angular plugin; both runtimes would need manual integration.
|
||||
* Bad, because smaller enterprise track record than Nx.
|
||||
|
||||
### pnpm workspaces alone
|
||||
|
||||
* Good, because no extra tool to learn.
|
||||
* Bad, because no caching, no `affected`, no generators — every piece reinvented by hand (the bricolage we're forbidden).
|
||||
|
||||
## More Information
|
||||
|
||||
* Nx documentation: https://nx.dev
|
||||
* Nx `apps` preset: https://nx.dev/getting-started/intro
|
||||
* Related ADRs: [ADR-0003](0003-workspace-and-app-naming-convention.md), [ADR-0004](0004-frontend-stack-angular-csr-zoneless-signals.md), [ADR-0005](0005-backend-stack-nestjs.md), ADR-0017 (CI/CD, future).
|
||||
Reference in New Issue
Block a user