Skip to content

🌱 refactor(nav): move sidebar navigation from page-map.ts into per-project nav.yaml data files - #7096

Merged
hivecommons-hive[bot] merged 5 commits into
mainfrom
refactor/nav-yaml-data-files-7080
Sep 26, 2026
Merged

hivecommons-hive[bot] merged 5 commits into
mainfrom
refactor/nav-yaml-data-files-7080

Conversation

@clubanderson

Copy link
Copy Markdown
Member

📌 Fixes

Fixes #7080


📝 Summary of Changes

src/app/docs/page-map.ts hard-coded ten per-project NAV_STRUCTURE_* literals (663 LOC). Sidebar navigation is now data: each project's nav lives in a nav.yaml next to the content it describes, and page-map.ts (251 LOC) loads and validates it at build time.

nav.yaml defines
docs/content/nav.yaml KubeStellar (PROJECTS.kubestellar.navPath)
docs/content/{a2a,kubeflex,multi-plugin,kubestellar-mcp,console}/nav.yaml each other project (PROJECTS[id].navPath)
docs/content/{contributing,community,news}/nav.yaml the three cross-project sections (GENERAL_SECTIONS)

The YAML uses the same { title, items: [{ Title: path.md }] } schema as the old literals (and mkdocs nav:), generated verbatim from them.

buildPageMap() output for all six projects is byte-identical before and after — verified by snapshotting the full pageMap / routeMap / filePaths on main and on this branch and cmp-ing the JSON.


Changes Made

  • Nav data files — nine nav.yaml files under docs/content/, each with a header comment describing the schema and path base.
  • PROJECTS[projectId].navPath (ProjectConfig) — mandatory field matching the contentPath/basePath pattern from [architect] page-map.ts has 3 parallel switch(projectId) shadows of PROJECTS with silent default arms #7037, so a new ProjectId fails to compile until it supplies a nav (issue point 4; the old NAV_STRUCTURE_BY_PROJECT lookup is gone).
  • src/lib/nav.ts — schema types, validateNavSections / parseNavYaml / loadNavFile. A missing or malformed nav throws NavFileError naming the file, section and item (Invalid sidebar nav file docs/content/console/nav.yaml: section[2] "Guides".items[1] "Bad": value must be a path string or a list of items) — a build error rather than an undefined spread. Nextra-free so scripts/ can reuse it under plain tsx.
  • One definition of "general section" — GENERAL_SECTIONS + isGeneralSectionFile replace the four hand-repeated startsWith('contributing/') || startsWith('community/') || startsWith('news/') triples and the ['Contributing','Community','News'] title list (issue point 3). Top-level anchoring under /docs/<slug> is still by title, but the title set is derived from the loaded general navs.
  • scripts/check-internal-links*.ts — navSourcesFor(PROJECTS, GENERAL_SECTIONS) + parseNavStructure() read the same nav.yaml files the site loads, replacing the regex over page-map.ts source and the hand-maintained PROJECT_FOR_NAV table (issue follow-up 1).
  • js-yaml moved from devDependencies to dependencies — page-map runs in the search API route at request time. Version unchanged (^5.2.2; ships its own types).
  • Docs — CONTRIBUTING.md and docs/content/contributing/documentation/docs-structure-inc.md now describe nav.yaml (schema, examples, workflows) instead of NAV_STRUCTURE.
  • Tests

Checklist

  • I have reviewed the project's contribution guidelines.
  • I have performed a self-review of my changes.
  • I have written unit tests for the changes (if applicable).
  • I have updated the documentation (if applicable).
  • I have tested the changes locally and ensured they work as expected.
  • All CI checks are passing.

Security Considerations

  • Dependencies — js-yaml was already a devDependency at the same version; only its section in package.json changed. yaml.load (safe schema by default in js-yaml ≥4) is used; no loadAll/custom types.

Screenshots or Logs (if applicable)

$ npm run type-check   # clean
$ npm run lint         # 0 errors (103 pre-existing warnings, unchanged)
$ npm test             # Test Files 138 passed, Tests 1554 passed
$ npm run lint:md      # 0 issues in 226 files
$ npm run check-links  # 554 links, 1048 routes, 0 broken
$ npm run build        # ✓ Compiled successfully

👀 Reviewer Notes

  • Link-checker behaviour change (a fix): the old regex NAV_STRUCTURE_([A-Z_]+) captured A for NAV_STRUCTURE_A2A (no digit in the class), so the A2A nav was silently skipped; CONTRIBUTING/COMMUNITY/NEWS had no PROJECT_FOR_NAV entry and were skipped too. Compared against main, the old nav-alias route set is a strict subset of the new one: 0 routes lost, 90 added, all from A2A and the three shared navs. Route count in the output went 973 → 1048 for that reason.
  • Kept, deliberately: the top-level section anchoring is by title, so kubeflex's own Community section still anchors its folder under /docs/community (its children were already under /docs/kubeflex/community/…). page-map-routes.test.ts pins this; changing it is out of scope for a behaviour-preserving refactor — happy to file a follow-up.
  • Deviation from the issue text: the shared-section navs sit in docs/content/<section>/nav.yaml (next to the pages) rather than docs/content/_shared/<section>/nav.yaml, so authors edit the nav in the directory they're already in. The kubestellar nav is at docs/content/nav.yaml (= its contentPath) rather than docs/content/kubestellar/nav.yaml, because its entries are relative to docs/content/; the invariant navPath === contentPath + '/nav.yaml' then holds uniformly and is tested.
  • Not done here (issue follow-ups 3): generate-shared-config.ts validating that every MDX under docs/content/<project>/ is listed in nav.yaml or unlisted: true. The loader now makes that a small follow-up.
  • package-lock.json churn is npm install --package-lock-only re-hoisting js-yaml 4.x under @eslint/eslintrc now that 5.x is a prod dep; npm ci verified clean.

— hive: backend=copilot model=claude-fable-5.1

…yaml data files

page-map.ts hard-coded ten per-project NAV_STRUCTURE_* literals (663 LOC).
Each project's sidebar now lives in a nav.yaml next to the content it
describes, and page-map.ts loads and validates it at build time.

- docs/content/nav.yaml (KubeStellar) and docs/content/<project>/nav.yaml
  for a2a, kubeflex, multi-plugin, kubestellar-mcp and console, generated
  verbatim from the former literals (same {title, items} schema).
- docs/content/{contributing,community,news}/nav.yaml for the three
  cross-project sections, appended to every project's nav in that order.
- PROJECTS[projectId].navPath (ProjectConfig) points at the project's nav,
  matching the contentPath/basePath pattern from #7037, so a new ProjectId
  fails to compile until it supplies a nav.
- src/lib/nav.ts: schema, validator and loader (nextra-free so scripts can
  reuse it). A missing or malformed nav.yaml throws NavFileError naming the
  file, section and item — a build error instead of an undefined spread.
- GENERAL_SECTIONS / isGeneralSectionFile replace the four hand-repeated
  startsWith('contributing/') || ... triples in page-map.ts. Top-level
  sections are anchored under /docs by title, derived from the loaded
  general navs rather than a hard-coded ['Contributing','Community','News'].
- js-yaml moves from devDependencies to dependencies: page-map runs in the
  search API route at request time.

buildPageMap() output for all six projects is byte-identical before and
after (verified by snapshotting the full pageMap/routeMap/filePaths).

Tests: src/__tests__/nav.test.ts covers every rejection path of the
loader (100% lines, 97% branches) and asserts every real nav entry points
at an existing page; versions.shape-invariants pins navPath ==
<contentPath>/nav.yaml and the file existing; the source drift-guard now
pins the single GENERAL_SECTIONS definition instead of the literal triples.

Fixes #7080

Hive-Run: #7080
Hive-Plan: architect/page-map-nav-data-files
Hive-Spec: kubestellar-docs-nav#7080
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
…-parsing page-map.ts

The link checker extracted NAV_STRUCTURE_* blocks from page-map.ts source
with a regex and mapped them through a hand-maintained PROJECT_FOR_NAV
table. That table silently missed A2A (the `[A-Z_]+` name pattern cannot
match `A2A`) and never included the contributing/community/news navs, so
their nav-slug routes were absent from the route set.

Now navSourcesFor(PROJECTS, GENERAL_SECTIONS) lists every nav.yaml the
site loads, parseNavStructure() validates it with the same src/lib/nav
loader the build uses, and navAliasEntries() applies buildPageMap's
title->slug rule. No parallel table to keep in sync.

Verified against main: the old route set is a strict subset of the new
one (0 routes lost; 90 added, all from a2a and the three shared navs).
`npm run check-links` still reports 0 broken links.

Hive-Run: #7080
Hive-Plan: architect/page-map-nav-data-files
Hive-Spec: kubestellar-docs-nav#7080
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
CONTRIBUTING.md and the docs-structure page told authors to edit
NAV_STRUCTURE in src/app/docs/page-map.ts. Update every reference,
example and workflow to the nav.yaml files and their schema.

Hive-Run: #7080
Hive-Plan: architect/page-map-nav-data-files
Hive-Spec: kubestellar-docs-nav#7080
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Copilot AI lite review requested due to automatic review settings September 26, 2026 15:26
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Sep 26, 2026
@kubestellar-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign kproche for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@netlify

netlify Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for kubestellar-docs ready!

Name Link
🔨 Latest commit ffc858d
🔍 Latest deploy log https://app.netlify.com/projects/kubestellar-docs/deploys/6ab8203184d68c0008280fcc
😎 Deploy Preview https://deploy-preview-7096--kubestellar-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added documentation Improvements or additions to documentation frontend typescript labels Sep 26, 2026
@kubestellar-prow kubestellar-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Sep 26, 2026
@github-actions github-actions Bot added contributing pages dependencies Pull requests that update a dependency file json yaml labels Sep 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate issues remain in navigation alias generation, CI path coverage, and filesystem error handling.

Review effort: Lite
Findings: None

What changed in this PR

Refactors sidebar navigation from TypeScript literals into validated per-project nav.yaml files.

Changes:

  • Adds YAML parsing, validation, and project navPath configuration.
  • Updates page-map generation and internal-link checking.
  • Adds navigation data, tests, dependency updates, and documentation.
File Summary
src/​lib/​nav.ts Adds navigation schema, validation, and loading; filesystem errors should be wrapped as NavFileError.
src/​config/​versions/​types.ts Adds required navPath configuration.
src/​config/​versions/​lookup.ts Defines project navigation paths.
src/​app/​docs/​page-map.ts Builds page and route maps from YAML navigation.
src/​__tests__/​versions.shape-invariants.test.ts Tests navigation path invariants.
src/​__tests__/​page-map-project-arms.test.ts Updates project navigation coverage.
src/​__tests__/​page-map-general-section-arms.test.ts Tests shared navigation sections.
src/​__tests__/​page-map-defensive-arms-drift.test.ts Guards against navigation implementation drift.
src/​__tests__/​nav.test.ts Tests parsing, validation, loading, and real navigation files.
src/​__tests__/​check-internal-links-helpers.test.ts Tests YAML-based link helper behavior.
scripts/​check-internal-links.ts Reads navigation YAML sources for link checking.
scripts/​check-internal-links-helpers.ts Generates navigation aliases; unresolved issues affect nested folder paths, section context, and CI path filters.
scripts/​check-internal-links-helpers.test.ts Tests navigation alias generation.
package.json Promotes js-yaml to a runtime dependency.
package-lock.json Updates dependency lock data.
docs/​content/​news/​nav.yaml Defines News navigation.
docs/​content/​nav.yaml Defines KubeStellar navigation.
docs/​content/​multi-plugin/​nav.yaml Defines Multi-plugin navigation.
docs/​content/​kubestellar-mcp/​nav.yaml Defines KubeStellar MCP navigation.
docs/​content/​kubeflex/​nav.yaml Defines KubeFlex navigation.
docs/​content/​contributing/​nav.yaml Defines Contributing navigation.
docs/​content/​contributing/​documentation/​docs-structure-inc.md Documents the YAML navigation structure.
docs/​content/​console/​nav.yaml Defines Console navigation.
docs/​content/​community/​nav.yaml Defines Community navigation.
docs/​content/​a2a/​nav.yaml Defines A2A navigation.
CONTRIBUTING.md Documents navigation authoring workflows.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

Copy link
Copy Markdown
Contributor

📖 Preview Links

The following documentation pages were changed in this PR:

Status Page Preview Link
📝 modified docs-structure-inc View preview

🔗 Full preview site

- loadNavFile now wraps readFileSync failures (EISDIR, EACCES, ...) in
  NavFileError naming the file, matching the missing-file and YAML-parse
  branches; test added.
- check-internal-links workflow path filters now include
  scripts/check-internal-links-helpers.ts, src/lib/nav.ts and
  src/config/versions/** (the old src/config/versions.ts path no longer
  exists after the versions/ split) so nav/link-check changes trigger it.

Addresses Copilot review summary on #7096.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@clubanderson

Copy link
Copy Markdown
Member Author

Pushed d50296b for the two concrete items in the Copilot review summary:

  • Filesystem error handling — loadNavFile now wraps readFileSync failures in NavFileError (naming the file) like the missing-file and YAML-parse branches already did; test added for the EISDIR case.
  • CI path coverage — check-internal-links.yml path filters now include scripts/check-internal-links-helpers.ts, src/lib/nav.ts and src/config/versions/** (the previous src/config/versions.ts entry pointed at a file that no longer exists).

On alias generation: navAliasEntries deliberately over-approximates (every entry is emitted under every section slug plus the bare form) to mirror the two validRoutes.add() calls in the checker; this is documented in the function's doc block and covered by check-internal-links-helpers.test.ts. If there is a specific nested-folder case that mis-resolves, an inline comment pointing at it would help — none were left on the diff.

vitest (nav + helpers, 99 tests), tsc --noEmit and eslint are green on this head.

@github-actions github-actions Bot added the ci-cd label Sep 26, 2026
@kubestellar-prow

Copy link
Copy Markdown

@clubanderson: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-kubestellar-docs-test d50296b link true /test pull-kubestellar-docs-test

Full PR test history

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@hivecommons-hive
hivecommons-hive Bot merged commit e3a4d29 into main Sep 26, 2026
16 of 21 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the refactor/nav-yaml-data-files-7080 branch September 26, 2026 19:42
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

Check out what's new:

Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey

hivecommons-hive Bot added a commit that referenced this pull request Oct 2, 2026
…7204)

buildPageMap()/getNavStructure() (src/app/docs/page-map.ts) load and parse
every project's sidebar nav.yaml at request time from SlugLayout (every
/docs/<project>/* page render) and from /api/search, not just at build
time, since the nav.yaml data-file refactor (#7096). A missing or
malformed nav.yaml throws NavFileError there uncaught: page renders hit
only the client-side global-error.tsx boundary (console.error in the
visitor's browser), producing no server log and no
docs_api_requests_total sample, since that metric is wired only into
/api/* route handlers. Meanwhile /api/healthz kept reporting 200 the
whole time, because it only checked that docs/content exists and is
non-empty -- the content directory itself is untouched by a bad
nav.yaml.

Extend the readiness check to also call loadNavFile() (src/lib/nav.ts)
for every project's navPath and the shared contributing/community/news
navs, returning 503 naming the offending file on failure. This gives an
orchestrator a way to detect and route around an instance with a broken
nav.yaml before it serves a broken sidebar/search to users, instead of
only finding out from a browser console log.

Cross-references the dependency in runbooks/deploy-rollback.md.

Signed-off-by: operations <operations@hive.kubestellar.io>
Co-authored-by: operations <operations@hive.kubestellar.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/scanner Agent scanner label ci-cd contributing dco-signoff: yes Indicates the PR's author has signed the DCO. dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation frontend json pages size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. typescript yaml

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[architect] page-map.ts hard-codes 10 per-project NAV_STRUCTURE arrays (663 LOC) — move nav to per-project data files

2 participants