[E00-S04-T05] .env.example contains placeholders only #404

Merged
kpcto merged 6 commits from feature/186 into main 2026-08-30 05:47:44 +00:00
4 changed files with 9 additions and 8 deletions
Showing only changes of commit ec4719a8b4 - Show all commits
+2 -1
View File
@@ -49,7 +49,8 @@
# removing any embedded secret. Tests: tests/secrets-not-embedded.test.mjs. # removing any embedded secret. Tests: tests/secrets-not-embedded.test.mjs.
# #
# All values have defaults so `docker compose up -d` works from a clean clone # All values have defaults so `docker compose up -d` works from a clean clone
# without a .env file (a committed .env.example template lands in E00-S04). # without a .env file (the committed .env.example template, E00-S04-T05,
# lists the overridable variables with placeholder values).
# Since E00-S04-T02 the app validates its required settings at startup: the # Since E00-S04-T02 the app validates its required settings at startup: the
# admin-session secret `EPPP_SESSION_SECRET` (the schema's required field, # admin-session secret `EPPP_SESSION_SECRET` (the schema's required field,
# Security-and-Operations §32/§26) is provided here with a dev-only default — # Security-and-Operations §32/§26) is provided here with a dev-only default —
+4 -4
View File
@@ -17,7 +17,7 @@ The workspace is a pnpm monorepo with three package groups:
| --- | --- | --- | | --- | --- | --- |
| `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Serves the application health endpoint (E00-S02-T03) gated on the startup migration run (E00-S03-T06), fails fast at startup with a field-specific error when a required setting is missing (E00-S04-T02), redacts secret values from all log output (E00-S04-T03), and reads all of its settings through the config package's environment adapter — no `process.env` reads in the server (E00-S04-T04); the Fastify 5 application shell lands in a later story. | | `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Serves the application health endpoint (E00-S02-T03) gated on the startup migration run (E00-S03-T06), fails fast at startup with a field-specific error when a required setting is missing (E00-S04-T02), redacts secret values from all log output (E00-S04-T03), and reads all of its settings through the config package's environment adapter — no `process.env` reads in the server (E00-S04-T04); the Fastify 5 application shell lands in a later story. |
| `packages/` | `packages/core` (`@personal-blog/core`) | Application core (site identity, content primitives). Bootstrap placeholder. | | `packages/` | `packages/core` (`@personal-blog/core`) | Application core (site identity, content primitives). Bootstrap placeholder. |
| `packages/` | `packages/config` (`@personal-blog/config`) | Configuration service. Owns the TypeBox/Ajv configuration schema for the validated config fields (E00-S04-T01), the field-specific startup error for a missing required setting (E00-S04-T02), the secret redaction layer (E00-S04-T03) and the environment adapter — the workspace's single owner of `process.env` reads, mapping `HOST`/`PORT`/`DATABASE_URL`/`EPPP_SESSION_SECRET` onto the validated config (E00-S04-T04) and validating `HOST` as a hostname or IP address at the adapter boundary; the `.env.example` template (E00-S04-T05) lands in a later task. | | `packages/` | `packages/config` (`@personal-blog/config`) | Configuration service. Owns the TypeBox/Ajv configuration schema for the validated config fields (E00-S04-T01), the field-specific startup error for a missing required setting (E00-S04-T02), the secret redaction layer (E00-S04-T03) and the environment adapter — the workspace's single owner of `process.env` reads, mapping `HOST`/`PORT`/`DATABASE_URL`/`EPPP_SESSION_SECRET` onto the validated config (E00-S04-T04) and validating `HOST` as a hostname or IP address at the adapter boundary; the committed `.env.example` template (E00-S04-T05) documents every variable with placeholder values only. |
| `packages/` | `packages/database-postgres` (`@personal-blog/database-postgres`) | PostgreSQL database adapter package. Single owner of the `pg`/Kysely driver imports (E00-S03-T02); the migration ledger (`schema_migrations`, E00-S03-T03), the migration advisory lock (E00-S03-T04) and the migration runner with its failure diagnostic (E00-S03-T05) are implemented here. The server depends on this package to run the startup migrations behind its readiness gate (E00-S03-T06). | | `packages/` | `packages/database-postgres` (`@personal-blog/database-postgres`) | PostgreSQL database adapter package. Single owner of the `pg`/Kysely driver imports (E00-S03-T02); the migration ledger (`schema_migrations`, E00-S03-T03), the migration advisory lock (E00-S03-T04) and the migration runner with its failure diagnostic (E00-S03-T05) are implemented here. The server depends on this package to run the startup migrations behind its readiness gate (E00-S03-T06). |
| `extensions/` | `extensions/example` (`@personal-blog/example-extension`) | Example extension exercising the `extensions/` group. Bootstrap placeholder. | | `extensions/` | `extensions/example` (`@personal-blog/example-extension`) | Example extension exercising the `extensions/` group. Bootstrap placeholder. |
@@ -99,8 +99,8 @@ compiled application entrypoint. Three things to know:
must be set in the environment — if it is missing, the process fails fast must be set in the environment — if it is missing, the process fails fast
with a field-specific startup error (`missing required setting: with a field-specific startup error (`missing required setting:
sessionSecret`) that names the missing field instead of booting. Provide it sessionSecret`) that names the missing field instead of booting. Provide it
in your shell or a local `.env` file (the `.env.example` template lands in in your shell or a local `.env` file copied from the committed
E00-S04). `.env.example` template (E00-S04-T05).
3. Since [E00-S02-T03], `apps/server` serves the **application health 3. Since [E00-S02-T03], `apps/server` serves the **application health
endpoint**: starting it opens an HTTP server on port 3000 answering endpoint**: starting it opens an HTTP server on port 3000 answering
`GET /health`, so the process stays up. Since [E00-S03-T06] the endpoint `GET /health`, so the process stays up. Since [E00-S03-T06] the endpoint
@@ -170,7 +170,7 @@ pnpm --filter @personal-blog/server start # requires EPPP_SESSION_SECRET (see
| `ERR_PNPM_UNSUPPORTED_ENGINE` on install | Your Node version is outside the supported 24.x engine line (`engines.node` in the root `package.json`, enforced by `engineStrict: true` in `pnpm-workspace.yaml`). Install Node 24.x (e.g. via `nvm`, `fnm` or another version manager). | | `ERR_PNPM_UNSUPPORTED_ENGINE` on install | Your Node version is outside the supported 24.x engine line (`engines.node` in the root `package.json`, enforced by `engineStrict: true` in `pnpm-workspace.yaml`). Install Node 24.x (e.g. via `nvm`, `fnm` or another version manager). |
| `start` exits immediately with no output | The server crashed or exited at startup — check the process output. Since [E00-S02-T03] the entrypoint serves `GET /health` on port 3000 and stays up; a missing `pnpm build` (stale/absent `dist/`) is the usual cause (see [Run](#run)). | | `start` exits immediately with no output | The server crashed or exited at startup — check the process output. Since [E00-S02-T03] the entrypoint serves `GET /health` on port 3000 and stays up; a missing `pnpm build` (stale/absent `dist/`) is the usual cause (see [Run](#run)). |
| `start` fails with `missing required setting: sessionSecret` | Since [E00-S04-T02] the server validates its required settings at startup: the admin-session secret `EPPP_SESSION_SECRET` (≥ 32 chars) is missing or too short — set it in your shell or a local `.env` file (see [Run](#run)). | | `start` fails with `missing required setting: sessionSecret` | Since [E00-S04-T02] the server validates its required settings at startup: the admin-session secret `EPPP_SESSION_SECRET` (≥ 32 chars) is missing or too short — set it in your shell or a local `.env` file (see [Run](#run)). |
| `.env` files | `.env`/`.env.*` are git-ignored; a committed `.env.example` template lands with the environment story (E00-S04). | | `.env` files | `.env`/`.env.*` are git-ignored; the committed `.env.example` template (E00-S04-T05) shows placeholder values only. |
## Out of scope ## Out of scope
+1 -1
View File
@@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"description": "EPPP configuration service. Owns the TypeBox/Ajv configuration schema (E00-S04-T01), the field-specific startup error for a missing required setting (E00-S04-T02), the secret redaction layer (E00-S04-T03) and the environment adapter — the single owner of process.env reads, validating HOST as a hostname/IP at the adapter boundary (E00-S04-T04); the .env.example template (E00-S04-T05) lands in a later task.", "description": "EPPP configuration service. Owns the TypeBox/Ajv configuration schema (E00-S04-T01), the field-specific startup error for a missing required setting (E00-S04-T02), the secret redaction layer (E00-S04-T03) and the environment adapter — the single owner of process.env reads, validating HOST as a hostname/IP at the adapter boundary (E00-S04-T04); the committed .env.example template (E00-S04-T05) ships placeholder values only.",
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"typecheck": "tsc -p tsconfig.json --noEmit" "typecheck": "tsc -p tsconfig.json --noEmit"
+2 -2
View File
@@ -26,8 +26,8 @@
* reads `process.env` directly. `HOST` is validated at the adapter boundary * reads `process.env` directly. `HOST` is validated at the adapter boundary
* as a hostname or IP address before it is used for binding or logged, so * as a hostname or IP address before it is used for binding or logged, so
* arbitrary env content is never echoed verbatim into the startup log. The * arbitrary env content is never echoed verbatim into the startup log. The
* `.env.example` template (E00-S04-T05) builds on this boundary in a later * committed `.env.example` template (E00-S04-T05) documents the same
* task. * variables with placeholder values only.
*/ */
export { configSchema } from './schema.js'; export { configSchema } from './schema.js';