Skip to main content
Version: 3.0.1

Contributor Guide

1. Introduction

This guide covers everything a contributor needs to author and maintain documentation for the PCR Analysis System. It is the central entry point for documentation work: repository layout, Docusaurus mechanics, version management, traceability, and validation.

Audience: Developers, QA engineers, and LLM agents working on requirements, design, or test documentation.

Scope:

  • Repository structure and directory conventions
  • Docusaurus frontmatter, sidebar config, linking, images, and diagrams
  • Version management and snapshot workflow
  • Code-to-documentation traceability (code_tags.json)
  • Validation commands and pre-commit checklists

Out of scope: STD/testing workflows are covered by the Dev Testing Guide. SRS and SDS authoring formats are covered by their respective detail guides:


2. Getting Started

Prerequisites

  • Node.js >= 20

Commands

# Install dependencies
cd docusaurus && npm install

# Start local dev server (hot reload)
npm start

# Production build (validates all links)
npm run build

# Serve production build locally
npm run serve

A successful npm run build with 0 broken link warnings is the primary quality gate. Run it before every commit.


3. Repository Layout

docusaurus/
├── docs/ # Current working version (edit here)
│ ├── srs/ # SRS domain files (29)
│ │ ├── introduction.md
│ │ ├── analytics.md
│ │ ├── kitcfg.md
│ │ └── ...
│ ├── srs/rules/ # SRS rule files (61)
│ │ ├── rules.md # Rule index page
│ │ ├── rule-adj.md
│ │ ├── rule-amb.md
│ │ └── ...
│ ├── sds/ # SDS files (34 total)
│ │ ├── sds-01-introduction.md # Template & conventions (frozen)
│ │ ├── sds-02-system-context.md
│ │ ├── sds-03-architecture-overview.md
│ │ ├── sds-04-data-architecture.md
│ │ ├── sds-05-security-architecture.md
│ │ ├── sds-06-cross-cutting.md
│ │ ├── sds-master-index.md
│ │ ├── domains/ # 14 domain design docs
│ │ ├── rules/ # 8 rule design docs
│ │ ├── reference/ # 4 reference docs (API, config, DB, glossary)
│ │ └── traceability/ # Coverage tracking
│ ├── std/ # STD files (91)
│ │ ├── std-test-plan.md
│ │ ├── std-ui-testability.md # NOTE: at std/ root, not std/domains/
│ │ ├── domains/ # 29 domain test docs
│ │ └── rules/ # 60 rule test docs
│ ├── guides/ # This guide and others
│ └── traceability/ # Known issues, traceability, coverage
├── versioned_docs/ # Frozen version snapshots (do NOT edit)
│ └── version-3.0.0/
├── versioned_sidebars/
│ └── version-3.0.0-sidebars.json
├── static/media/ # Images and assets
├── sidebars.js # Manual sidebar configuration
├── docusaurus.config.js # Site configuration
└── versions.json # Version registry
Hands off
  • versioned_docs/ -- Frozen release snapshots. Do not edit unless deliberately replacing a version.
  • sdd/ -- Deprecated legacy design documents. Retained for reference only; all new design content goes in sds/.

4. Version Management

How It Works

Docusaurus uses directory-based versioning:

DirectoryVersionURL Path
docs/Working "Next" version/next/
versioned_docs/version-3.0.0/Frozen v3.0.0 release/ (root, current default)

The docusaurus.config.js docs.versions block controls which version is served at which URL. Currently, v3.0.0 is served at the site root and "Next" is served at /next/.

Creating a Version Snapshot

cd docusaurus
npx docusaurus docs:version X.Y.Z

This creates:

  • versioned_docs/version-X.Y.Z/ -- frozen copy of docs/
  • versioned_sidebars/version-X.Y.Z-sidebars.json -- frozen sidebar configuration

After Snapshotting

Update docusaurus.config.js to configure the new version's label and URL path:

// In docusaurus.config.js → docs.versions
versions: {
current: {
label: 'Next',
path: 'next',
},
'X.Y.Z': {
label: 'X.Y.Z',
path: '/',
},
// older versions...
},

When to Snapshot

  • Before a product release, after documentation is finalized
  • After completing a major documentation milestone (e.g., SDS creation, STD reconciliation)
  • Use semantic versioning matching the product release: 3.0.0, 3.1.0, 3.0.1

Replacing an Existing Snapshot

To update a frozen version: delete the old versioned_docs/version-X.Y.Z/ directory and sidebar file, copy fresh docs/ content in, restore the version in versions.json, and rebuild. See the Docusaurus versioning docs for detailed steps.


5. Docusaurus Mechanics

5.1 Frontmatter

Every documentation file requires YAML frontmatter:

---
title: "Human-readable title"
description: "One sentence summary for SEO/meta"
sidebar_position: N
---
FieldRequiredGuidelines
titleYesTitle Case, max ~40 characters for clean sidebar rendering. Can abbreviate the H1.
descriptionYesOne sentence, 10-20 words. Describe what the document covers. Include key terms for search.
sidebar_positionYesInteger determining order within its category. See Section 5.2 and Section 7 for ranges.

5.2 Sidebar Configuration

The sidebar is 100% manually configured in docusaurus/sidebars.js. Every new file must be explicitly added or it will not appear in navigation.

Document IDs are the file path relative to docs/ without the .md extension:

File PathDocument ID
docs/srs/analytics.mdsrs/analytics
docs/srs/rules/rule-adj.mdsrs/rules/rule-adj
docs/sds/domains/sds-domain-kitcfg.mdsds/domains/sds-domain-kitcfg
docs/guides/contributor-guide.mdguides/contributor-guide
docs/traceability/known-issues.mdtraceability/known-issues

Sidebar structure (abbreviated):

const sidebars = {
srsSidebar: [
'srs/introduction',
{ type: 'category', label: 'Run Management', items: ['srs/upload-runs', ...] },
{ type: 'category', label: 'Analysis & Rules', items: ['srs/analytics', ...] },
{ type: 'category', label: 'User Interface', items: ['srs/ui', ...] },
{ type: 'category', label: 'Configuration', items: ['srs/kitcfg', ...] },
{ type: 'category', label: 'User & Audit', items: ['srs/user-management', ...] },
{ type: 'category', label: 'Reference', items: ['srs/nfr'] },
{ type: 'category', label: 'Rule Definitions', collapsed: true, items: [...] },
],
sdsSidebar: [
'sds/sds-01-introduction',
{ type: 'category', label: 'System Architecture', collapsed: false, items: [...] },
{ type: 'category', label: 'Domain Design', collapsed: true, items: [...] },
{ type: 'category', label: 'Rules Design', collapsed: true, items: [...] },
{ type: 'category', label: 'Reference', items: [...] },
{ type: 'category', label: 'Traceability', items: [...] },
],
stdSidebar: [
'std/std-introduction',
'std/std-test-plan',
{ type: 'category', label: 'Test Infrastructure', items: [...] },
{ type: 'category', label: 'Domain Tests', collapsed: true, items: [...] },
{ type: 'category', label: 'Rule Tests', collapsed: true, items: [...] },
{ type: 'category', label: 'Reference', items: [...] },
],
guidesSidebar: [
{ type: 'category', label: 'Guides', collapsed: false, items: [...] },
],
};

Adding a new file to the sidebar:

  1. Create the file with correct frontmatter
  2. Determine the document ID (path without docs/ prefix and .md suffix)
  3. Add the ID to the appropriate category array in sidebars.js
  4. Run npm run build to verify

Position ranges by document type:

Document TypePosition RangeCategory
SRS1Introduction
SRS10-19Run Management
SRS20-29Analysis & Rules
SRS30-39User Interface
SRS40-49Configuration
SRS50-59User & Audit
SRS90-99Reference
SRS Rules1-62Alphabetical by rule name
SDS1-9System Architecture (Tier 1)
SDS10-29Domain Design (Tier 2)
SDS30-49Rules Design (Tier 2)
SDS50-59Reference (Tier 3)
SDS60-69Traceability (Tier 4)
SDS90Master Index
info

When sidebars.js uses explicit item arrays, the array order takes precedence over sidebar_position in frontmatter. Both should agree, but the array is authoritative.

Relative Path Rules

All internal links use relative paths based on the source file's location:

Source File LocationTargetLink Format
docs/guides/SRS file../srs/kitcfg.md
docs/guides/SDS domain doc../sds/domains/sds-domain-kitcfg.md
docs/srs/SDS file../sds/sds-03-architecture-overview.md
docs/srs/STD file../std/std-test-plan.md
docs/sds/domains/SRS file../../srs/analytics.md
docs/sds/domains/Sibling SDS domain./sds-domain-audit.md
docs/sds/domains/SDS root file../sds-03-architecture-overview.md
docs/sds/domains/SDS reference../reference/sds-ref-config.md
docs/sds/domains/SDS rules../rules/sds-rules-engine.md

Use absolute paths only for static assets (images served from /media/).

Anchor Format

Headers generate automatic anchors, but explicit anchors are recommended for REQ headers to ensure stability:

## REQ-KITCFG-001: Configuration Validation \{#req-kitcfg-001}

Anchors are lowercase with hyphens: #req-kitcfg-001 (not #REQ-KITCFG-001).

File Naming Gotchas

SRS filenames do not always match domain codes:

Domain CodeActual FilenameCommon Mistake
AUDITaudit-log.mdaudit.md
USERMGMTuser-management.mdusermgmt.md
RUNFILErunfile-list.md and runfile-report.mdrunfile.md

Helper Scripts

# Add explicit anchors to REQ headers (idempotent, safe to run repeatedly)
python docusaurus/scripts/add-req-anchors.py --dry-run # Preview
python docusaurus/scripts/add-req-anchors.py # Apply

# Convert bare Jira references to linked format
./docusaurus/scripts/link-jira-refs.sh -n # Dry-run preview
./docusaurus/scripts/link-jira-refs.sh # Apply
warning

fix-docusaurus-links.py is NOT idempotent. Running it multiple times corrupts paths. Always run git restore docusaurus/docs/ before using it:

git restore docusaurus/docs/
python docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --dry-run
python docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --apply

5.4 Images and Media

  • Place new images in docusaurus/static/media/ with descriptive filenames
  • Images are served at /media/filename.png (absolute path)
  • Use absolute paths for static assets in markdown:
![Architecture Diagram](/img/architecture-overview.png)

The Docusaurus preprocessor in docusaurus.config.js automatically rewrites legacy image paths (../../pilot/restructured/adocs/media/ and similar) to /img/. SDD images are routed to /img/sdd/ to avoid filename collisions.

5.5 Mermaid Diagrams

Mermaid is enabled globally via the @docusaurus/theme-mermaid plugin.

Primary diagram types:

TypeUse For
flowchart TD / flowchart LRDecision logic, algorithms, workflows
erDiagramEntity relationships, data models
sequenceDiagramInteraction flows between components
graph TB / graph LRComponent architecture, dependencies
stateDiagram-v2State machines

Conventions:

  • SRS files: one diagram near the top of the file, section titled "Behavior Overview (Illustrative)" or "Rule Flowchart (Illustrative)"
  • SDS files: multiple diagrams per file (dependencies, components, ERD, algorithms)
  • Always mark illustrative diagrams explicitly -- never use "non-normative"

Syntax gotchas:

IssueWrongCorrect
Pipe chars in labels`{CT
Forward slashes in labelsNode[/api/runs]Node["/api/runs"]
Node ID = subgraph IDCauses cycle errorsUse distinct IDs
Special chars (@, ())Unquoted in labelsQuote the label
Cross-subgraph connectionsInside subgraph blockDefine outside subgraph blocks

Validation:

bash docusaurus/scripts/validate-mermaid.sh docusaurus/docs

This script uses the exact mermaid version bundled with Docusaurus (docusaurus/node_modules/mermaid) to ensure zero version drift.


6. Traceability and Code Linking

6.1 Code Mapping Registry

Code-to-documentation traceability is maintained in a single JSON registry rather than inline code comments.

Registry location: tests/catalogue/code_tags.json

Structure:

{
"by_file": {
"app/Http/Controllers/RunImportController.php": {
"srs": ["REQ-RUNIMPORT-012", "REQ-AUDIT-004"],
"sdd": ["sds-domain-fileimport.md#run-import-process"]
}
},
"by_srs": {
"REQ-RUNIMPORT-012": ["app/Http/Controllers/RunImportController.php", "app/Services/RunImportService.php"]
},
"by_sdd": {
"sds-domain-fileimport.md#run-import-process": ["app/Http/Controllers/RunImportController.php"]
}
}

Keys:

KeyUsage
by_fileFile path to its SRS and SDS references
by_srsREQ ID to all implementing code files
by_sddSDS anchor to all implementing code files

Mappings are many-to-many: one code file can reference multiple REQs, and one REQ can be mapped to multiple code files.

6.2 What to Map

Add entries for these (navigation anchor points):

CategoryExamplesWhy
Entry pointsHTTP controllers, API routes, CLI commandsUser-facing boundaries
Queue workersJobs, event listenersAsync processing entry points
Core domain servicesRulesEngine, RunImportServiceBusiness logic centers
Persistence boundariesMigrations with logic, repositoriesData layer decisions
Integration boundariesS3, SES, Pusher, Cognito handlersExternal system touchpoints

Do NOT add entries for these:

CategoryExamplesWhy
UtilitiesString helpers, formattersNo direct requirement mapping
Simple CRUDBasic model accessorsToo granular
PresentationalBlade templates, simple Vue componentsUI layer, not behavior
Config files.env, config/*.phpNot code boundaries

6.3 Unified Traceability System

The project uses an auto-generated unified traceability system that replaces the old hand-maintained matrices.

Source of truth: tests/catalogue/unified-traceability.json -- a single JSON file that maps every REQ to its SDS design sections, STD test vectors, Behat feature files, and code mappings.

Generated views (3 Markdown files, do not edit manually):

FileContent
docusaurus/docs/traceability/unified-traceability-matrix.mdFull REQ-to-test mapping (site homepage)
docusaurus/docs/traceability/unified-coverage-report.mdCoverage metrics and gap analysis
docusaurus/docs/traceability/unified-release-checklist.mdTest inventory for release validation

Regeneration command:

python3 docusaurus/scripts/generate-unified-traceability.py --render-md

Run this after any STD, SDS, or code_tags.json changes.

6.4 Bidirectional Maintenance

Traceability flows in both directions and both sides must stay in sync:

DirectionMechanismLocation
Code to DocsEntries in code_tags.jsontests/catalogue/code_tags.json
Docs to CodeImplementation sections in SRS files## Implementation (Illustrative)

When code moves or requirements change, update both sides:

  1. Update the entry in tests/catalogue/code_tags.json (add, move, or remove file paths and REQ IDs)
  2. Update the Implementation section in the corresponding SRS file
  3. Update the Implementation Mapping section (section 8) in the corresponding SDS domain doc
  4. Regenerate unified traceability: python3 docusaurus/scripts/generate-unified-traceability.py --render-md

6.5 Cross-References Between Docs

The documentation suite is cross-linked at multiple levels:

FromToPurpose
SRS filesSDS sections in Traceability blocksLink requirements to design
SDS Requirements Covered tablesSRS REQ IDsMap design back to requirements
SDS domain docssds-master-index.mdNavigation hub
SDS domain docssds-ref-config.md, sds-ref-database.md, etc.Shared reference material
STD test docsSRS REQ IDsTest coverage traceability

When adding new content, keep these linkages current:

  • Update sds-master-index.md for new SDS sections or documents
  • Update SDS reference docs (sds-ref-api.md, sds-ref-config.md, sds-ref-database.md, sds-ref-glossary.md) for new APIs, config options, schema changes, or terms
  • Update the SRS Traceability Matrix for new requirements

For detailed authoring procedures, see SRS operations and SDS operations.


7. Sidebar Taxonomy & Positions

File Naming Conventions

Document TypePatternExample
SRS domain{domain}.mdkitcfg.md, analytics.md
SRS rulerule-{name}.mdrule-adj.md, rule-amb.md
SDSsds-{topic}.mdsds-03-architecture-overview.md
SDS domainsds-domain-{name}.mdsds-domain-kitcfg.md
SDS rulesds-rules-{name}.mdsds-rules-engine.md
STDstd-{topic}.mdstd-test-plan.md
SDD (legacy)sdd-{topic}.mdsdd-architecture.md

Position Ranges by Document Type

The position ranges below supplement the table in Section 5.2. STD ranges are included here for completeness.

Doc TypeRangeCategory
STD1Introduction
STD10-19Test Infrastructure
STD20-29Test Plans
STD90-99Reference (traceability, coverage)
SRS Rules1-62Alphabetical by rule name
Guides1+Ordered by audience (ops, dev, contributor)

SRS and SDS ranges are already listed in Section 5.2.


This section consolidates linking rules. See also Section 5.3 for relative path tables and anchor format.

Jira Reference Format

Bare Jira keys (BT-123, CST-456, PCRAI-789) should be converted to linked format:

[BT-123](https://arctichare.atlassian.net/browse/BT-123)

Auto-convert with ./docusaurus/scripts/link-jira-refs.sh (or -n for dry-run). Supported prefixes: BT-*, CST-*, PCRAI-*.

Static Asset Paths

Files in docusaurus/static/media/ are served at /media/. Always use absolute paths for images:

![Diagram](/img/architecture-overview.png)

SDD images use /img/sdd/ to avoid filename collisions (handled by the preprocessor in docusaurus.config.js).

Code Mapping Format

Code-to-documentation traceability is maintained in tests/catalogue/code_tags.json. See Section 6.1 for the JSON structure and update workflow.


9. Validation and Quality

9.1 Validation Commands

cd docusaurus

# 1. Build -- authoritative link check (0 broken links = pass)
npm run build 2>&1 | tail -5

# 2. Mermaid diagram validation (0 errors = pass)
bash scripts/validate-mermaid.sh docs

# 3. REQ anchor check (idempotent, safe to run)
python scripts/add-req-anchors.py --dry-run

# 4. Code mapping orphan check
jq -r '.by_srs | keys[]' ../tests/catalogue/code_tags.json | sort -u > /tmp/code-refs.txt
grep -roh "REQ-[A-Z]*-[0-9]*" docs/srs/*.md docs/srs/rules/ | sort -u > /tmp/srs-ids.txt
comm -23 /tmp/code-refs.txt /tmp/srs-ids.txt
# Should return empty

9.2 Common Build Issues

Build WarningCauseFix
couldn't be resolved on a file pathWrong relative pathCount ../ levels from source file location
#anchor couldn't be resolvedHeader anchor missing or mismatchedRun add-req-anchors.py or add explicit {#anchor}
../sdd/sdd-*.md couldn't be resolvedLegacy SDD referenceUpdate to ../sds/sds-*.md path
YAML errorMalformed frontmatterCheck for missing --- delimiters, unquoted special characters
Document not in sidebarMissing from sidebars.jsAdd document ID to correct category

10. Checklists

The following checklists cover common documentation workflows. For the full consolidated checklist reference (including validation commands), see the Authoring Checklists Reference.

10.1 Pre-Commit Checklist

  • npm run build produces 0 broken link warnings
  • bash docusaurus/scripts/validate-mermaid.sh docusaurus/docs produces 0 errors
  • python docusaurus/scripts/add-req-anchors.py --dry-run shows no missing anchors
  • No files modified in versioned_docs/ (unless intentionally replacing a snapshot)
  • No files modified in sdd/ (deprecated)
  • sidebar_position does not conflict with existing files in the same category
  • All new files tracked in sidebars.js
  • code_tags.json updated if code changed (add/move/remove file mappings)
  • Cross-document references are bidirectional (docs link to code AND code links to docs)

11. Quick Reference

Domain Code Table

For the full domain-to-file mapping, see the SDS Master Index.

Validation Commands Summary

TaskCommand
Full build (authoritative)cd docusaurus && npm run build
Mermaid validationbash docusaurus/scripts/validate-mermaid.sh docusaurus/docs
Add REQ anchorspython docusaurus/scripts/add-req-anchors.py
Preview REQ anchorspython docusaurus/scripts/add-req-anchors.py --dry-run
Convert Jira refs./docusaurus/scripts/link-jira-refs.sh
Preview Jira refs./docusaurus/scripts/link-jira-refs.sh -n
Preview link fixespython docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --dry-run
Run all Behat tests (V3+legacy+browser)python3 tests/scripts/behat-optimizer.py run --workers 10 --pre-migrate --rerun-failures --suite all --browser-workers 6
Run V3 API tests onlypython3 tests/scripts/behat-optimizer.py run --workers 10 --dir tests/exports/cucumber/v3

Parallel test execution: The behat-optimizer.py script consolidates feature files by identical config hash and runs them in parallel across the DB pool. Default mode runs migrate:fresh per file for correctness (~118 min, 99% pass rate). The --skip-migrate-fresh flag is faster (~28 min) but may cause FK constraint failures (~73% pass rate). See the Dev Testing Guide for full CLI reference and details.

Version tagging for tests: This is a multi-tenant medical device SaaS where clients run different versions. When a test's expected behavior differs between versions, create version-tagged scenario copies:

TagWhen to use
(no tag)Test passes on all versions (default — most tests)
@V3_0_0Assertions specific to v3.0.0 behavior
@V3_0_1Assertions specific to v3.0.1 behavior

Only add version tags when behavior actually differs between versions. Both tagged copies share the same BT key, TV tags, and fixtures — only assertions change. The --target-version flag on behat-optimizer.py selects which version set to run (default = latest, excludes @V3_0_0). See the Dev Testing Guide for the full scheme and examples.