Scrum4Me/app/(app)/manual/[[...slug]]/page.tsx
Janpeter Visser bd7478861b
PBI-58: Developer manual + in-app /manual page (#148)
* docs(PBI-58): add developer manual chapters under docs/manual/

Adds a 7-file English-language manual targeted at new human contributors:
index, overview, statuses & transitions (with mermaid state diagrams),
git workflow, MCP integration, docker, and troubleshooting. The manual
is the *map* — it cross-references existing runbooks/ADRs/architecture
docs rather than duplicating their content.

Regenerates docs/INDEX.md and validates with check-doc-links.mjs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(PBI-58): add markdown rendering deps + manual:build script

Adds mermaid, rehype-slug, rehype-autolink-headings for the in-app
/manual page. Wires manual:build into prebuild so production builds
always regenerate the chapter TOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(PBI-58): codegen script for in-app manual TOC

scripts/build-manual.mjs walks docs/manual/, parses YAML front-matter,
strips it from the body, and emits lib/manual.generated.ts with a typed
ManualEntry[] containing slug, title, description, filePath, and the
embedded markdown body. Pure Node 20, mirrors generate-docs-index.mjs.

Inlining the markdown at build time keeps runtime serverless functions
free of filesystem reads, which avoids whole-project NFT tracing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(PBI-58): /manual route renders developer manual chapters in-app

Catch-all route at app/(app)/manual/[[...slug]]/page.tsx with
generateStaticParams covering every TOC entry. Server-side
MarkdownView uses react-markdown with remark-gfm, rehype-slug, and
rehype-autolink-headings; mermaid code blocks are routed to a
client-only MermaidBlock that dynamic-imports mermaid on mount.

ManualSidebar (client) reads the typed TOC and highlights the active
chapter via usePathname.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(PBI-58): add Manual link to main nav bar

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:00:10 +02:00

42 lines
1.1 KiB
TypeScript

import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { getManualChapter, getManualToc } from '@/lib/manual-server'
import { MarkdownView } from '../_components/markdown-view'
type Params = { slug?: string[] }
export async function generateStaticParams(): Promise<Params[]> {
return getManualToc().map((entry) => ({
slug: entry.slug.length > 0 ? [...entry.slug] : undefined,
}))
}
export async function generateMetadata({
params,
}: {
params: Promise<Params>
}): Promise<Metadata> {
const { slug = [] } = await params
const chapter = getManualChapter(slug)
if (!chapter) return { title: 'Manual — not found' }
return {
title: `${chapter.entry.title} — Scrum4Me Manual`,
description: chapter.entry.description.slice(0, 200),
}
}
export default async function ManualChapterPage({
params,
}: {
params: Promise<Params>
}) {
const { slug = [] } = await params
const chapter = getManualChapter(slug)
if (!chapter) notFound()
return (
<div className="mx-auto w-full max-w-3xl px-6 py-8">
<MarkdownView markdown={chapter.body} />
</div>
)
}