Skip to main content

How these docs are built

The site is Docusaurus 3 with the Mermaid theme, offline local search, and docusaurus-plugin-openapi-docs for the API reference. The architecture diagrams are exported from a Structurizr model. Exact versions are pinned in docs-site/package.json and listed in docs-site/TOOLS.md. Use Node 22 (docs-site/.nvmrc).

Tools​

JobTool
SiteDocusaurus 3.10.2 (MDX, sidebars, faster build mode)
API referencedocusaurus-plugin-openapi-docs and theme 5.2.0, one spec per service
API specsSmallRye OpenAPI through the opt-in Maven profile openapi-docs, at build time
Spec lintSpectral 6.17.1
C4 modelStructurizr DSL, exported to Mermaid by the Structurizr CLI
FlowsMermaid sequence and state diagrams in the pages
Search@easyops-cn/docusaurus-search-local, offline
DecisionsMADR 4.0 pages under docs/adr/
Qualitymarkdownlint-cli2, Docusaurus broken-link checks set to throw, lychee for external links, Playwright and axe for browser checks

Commands​

Run these from docs-site/.

CommandWhat it does
npm ciInstall the pinned dependencies.
npm run buildInternal build into build/, using the committed specs and diagrams.
npm run build:publicPublic build into build-public/, without the internal section, then checks that nothing withheld leaked.
npm run serveServe the last build/ on port 3100.
npm run lint:mdLint the Markdown.
bash scripts/build.shRegenerate the specs and the C4 export (needs JDK 21), then build.
bash scripts/generate-c4.shRe-export the C4 diagrams only.

Keeping the specs current​

scripts/generate-openapi.sh runs the Maven profile openapi-docs for each service. SmallRye OpenAPI stores the schema during the Quarkus build. No service is started and nothing is fetched from a running environment. Run it with JAVA_HOME pointing at JDK 21, then commit the changed files in openapi/generated/.

scripts/apply-overlays.mjs adds summaries, tag descriptions, the authentication schemes and the public operations from openapi/overlays/. It fails if an overlay names an operation that no longer exists. When a service adds or removes a public path in quarkus.http.auth.permission.public.paths, update that service's overlay in the same change. The LMS and onboarding services have public operations today.

The frontend routes are written by hand in openapi/handwritten/frontend.yaml. Update it in the same change as any route handler under frontend/src/app/api.

scripts/lint-openapi.sh runs Spectral. It fails only when a document is invalid and writes the lint report.

Keeping the diagrams current​

architecture/workspace.dsl is the single source for the C4 diagrams. Edit it, run scripts/generate-c4.sh, and commit the changed partials in docs/architecture/c4/. The script downloads the Structurizr CLI into .tools/ (git-ignored) and checks its SHA-256. Every element description should trace to a file in the repository. An element that could not be confirmed is tagged Unverified and drawn dashed.

Sequence and state diagrams are written by hand as Mermaid blocks inside the pages. Wrap each in the Diagram component with a title and a text description, which is the alt text for the diagram.

How content is verified​

Pages are written from the code, manifests and reports in the repository. Each page ends with a Sources: line naming them. A statement that could not be confirmed is marked unverified in the text. Observations of the live cluster are read-only and carry a date. Secret values, tokens and passwords never appear. Names of Secrets are given only where the design needs them.

Adding a decision record​

Copy ADR 0000, take the next number, fill in the MADR sections and add it to the index.

Internal and public builds​

DOCS_INTERNAL=false is the single flag. It excludes docs/internal/, removes navigation to it, and strips every <InternalOnly> block at compile time. Put detail that should not be public either in docs/internal/ or inside an <InternalOnly> block. Terms that must never appear in a public build are listed in scripts/internal-terms.txt. scripts/check-public-build.sh searches the public build, including the search index, for each term. Add a term whenever an internal page introduces new vocabulary.

Hosting​

The docs are published as two static sites, each served by an unprivileged nginx image on the production cluster:

SiteAddressContent
Publicdocs.rtih.peoplewave.inThe public build. No internal section. Open to anyone.
Internaldocs-internal.rtih.peoplewave.inThe full build, protected by a password at the ingress and kept out of search engines.

The image recipe and the web server settings (security headers, caching, health endpoint) are in docs-site/deploy/. The cluster manifests are in infra/k8s/docs-site.yaml.