Add docs example: dogfood flatbread with a mono, ASCII-styled Next.js site - #246
Add docs example: dogfood flatbread with a mono, ASCII-styled Next.js site#246tonyketcham wants to merge 2 commits into
Conversation
… site Add examples/docs, a Next.js 15 + Tailwind v4 site that reads its own content through flatbread. Markdown files under docs/ become a DocPage collection; the site reads them through the generated typed read API, so the docs eat the same dog food as any user app. - Symlink examples/docs/content/markdown/docs -> docs/ so the canonical guides stay the single source of truth. - Add frontmatter (id, title, section, order, summary, related) to the seven top-level guides so flatbread can model and sort them. - Build a monospaced, dark 'engineering paper' shell: one mono family, hairline borders, a single lime accent, and an AsciiRule component that renders box-drawing section breaks. - Add Motion.dev text reveals (MotionText staggers the hero headline word by word; MotionReveal fades section blocks in on scroll) and a shared layoutId nav marker that travels to the active page. - Wire a catch-all docs route with generateStaticParams and prev/next navigation, plus a landing page that lists every guide by section. - Pin the example to port 3001 so it can run alongside examples/nextjs, and add a root pnpm play:docs script. Change-Id: Ib3f45c8f22f3a9efbb19f6bc158d484f8529c373
|
Tick the box to add this pull request to the merge queue (same as
|
The Geist Mono CSS variable was applied to <body>, but the html element's font-family resolved --font-mono at :root, where --font-geist-mono was undefined. The whole site fell back to Times New Roman, breaking the monospaced requirement. Move the variable class to <html> so the font is defined at :root and inherited everywhere. Change-Id: I3bf947a79691c5910d6a80a2c2bf90e14f533a6e
|
The site is running. The cloud VM has no public port forwarding, so here are screenshots of the live dev server ( Landing page — animated hero (Motion.dev word-by-word reveal) + section index: Doc page ( Flatbread positioning doc page Glossary page ( To run it locally: pnpm install
pnpm play:docs
# open http://localhost:3001Note: a follow-up commit on this branch fixes a font bug — the Geist Mono variable was attached to |
There was a problem hiding this comment.
Review verdict
REQUEST_CHANGES — Consensus HIGHs on a false GraphQL dogfood contract (queries/docs.graphql claims the site reads those documents while runtime uses only createFlatbreadReadApi), missing example onboarding (examples/docs/README.md + undocumented play:docs), and an unenforced id/_slug routing contract, plus a non-empty coverage plan over new non-test source. No accepted BLOCKER: demote docs-and-positioning’s informal BLOCKER on GitHub-shaped .md links (dual-audience content; DX verified happy-path 200s). Release-discipline correctly clears the publish surface.
Consensus findings (priority)
- Dead GraphQL document surface (HIGH) —
.graphqloperations unused;read.tsdogfoods only the read API; sort claim does not match runtime. - Missing onboarding (HIGH) — no
examples/docs/README.md;play:docsabsent from CONTRIBUTING/AGENTS; ports 3001/5057 andpnpm buildprerequisite implicit. idvs_slugdual keying — params/getDocPageByIduseid; nav/hrefs use_slug; no invariant test.- Asymmetric GraphQL failure UX (MED) — home/Shell swallow errors into
[]; catch-all doc route can throw. - No automated net (MED–HIGH) — zero tests under
examples/docs; CI builds nextjs/sveltekit only.
Coverage plan (top)
graphqlFetchpositive/negative/timeout mocksgetAllDocPages/getDocPageByIdlist/find/null +id===_slug/ related resolves- Catch-all route smoke (empty slug, unknown id, known page, GraphQL down)
- Operation-path parity (wire documents or stop claiming they are read)
- Codegen drift + optional
pnpm --dir examples/docs buildin CI
Disputed
In-site .md / ../ links 404 on the dogfood site — real HIGH UX defect, not BLOCK (dual-audience GitHub markdown; happy path verified).
Reviewer scoreboard
| Perspective | Call | Signal |
|---|---|---|
| test-coverage-robustness | REQUEST_CHANGES | HIGH |
| docs-example-contracts | REQUEST_CHANGES | HIGH |
| dx-and-examples | APPROVE (gaps) | HIGH |
| docs-and-positioning | NEEDS WORK | MED |
| release-discipline | APPROVE | HIGH |
Perspectives: coverage, docs-example-contracts, dx-and-examples, docs-and-positioning, release-discipline. Models: Grok 4.5 High / Composer 2.5. Judge: /tmp/review-judge-final.md.
Sent by Cursor Automation: Flatbread PR Review
| @@ -0,0 +1,40 @@ | |||
| # GraphQL documents read by the docs site. Codegen includes these when | |||
There was a problem hiding this comment.
HIGH (consensus) — Comment says these documents are “read by the docs site,” but nothing imports GetAllDocPagesDocument / GetDocPageByIdDocument. Runtime uses only createFlatbreadReadApi in lib/read.ts.
Minimal fix: Wire the typed documents in the read path, or delete/relabel this header so dogfood does not teach a dead operation surface.
| ); | ||
|
|
||
| /** | ||
| * Every DocPage, sorted by `order`, with the summary fields the nav and |
There was a problem hiding this comment.
HIGH (consensus) — Comment claims “sorted by order,” but DocPage.all() has no sortBy/order (the unused .graphql query does). Callers in page.tsx / Shell sort client-side or not at all in a documented way.
Minimal fix: Execute the sorted document (or drop the sort claim and sort explicitly in one place) and add list/find/null tests.
|
|
||
| export async function generateStaticParams() { | ||
| const pages = await getOrderedPages(); | ||
| return pages.map((p) => ({ slug: [p.id] })); |
There was a problem hiding this comment.
HIGH (consensus) — generateStaticParams keys on frontmatter id while nav/index/related hrefs use _slug. Safe only while id === slugify(stem). Same GraphQL outage also throws here while home/Shell return [].
Minimal fix: Pick one canonical key for params, hrefs, and DocPage(id:); add route smoke for empty slug, unknown id, known page, and outage.
| .sort((a, b) => a.order - b.order); | ||
| } catch (error) { | ||
| console.error('Docs index failed to load:', error); | ||
| return []; |
There was a problem hiding this comment.
MED (consensus) — getPages swallows all errors into [], so a down GraphQL server looks like an empty docs site. Shell nav does the same.
Minimal fix: Surface a clear “Flatbread unreachable at :5057” empty state and cover success vs fetch-failure.
| "codegen": "flatbread codegen --watch", | ||
| "build": "flatbread start -- next build", | ||
| "start": "next start -p 3001", | ||
| "lint": "next lint" |
There was a problem hiding this comment.
HIGH (consensus) — No examples/docs/README.md (unlike examples/nextjs). lint (next lint) also fails with no ESLint config/deps — a trap for anyone who runs it.
Minimal fix: Add a README covering ports (Next 3001, GraphQL 5057), pnpm build prerequisite, symlink, and codegen; fix or remove the broken lint script.
| "lint:fix:prettier": "pretty-quick --staged", | ||
| "typecheck": "pnpm --filter @flatbread/explorer typecheck", | ||
| "play": "cd examples/nextjs && pnpm dev", | ||
| "play:docs": "cd examples/docs && pnpm dev", |
There was a problem hiding this comment.
HIGH (consensus) — play:docs is root-discoverable only here; CONTRIBUTING/AGENTS still document pnpm play (:3000) only. Concurrent play + play:docs both bind GraphQL 5057 (EADDRINUSE).
Minimal fix: Document play:docs (ports, pnpm build, mutual exclusion) in CONTRIBUTING/AGENTS; optionally add a CI/play:build peer for examples/docs.
|
|
||
| # Flatbread positioning | ||
|
|
||
| For installation and usage, see the [main README](../README.md). For |
There was a problem hiding this comment.
HIGH (disputed → not BLOCK) — Relative GitHub links (../README.md, ./glossary.md, later ../packages/…) 404 or miss anchors when the same file is rendered on the dogfood site at /docs/{id}.
Minimal fix: Keep GitHub-valid paths in source or rewrite/resolve them in the Doc renderer for /docs/{id} (and heading ids). Same pattern on the other six indexed guides.


… site
Add examples/docs, a Next.js 15 + Tailwind v4 site that reads its own content through flatbread. Markdown files under docs/ become a DocPage collection; the site reads them through the generated typed read API, so the docs eat the same dog food as any user app.
Change-Id: Ib3f45c8f22f3a9efbb19f6bc158d484f8529c373