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
| Job | Tool |
|---|---|
| Site | Docusaurus 3.10.2 (MDX, sidebars, faster build mode) |
| API reference | docusaurus-plugin-openapi-docs and theme 5.2.0, one spec per service |
| API specs | SmallRye OpenAPI through the opt-in Maven profile openapi-docs, at build time |
| Spec lint | Spectral 6.17.1 |
| C4 model | Structurizr DSL, exported to Mermaid by the Structurizr CLI |
| Flows | Mermaid sequence and state diagrams in the pages |
| Search | @easyops-cn/docusaurus-search-local, offline |
| Decisions | MADR 4.0 pages under docs/adr/ |
| Quality | markdownlint-cli2, Docusaurus broken-link checks set to throw, lychee for external links, Playwright and axe for browser checks |
Commands
Run these from docs-site/.
| Command | What it does |
|---|---|
npm ci | Install the pinned dependencies. |
npm run build | Internal build into build/, using the committed specs and diagrams. |
npm run build:public | Public build into build-public/, without the internal section, then checks that nothing withheld leaked. |
npm run serve | Serve the last build/ on port 3100. |
npm run lint:md | Lint the Markdown. |
bash scripts/build.sh | Regenerate the specs and the C4 export (needs JDK 21), then build. |
bash scripts/generate-c4.sh | Re-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:
| Site | Address | Content |
|---|---|---|
| Public | docs.rtih.peoplewave.in | The public build. No internal section. Open to anyone. |
| Internal | docs-internal.rtih.peoplewave.in | The 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.