From 72c53494a13ebf9014b50e5df0cdf3703b558827 Mon Sep 17 00:00:00 2001 From: implementer Date: Fri, 28 Aug 2026 08:52:03 +0000 Subject: [PATCH] docs: add local non-container developer path guide (E00-S01-T06) --- docs/development/non-container.md | 141 ++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 docs/development/non-container.md diff --git a/docs/development/non-container.md b/docs/development/non-container.md new file mode 100644 index 0000000..b531cc0 --- /dev/null +++ b/docs/development/non-container.md @@ -0,0 +1,141 @@ +# Local non-container development + +This guide documents the **local, non-container developer path** for the EPPP +workspace: how to install, build and run the project on your machine **without +Docker**. The containerised path (Docker Compose baseline, container smoke +tests) is tracked separately as story [E00-S02] Docker Compose baseline and is +**not** covered here. + +> Status: this document tracks the E00-S01 workspace bootstrap state. Commands +> and expected outputs below were verified from a clean clone. + +## What you get at bootstrap + +The workspace is a pnpm monorepo with three package groups: + +| Group | Path | Purpose | +| --- | --- | --- | +| `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Bootstrap placeholder — the Fastify 5 application shell lands in a later story. | +| `packages/` | `packages/core` (`@personal-blog/core`) | Application core (site identity, content primitives). Bootstrap placeholder. | +| `extensions/` | `extensions/example` (`@personal-blog/example-extension`) | Example extension exercising the `extensions/` group. Bootstrap placeholder. | + +A dependency-boundary rule (`dependency-boundaries.json`, enforced by +`tests/architecture-import.test.mjs`) keeps the groups from collapsing into an +accidental dependency graph: no `packages/*` package may import a concrete +`extensions/*` package. + +## Prerequisites + +- **Git** — to clone the repository. +- **Node.js 24.x** — the CI pipeline runs Node 24 and this is the supported + line for the workspace (a hard `engines` restriction is tracked separately as + E00-S01-T08). Any Node ≥ 22 is enough for the current bootstrap commands. +- **pnpm 11.23.0** — pinned via the `packageManager` field in the root + `package.json`. The easiest way to get exactly this version is Corepack, + which ships with Node.js (`corepack enable`). + +No database, no runtime services and no Docker daemon are required at this +stage. + +## Install + +```sh +# 1. Clone the repository +git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git +cd PersonalBlog + +# 2. Activate the pinned pnpm (11.23.0) via Corepack +corepack enable + +# 3. Install dependencies against the committed lockfile (reproducible) +pnpm install --frozen-lockfile +``` + +- The install is **frozen**: `--frozen-lockfile` refuses to run if + `pnpm-lock.yaml` is out of date with the manifests, so every clone gets the + exact same dependency tree. CI uses the same flag. +- If you are adding or changing dependencies, run `pnpm install` (without the + flag) and **commit the resulting `pnpm-lock.yaml`** so the frozen install + keeps working for everyone. +- `node_modules/` and the pnpm content-addressable store are git-ignored and + never committed. + +## Build + +```sh +# Compile every workspace package (apps, packages, extensions) into dist/ +pnpm build + +# Typecheck every workspace package (no emit) +pnpm typecheck +``` + +`pnpm build` runs `tsc -p tsconfig.json` in each package in topological order +and emits `dist/` (JavaScript + type declarations + source maps) per package. +Expected result: `apps/server/dist/`, `packages/core/dist/` and +`extensions/example/dist/` are produced, all packages report `Done`, exit 0. +`dist/` is git-ignored; rebuild whenever you change `src/`. + +## Run + +```sh +# Run the compiled public server entrypoint +pnpm --filter @personal-blog/server start +``` + +This runs the `start` script of `apps/server` (`node dist/index.js`), i.e. the +compiled application entrypoint. Two things to know at bootstrap: + +1. The command **must follow `pnpm build`** — the `start` script executes the + compiled artifact in `dist/`, it does not compile first. +2. `apps/server` is currently a **bootstrap placeholder**: its entrypoint is an + empty module, so starting it loads the module and exits cleanly (exit 0) + without opening an HTTP port yet. The real Fastify 5 application shell — + which turns this into a serving process — lands in a later story; the + `start` command shape above stays the same once it does. + +To run the compiled output of any other workspace package directly: + +```sh +node /dist/index.js # e.g. node packages/core/dist/index.js +``` + +## Test + +```sh +pnpm test +``` + +`pnpm test` runs the `node:test` suites under `tests/` (currently +`tests/architecture-import.test.mjs`, 10 tests) with zero extra dependencies. +This is also the suite that enforces the dependency-boundary rule. + +## Smoke check from a clean clone + +```sh +git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git && cd PersonalBlog +corepack enable +pnpm install --frozen-lockfile # exit 0, lockfile untouched +pnpm build # 3/3 packages emit dist/, exit 0 +pnpm typecheck # 3/3 packages pass --noEmit, exit 0 +pnpm test # 10/10 pass, exit 0 +pnpm --filter @personal-blog/server start # loads compiled server entrypoint, exit 0 +``` + +## Troubleshooting + +| Symptom | Cause / fix | +| --- | --- | +| `pnpm: command not found` | Corepack shims not activated — run `corepack enable`, or prefix commands with `corepack pnpm ...`. | +| `ERR_PNPM_OUTDATED_LOCKFILE` | `pnpm-lock.yaml` is out of date with the manifests. Run `pnpm install` (unfrozen) and commit the lockfile update. | +| Node version warnings / unexpected behavior | Use Node 24.x to match CI (e.g. via `nvm`, `fnm` or another version manager). A hard `engines` restriction is tracked as E00-S01-T08. | +| `start` exits immediately with no output | Expected at bootstrap — the server entrypoint is a placeholder module; the Fastify 5 shell is a later story (see [Run](#run)). | +| `.env` files | `.env`/`.env.*` are git-ignored; a committed `.env.example` template lands with the environment story (E00-S04). | + +## Out of scope + +- Root build/test/typecheck **script wiring** — covered by E00-S01-T05; only + usage is documented here. +- **Docker Compose baseline** and container smoke tests — E00-S02. +- PostgreSQL adapter, migration runner and other runtime services — later E00 + stories.