Zum Inhalt springen

11 — Docs Site (`docs.nowyourlink.com`)

Status: Draft Date: 2026-05-23 Owner: docs/devrel agent team Depends on: Master design D18 (Starlight), D19 (i18n EN+DE), D20 (subdomain docs.) Pattern source: ghardenlab-platform/docs-site/ (Astro 5 + @astrojs/starlight 0.32, prebuild generator pattern)


Publish every spec, process diagram, runbook, and onboarding doc that lives in docs/superpowers/ as a navigable site at https://docs.nowyourlink.com — EN primary, DE secondary, mermaid + Pagefind, deployed via Cloudflare Pages. Build-in-the-open posture matches the PDF’s marketing angle.

In scope: Astro Starlight site under docs-site/; sidebar grouped by sub-system 01–12 + cross-cutting; EN+DE (only Getting Started + Architecture translated at MVP); mermaid; Pagefind; build-time sync of docs/superpowers/{specs,processes,runbooks}/ into docs-site/src/content/docs/; CF Pages deploy with PR previews and custom domain; public site with /internal/* Access-gated.

Out of scope (Phase 2+): auto-generated API reference, Algolia DocSearch, versioned docs, full DE translation of sub-specs.


nowyourlink/
docs/superpowers/
specs/2026-05-23-NN-*.md # source of truth
processes/NN-*.md # source of truth
runbooks/*.md
docs-site/
package.json # pnpm workspace member
astro.config.mjs
tsconfig.json
src/
content.config.ts
content/docs/
index.mdx # EN landing (hero, CTA)
getting-started/
architecture/
sub-systems/01-foundation/ # synced specs + processes
sub-systems/02-identity/
...
operations/ # runbooks
decisions-log.md # generated from master §2
risks.md # generated from master §6
cost-performance.md # generated from research/cf-cost-projection.md
api-reference/index.md # placeholder
legal.md # links to apex /legal
de/ # mirror tree, MVP-translated subset
index.mdx
getting-started/
architecture/
internal/ # CF Access-gated runbooks
scripts/
sync-specs.mjs # copies specs + processes into content/docs/sub-systems/
link-check.mjs # build-time cross-link verifier
public/
favicon.svg
og-nowyourlink.png

Pattern reused from ghardenlab-platform/docs-site: prebuild script regenerates content before astro build (theirs is gen-reference.ts; ours is sync-specs.mjs). Same Astro 5 + Starlight 0.32 stack.


Top-level groups, in order:

  1. Getting Started — what is nowyourlink, glossary, “build your first bid” walkthrough, contributor setup.
  2. Architecture — master design, sub-system map, cross-cutting contracts, domain layout.
  3. Sub-Systems — collapsible group per sub-system 01–12, each with Design spec + nested Processes.
  4. Operations — runbooks (deploy, on-call, Sentry setup, Stripe webhook replay, degraded-mode), env & secrets reference.
  5. Decisions Log — generated from master §2.
  6. Risks — generated from master §6.
  7. Cost & Performance — synced from research/cf-cost-projection.md.
  8. API Reference — placeholder (“Phase 2”).
  9. Legal Notice — links to apex Impressum/AGB/Datenschutz (sub-system 12).

Top-level structure is hand-curated in astro.config.mjs (explicit items: [...]) for stable ordering; per-sub-system inner trees use autogenerate: { directory: 'sub-systems/NN-*' }.


  • Starlight locales: root: { label: 'English', lang: 'en' }, de: { label: 'Deutsch', lang: 'de' }. EN default; DE opt-in via picker.
  • MVP DE coverage: index.mdx, getting-started/*, architecture/overview.md. Everything else falls back to EN and renders <TranslationPendingBanner /> (Diese Seite ist nur auf Englisch verfügbar).
  • Source-of-truth specs stay English — drift cost too high to translate at MVP.
  • The product uses Paraglide (D19); the docs site uses Starlight’s built-in i18n. Different concerns.

Use astro-mermaid (Starlight 0.32 compatible); fallback rehype-mermaid via remark. Theme follows Starlight --sl-color-* tokens (default/dark). Lazy render via the integration’s native mode. Test fixture: render master §3 sub-system map without “raw text” fallback.

Starlight 0.32 ships Pagefind zero-config as a postbuild step. Static dist/_pagefind/, no hosted service. Acceptance: search cascade saga returns payment-saga spec; Spotlight reveal returns engagement-features.


Superseded (2026-05-24) by ADR-0002. The docs site now ships as a Cloudflare Worker with the [assets] binding (Workers Static Assets) rather than a Pages project. Cloudflare moved Pages to maintenance mode and recommends Workers for new static sites; the migration also unifies the deploy surface with every other app in the monorepo (wrangler deploy). The build pipeline (Starlight + Astro + Pagefind) and the public hostname are unchanged. Read ADR-0002 for the binding-by-binding mapping; the bullets below describe the original Pages plan and are kept for context only.

  • Pages project: nowyourlink-docs (separate from nowyourlink-web).
  • Build command: pnpm install --frozen-lockfile && pnpm --filter docs-site build
  • Output dir: docs-site/dist
  • Root dir: repo root (so pnpm workspaces resolve).
  • Node version: matches root .nvmrc (Node 22).
  • Custom domain: docs.nowyourlink.com (Terraform-managed via D24, CNAME flattening at apex zone).
  • Preview deploys: per PR, default Pages behaviour. URL pattern https://<sha>.nowyourlink-docs.pages.dev.
  • Headers: _headers file sets Cache-Control: public, max-age=300, s-maxage=86400 on HTML, max-age=31536000, immutable on /_astro/* and /_pagefind/*.
  • Redirects: _redirects file aliases /sub-systems/auction → current canonical slug so links survive renames.

Decision: Site is public by default; only /internal/* is gated by CF Access (audience docs-internal).

Rationale: build-in-the-open is a PR + recruiting moat; bidders self-serve from process diagrams; operational secrets (DSN names, webhook URLs, on-call rotation, infra topology) live under /internal/* behind the same admin group as admin.nowyourlink.com (D15). Kill-switch: one zone-level Access policy flips the site to admin-only with no rebuild.


docs-site/scripts/sync-specs.mjs runs as prebuild:

  1. Walk ../docs/superpowers/specs/ and ../docs/superpowers/processes/.
  2. Copy each 2026-05-23-NN-<slug>-design.md → src/content/docs/sub-systems/NN-<slug>/design.md, injecting Starlight front-matter (title, sidebar.label, sidebar.order).
  3. Copy each NN-<sub>.md process → src/content/docs/sub-systems/NN-<slug>/processes/<sub>.md.
  4. Rewrite cross-links: ../processes/04-bid-placement.md → /sub-systems/04-auction-engine/processes/bid-placement/.
  5. Generate decisions-log.md and risks.md from master §2 and §6 tables.
  6. Emit dist-sync-manifest.json for link-check.mjs.

Copy, not symlink: CF Pages unrolls symlinks unpredictably; Astro Content Collections want real files. Not a workspace dep: specs are human-authored across teams — workspace dep adds friction.

Pagefind crawls all dist/ pages including synced specs (zero-config). /internal/* is excluded via data-pagefind-ignore on its layout wrapper — defence in depth even though Access-gated.


  • Favicon: shared public/favicon.svg from apex.
  • OG image: default public/og-nowyourlink.png (1200×630, “nowyourlink — Docs”); per-page override via Starlight front-matter head.
  • Regenerate that image from public/og-nowyourlink.svg: inkscape apps/docs-site/public/og-nowyourlink.svg --export-type=png --export-filename=apps/docs-site/public/og-nowyourlink.png --export-png-use-dithering=false --export-png-compression=9 --export-png-color-mode=RGB_8.
  • Hero: Starlight hero — tagline + CTAs “Read the architecture” / “Open the spec on GitHub”.
  • Theme: customCss imports src/styles/brand.css overriding --sl-color-accent-* (palette finalized in sub-system 07).
  • schema.org: inject SoftwareApplication JSON-LD via a Head component.
  • robots.txt: allow all, disallow /internal/*. Sitemap via @astrojs/sitemap.

CaseHandling
Spec is renamed and an internal link breakslink-check.mjs runs after sync-specs.mjs, fails the build with a list of broken links and a suggested redirect.
Large mermaid diagram blocks paintastro-mermaid lazy mode + loading="lazy" on the SVG wrapper.
DE string missingStarlight auto-falls-back to EN; <TranslationPendingBanner /> renders if locale is de and source file lives outside de/.
Spec contains a secret accidentallyPre-commit hook + CI gitleaks run on docs/; sync-specs.mjs refuses to copy a file matching the secret-pattern regex.
PR preview URL leaks unreleased plansPreview deploys are public by default — acceptable given build-in-the-open. If a spec is status: confidential, sync script skips it.
Pagefind index gets hugeSet pagefind.maxResultsPerPage = 8; exclude decisions-log.md rows from index (tables tokenize badly).

  1. pnpm --filter docs-site dev boots locally; visiting http://localhost:4321/ shows landing with hero.
  2. Sidebar contains all nine top-level groups; Sub-Systems group has 12 entries each with a Design spec link.
  3. Editing docs/superpowers/specs/2026-05-23-04-auction-engine-design.md and reloading shows the change in the docs site (after prebuild runs).
  4. Mermaid diagram from master design §3 renders as SVG.
  5. Pagefind search for cascade returns the payment-saga page.
  6. Language picker switches / → /de/; DE landing renders translated; navigating to an EN-only spec shows the pending-translation banner.
  7. CF Pages deploy succeeds on push to main; https://docs.nowyourlink.com resolves and serves the landing within 10 min of merge.
  8. /internal/runbooks/on-call returns CF Access login when not authenticated.
  9. link-check.mjs fails the build if a synced spec references a non-existent sibling spec.
  10. Lighthouse: Performance ≥ 95, Accessibility ≥ 95, SEO ≥ 95 on landing.

  • Bootstrap by copying ghardenlab-platform/docs-site/ wholesale, then rename gen-reference.ts → sync-specs.mjs. Versions match.
  • Sidebar: explicit items at top level; autogenerate only inside each sub-system folder.
  • Keep sync-specs.mjs Node-stdlib-only — easier to debug in Pages build logs.
  • Phase 2 DE translation: pnpm docs:translate calls Claude with a DE style guide; humans review via PR.
  • Sub-system 12 owns the legal MD; this spec only links to it. Sub-system 01 owns the Terraform that creates the nowyourlink-docs Pages project and docs-internal Access application.

Should the synced spec pages render an “Edit on GitHub” link pointing to docs/superpowers/specs/… (source of truth) or to the synced copy under docs-site/src/content/docs/… (what the user is reading)? Source-of-truth is correct semantically but exposes the monorepo layout; synced copy is editable but the next sync would overwrite. Leaning source-of-truth; resolve in implementation PR.