feat(docs): mkdocs-style documentation site served at /docs

Full documentation hub replacing the release-notes-only view:
- Handbook pages (docs/handbook) for all features and admin/betrieb
- API reference generated from lib/api-spec/openapi.yaml via
  scripts/src/generate-docs.mjs (replaces sync-release-docs.mjs):
  endpoints, schemas/fields, search index, per-release snapshots
- mkdocs layout: sidebar nav, right TOC with scrollspy, search overlay,
  version dropdown, repo link
- FieldHelp (?) buttons in forms linking to reference field docs
- v0.7.0 release notes backfilled, v0.8.0 release notes added
This commit is contained in:
opencode
2026-08-03 22:15:54 +02:00
parent 520f917723
commit 6c92b6358d
29 changed files with 7545 additions and 264 deletions
@@ -38,9 +38,30 @@ function buildCrumbs(location: string, t: TFunction): Crumb[] {
} else if (location.startsWith("/analytics")) {
crumbs.push({ label: t("nav.analytics") });
} else if (location.startsWith("/docs")) {
crumbs.push({ href: "/docs", label: t("nav.docs") });
const match = location.match(/^\/docs\/(.+)$/);
if (match) crumbs.push({ label: match[1] });
crumbs.push({ href: "/docs", label: t("docs.title") });
const m = location.replace(/^\/docs\/?/, "");
if (m.startsWith("handbook/")) {
crumbs.push({ href: "/docs/handbook", label: t("docs.guides") });
const slug = m.replace(/^handbook\//, "").split("#")[0];
if (slug) crumbs.push({ label: slug });
} else if (m.startsWith("reference/")) {
crumbs.push({ href: "/docs/reference/endpoints", label: t("docs.reference") });
const rest = m.replace(/^reference\//, "").split("#")[0];
if (rest.startsWith("schemas/")) {
crumbs.push({ label: t("docs.schemas") });
const name = rest.replace(/^schemas\//, "");
if (name) crumbs.push({ label: name });
} else {
const tag = rest.replace(/^endpoints\//, "");
if (tag) crumbs.push({ label: tag });
}
} else if (m.startsWith("releases/")) {
crumbs.push({ href: "/docs/releases", label: t("docs.releases") });
const version = m.replace(/^releases\//, "").split("#")[0];
if (version) crumbs.push({ label: version });
} else if (m) {
crumbs.push({ label: m });
}
} else if (location.startsWith("/login")) {
crumbs.push({ label: t("auth.signIn") });
}