Skip to content

Documentation Maintenance

This document gathers the maintenance procedures for all parts of the documentation portal. Use as a reference when adding, modifying, or removing content.


Build Flow Overview

text
docs:rtm   →   docs:openapi   →   docs:typedoc   →   vitepress build
   │               │                   │                   │
   │               │                   │                   └── final site
   │               │                   │                       at docs/.vitepress/dist/
   │               │                   │
   │               │                   └── docs/reference/typedoc/
   │               │                   └── docs/public/reference/typedoc/
   │               │
   │               └── docs/reference/api/openapi.json
   │               └── docs/public/reference/api/openapi.json

   └── docs/quality/rtm.md

Phase 1 — VitePress Portal

How to add a new page to the portal

  1. Create the .md file in the corresponding folder (e.g. docs/frontend/my-page.md)
  2. Add YAML frontmatter (see pattern below)
  3. Add the page to the sidebar in docs/.vitepress/config.mts:
    • pt-BR: in the ptSidebar section (links without /en/ prefix)
    • en-US: in the enSidebar section (links with ${enPrefix}/ prefix)
  4. Run pnpm docs:build — VitePress validates internal links

Standard frontmatter

Every markdown document in the portal must start with:

yaml
---
title: Page Name
description: One-line summary of the page's purpose.
status: published | draft
owner: engineering | product | design
lastReviewed: 2026-06-10
---

How to change navigation

  • Top navbar: edit themeConfig.nav inside locales.root.themeConfig (pt-BR) and locales.en.themeConfig (en-US) in config.mts
  • Sidebar: edit the ptSidebar or enSidebar arrays in the same file
  • Footer: edit themeConfig.footer within each locale

i18n Locale

The portal has two locales: root (pt-BR, default) and en (en-US).

  • docs/en/ is a hand-maintained English translation layer — every .md there is a real translation, not a byte copy of docs/. There is no copy script; scripts/copy-docs-en.sh was retired because it rm -rf'd docs/en/ and would have destroyed the hand-written translations.
  • When a root page changes, update its docs/en/ counterpart in the same change, then refresh the freshness pin with pnpm docs:i18n:commit -- <paths> (see "Source Language Policy" and "en mirror policy" below).
  • To add locale-specific content, create the file only in the desired locale folder.

Source Language Policy

  • The root docs (docs/) are the canonical pt-BR source. The en locale is a derived translation layer, never a co-author.
  • default_lang_commit semantics: each docs/en/ page records in its frontmatter the commit hash of the root (pt-BR) page it was translated from. An en page is drifted when its pin is older than the current commit of the root file; refreshing the pin (pnpm docs:i18n:commit -- <paths>) declares the translation is in sync again. A # patched marker allows mechanical fixes (link retargets, build fixes) without a content resync.
  • Documented exceptions: root pages whose body is still authored in English, pending pt-BR conversion (tracked in the v1 i18n backlog): docs/index.md, docs/maintenance.md (this guide), docs/community/security-policy.md, docs/community/code-of-conduct.md. These pages are exempt from the "root = pt-BR" rule until converted.

en mirror policy

The docs/en mirror follows the no-partial policy (Kubernetes/MDN model, see spec #588), enforced by scripts/check-i18n.sh in the CI docs job and in pnpm docs:check:

  • Orphan — an en page without a root counterpart fails (delete the en page).
  • Stub — an en page byte-identical to its root counterpart fails: it is an untranslated pt-BR page served under /en (translate it or delete it).
  • Missing — a root page without an en counterpart fails, unless it is exempted by a glob in docs/en/.i18n-exempt (internal-only docs: analysis/**, research/**, roadmap/**, big-fat-refactor-01/**, individual ADRs and SDD specs, internal audits/reference pages).
  • Pin — an en page without default_lang_commit in its frontmatter fails.
  • Drift — an en page whose pin is older than the root file's current commit is reported as drifted (non-blocking warning) and gets drifted_from_default: true set in its frontmatter, which exempts it from the lychee dead-link check until resynced.

Workflow when a root page changes:

  1. Update the translation in docs/en/.
  2. Refresh its pin: pnpm docs:i18n:commit -- product/prd (or all pages: pnpm docs:i18n:commit).
  3. pnpm docs:check must pass locally before pushing (CI enforces the same gate).

Adding a new page to the portal in pt-BR? Add the English translation in the same change — the missing check will block otherwise. Adding an internal-only pt-BR doc? Add a glob to docs/en/.i18n-exempt instead of a translation.

Commands

CommandAction
pnpm docs:devDevelopment server (hot-reload)
pnpm docs:buildFull production build
pnpm docs:previewBuild preview
pnpm docs:lintmarkdownlint on all docs (incl. docs/en)
pnpm docs:i18nen-mirror policy check (check-i18n.sh)
pnpm docs:i18n:commitRefresh default_lang_commit pins (check-i18n.sh commit HEAD)
pnpm docs:linkslychee dead-link check on the built site (drifted pages exempt)
pnpm docs:stalenesslastReviewed staleness warning (incl. docs/en)
pnpm docs:checklint + i18n + build (what the CI docs job runs, plus lychee/staleness)

Phase 2 — Editorial Taxonomy

Folder structure

text
docs/
├── index.md                  ← Portal landing page
├── getting-started/          ← Onboarding for new contributors
│   ├── overview.md
│   ├── quickstart.md
│   ├── repository-structure.md
│   └── contributor-workflow.md
├── product/                  ← Business vision and product requirements
│   ├── index.md
│   ├── prd.md
│   ├── business-rules.md
│   ├── roles-and-permissions.md
│   ├── scope.md
│   └── success-criteria.md
├── architecture/             ← Architecture and design
│   ├── index.md
│   ├── srs.md
│   ├── sdd.md
│   ├── context-map.md
│   ├── domain-model.md
│   ├── sync-architecture.md
│   ├── auth-architecture.md
│   └── adr/                  ← Architectural decisions (individual files)
│       ├── index.md
│       ├── ADR-0001.md
│       └── ...
├── frontend/                 ← Frontend SPA documentation
│   ├── index.md
│   ├── app-overview.md
│   ├── offline-mode.md
│   ├── import-export.md
│   ├── reports.md
│   └── ui-flows.md
├── workers/                  ← Backend documentation
│   ├── index.md
│   ├── workers-overview.md
│   ├── api-overview.md
│   ├── api-guide.md          ← Guide on how to add routes
│   ├── auth.md
│   ├── idempotency.md
│   ├── d1-schema.md
│   └── legacy-fastify.md
├── operations/               ← Operations and deployment
│   ├── index.md
│   ├── environments.md
│   ├── deployment.md
│   ├── migrations.md
│   ├── seed.md
│   ├── backup-restore.md
│   ├── security.md
│   ├── lgpd.md
│   └── troubleshooting.md
├── quality/                  ← Quality and testing
│   ├── index.md
│   ├── mtp.md
│   ├── rtm.md                ← Automatically generated (csv → md)
│   ├── production-readiness-gates.md
│   ├── hardening-backlog.md
│   ├── test-execution-handbook.md
│   └── testing-patterns.md
├── reference/                ← Technical reference
│   ├── index.md
│   ├── api/
│   │   ├── index.md
│   │   ├── api-contract.md
│   │   └── openapi.json      ← Automatically generated
│   ├── typedoc/              ← Automatically generated (gitignored)
│   ├── schemas.md
│   ├── permissions.md
│   ├── data-dictionary.md
│   └── extending-student-fields.md
├── community/                ← Community documents
│   ├── index.md
│   ├── contributing.md
│   ├── security-policy.md
│   ├── code-of-conduct.md
│   └── changelog.md
├── agents/                   ← Internal Reasonix workflow docs (outside portal)
├── archive/                  ← Preserved obsolete documents
└── RTM.csv                   ← Source for rtm.md generation

Rules

  1. Each section must have an index.md with overview and link list
  2. Links between documents use relative markdown paths (../product/prd.md)
  3. The VitePress sidebar is the source of truth for navigation — keep it in sync
  4. docs/agents/ contains internal Reasonix workflow documentation — do not link in the portal
  5. docs/archive/ contains obsolete documents preserved for historical reference

How to move or rename a document

  1. Move/rename the file
  2. Update the sidebar in docs/.vitepress/config.mts (in both ptSidebar and enSidebar sections)
  3. Update internal links in other documents that pointed to the old path
  4. Update REDIRECT.md or third-party links (README.md, CONTEXT-MAP.md, AGENTS.md, REASONIX.md)
  5. Run pnpm docs:build to check for dead links

Phase 3 — OpenAPI / Live API

See the full guide in API Guide.

Summary flow

  1. Add the handler in workers/src/routes/
  2. Import and register in workers/src/router.ts (via route() helper with declarative middlewares)
  3. Add entry in scripts/openapi-registry.ts (with Zod schema, example, auth)
  4. Run pnpm docs:openapi to validate coverage and generate openapi.json

Automatic validation

The scripts/generate-openapi.ts script verifies that every route in router.ts has a corresponding entry in the registry. If missing, the build fails with:

text
Route POST /api/v1/customers is NOT documented in openapi-registry.ts

Files

FilePurposeEditable?
scripts/openapi-registry.tsRegistry with schemas, examples, and metadata for each route✅ Yes
scripts/generate-openapi.tsOpenAPI 3.1 generatorRarely
docs/reference/api/openapi.jsonGenerated spec (source)❌ Generated
docs/public/reference/api/openapi.jsonSpec for VitePress build❌ Generated

Phase 4 — TypeDoc

How to add a new entry point

  1. Edit typedoc.json, add the file path to entryPoints
  2. Edit typedoc.tsconfig.json, add to include
  3. Run pnpm docs:typedoc to generate
  4. If you want a sidebar link, add it in docs/.vitepress/config.mts under Reference > TypeDoc (sub-item)

Common error resolution

ErrorCauseSolution
TS2322: Uint8Array not assignable to BufferSourceWorkers-specific runtime typeExclude the file from entry points
TS2339: timingSafeEqual does not existWorkers API not available in standard TypeScriptExclude the file from entry points
Module has no exported memberPath alias not resolvedAdd to paths in typedoc.tsconfig.json

Files

FilePurposeEditable?
typedoc.jsonTypeDoc config (entry points, output)✅ Yes
typedoc.tsconfig.jsonTSConfig for TypeDoc to resolve workspace packagesRarely
scripts/generate-typedoc.shScript that generates + copies to docs/public/Rarely
docs/reference/typedoc/Generated HTML❌ Generated (gitignored)
docs/public/reference/typedoc/Copy for VitePress build❌ Generated (gitignored)

Current entry points

Entry PointContent
packages/permissions/index.tsPERMISSIONS, UserRole, Permission
packages/schemas/src/index.tsAll Zod schemas + enums + utils (HttpError, sanitizePayload)
workers/src/modules/auth/sessionTokens.tssignAccessToken, verifyAccessToken, createRefreshToken, hashRefreshToken
workers/src/modules/idempotency.tspayloadHash, isSamePayloadHash
workers/src/schemas.tsHTTP API schemas (auth, student, attendance, sync)

Phase 5 — RTM (Requirement Traceability Matrix)

How to update requirements

  1. Edit docs/RTM.csv (spreadsheet with 6 columns: RequirementID, Category, RequirementSummary, PrimarySuite, TestCaseRefs, CoverageStatus)
  2. Run pnpm docs:rtm to regenerate docs/quality/rtm.md
  3. Run pnpm docs:build to verify

CSV fields

ColumnExampleRequired
RequirementIDFR-001Yes
CategoryFunctionalYes
RequirementSummarySupport all defined rolesYes
PrimarySuiteRBACYes
TestCaseRefsTC-RBAC-001;TC-RBAC-002Yes (separated by ;)
CoverageStatusPlanned, Implemented, Passed, FailedYes

New requirements

  • IDs follow the format <PREFIX>-<NUMBER>: FR-, NFR-, DR-, SR-, SCR-
  • Insert at the end of the corresponding section or reorder freely (the generator preserves CSV order)
  • When changing TestCaseRefs, use ; as separator — no spaces
  • For coverage status, use Planned (not tested), Implemented (code exists), Passed (tests pass), Failed (tests break)

Files

FilePurposeEditable?
docs/RTM.csvData source✅ Yes (manual editing or spreadsheet)
scripts/generate-rtm.tsCSV → Markdown generatorRarely
docs/quality/rtm.mdGenerated page❌ Generated

Script Summary

ScriptPhaseGeneratesValidatesFrequency
1docs:build validates dead linksAlways on build
scripts/generate-openapi.ts + openapi-registry.ts2openapi.json✅ Coverage against router.tsNew route
scripts/generate-typedoc.sh3docs/reference/typedoc/New entry point
scripts/generate-rtm.ts4docs/quality/rtm.mdNew requirement

Checklist for New Content

  • [ ] .md file created in the correct folder
  • [ ] YAML frontmatter present (title, description, status, owner, lastReviewed)
  • [ ] Sidebar updated in docs/.vitepress/config.mts (pt-BR + en-US)
  • [ ] If it's a new route: handler → router.ts (via route() helper with declarative middlewares) → openapi-registry.ts
  • [ ] If it's a new requirement: RTM.csv → pnpm docs:rtm
  • [ ] If it's a new TypeDoc entry point: typedoc.json + typedoc.tsconfig.json
  • [ ] pnpm docs:build passes without errors

Distribuído sob licença MIT.