DocLang Format

DocLang is a JSON-based documentation format used by NIVAA. It separates content from presentation, allowing documentation pages to be rendered by any compatible frontend while maintaining rich structure and semantics.

Overview

Each documentation page is a JSON file with three top-level fields: title, lead (optional subtitle), and blocks (array of content blocks). The renderer processes blocks in order, choosing the appropriate component for each block type.

Page Structure

Page JSON Shape
{
  "title": "Page Title",
  "lead": "Optional subtitle or intro text.",
  "blocks": [
    { "type": "heading", "level": 2, "text": "Section Title" },
    { "type": "paragraph", "text": "Body text with **bold** and `code`." }
  ]
}
FieldTypeRequiredDescription
titlestringYesPage title displayed as h1
leadstringNoSubtitle text displayed below the title
blocksarrayYesOrdered array of content blocks

Inline Markup

Within any text field, the following inline markup is supported:

SyntaxRenders AsExample
bold textBold textimportant becomes bold
` code `Inline codevariable becomes monospace code
link textHyperlinkSession Lifecycle becomes a link
No raw HTML

Text fields must not contain raw HTML. All formatting is done through inline markup syntax.

Block Types Reference

TypeCategoryDescription
headingTextSection heading (h2, h3, etc.)
paragraphTextBody text with inline markup
calloutTextHighlighted note or warning box
listTextBulleted or numbered list
stepsTextOrdered process steps
tableDataRows and columns of data
codeDataSyntax-highlighted code block
badge-listDataStatus badges with descriptions
command-tableDataBot command reference table
endpointDataAPI endpoint documentation
link-gridLayoutGrid of linked cards
flowDiagramNode-and-edge status flow diagram
decision-treeDiagramYes/no branching tree
state-machineDiagramStates and transitions
scored-breakdownDiagramWeighted scoring dimensions
architectureDiagramSystem architecture layers
timelineDiagramChronological event list
swimlaneDiagramCross-actor workflow with horizontal lanes
test-groupTestingA named group of test cases with file, describe label, and per-test assertions

Text Blocks

heading

Schema
{ "type": "heading", "level": 2, "text": "Section Title" }

Properties: level (number, 2-4) and text (string).

paragraph

Schema
{ "type": "paragraph", "text": "Text with **bold** and `code` markup." }

callout

Schema
{ "type": "callout", "variant": "info", "title": "Note", "text": "Important detail." }

Variants: info (purple), warning (amber).

list

Schema
{ "type": "list", "ordered": false, "items": ["Item 1", "Item 2"] }

steps

Schema
{ "type": "steps", "items": ["First do this.", "Then do that."] }

Steps are always ordered (rendered as <ol>) and typically describe a sequential process.

Data Blocks

table

Schema
{ "type": "table", "headers": ["Col1", "Col2"], "rows": [["val1", "val2"]] }

code

Schema
{ "type": "code", "header": "Example", "language": "json", "content": "{ \"key\": \"value\" }" }

Properties: header (optional label above the block), language (syntax highlighting hint), content (raw code string).

badge-list

Schema
{ "type": "badge-list", "items": [
  { "label": "Scheduled", "variant": "blue", "description": "Initial state" }
] }

Variants: blue, green, amber, red, purple, muted.

command-table

Schema
{ "type": "command-table", "commands": [
  { "command": "/sessions", "description": "Today's sessions", "detail": "Full explanation..." }
] }

endpoint

Schema
{ "type": "endpoint", "method": "GET", "path": "/admin/students",
  "auth": "Admin", "description": "List all students",
  "params": [{ "name": "funnel", "type": "string", "description": "Filter" }],
  "response": "{ ... }" }

Layout Blocks

link-grid

Schema
{ "type": "link-grid", "columns": 2, "items": [
  { "title": "Link Title", "description": "Short description", "href": "/docs/page" }
] }

Diagram Blocks

flow

Schema
{ "type": "flow",
  "nodes": [
    { "id": "scheduled", "label": "Scheduled", "variant": "blue" },
    { "id": "active", "label": "Checked_In", "variant": "green" }
  ],
  "edges": [
    { "from": "scheduled", "to": "active", "label": "optional edge label" }
  ]
}

Represents a directed graph of status transitions. Node variants control color coding.

decision-tree

Schema
{ "type": "decision-tree", "title": "Cancel Flow",
  "root": {
    "label": "Is the session scheduled?",
    "yes": { "label": "Proceed with cancel" },
    "no": { "label": "Cannot cancel" }
  }
}

Recursive yes/no branching structure. Each node has label, and optional yes and no child nodes.

state-machine

Schema
{ "type": "state-machine", "title": "Callback Data",
  "states": [
    { "id": "checkin_ID", "label": "Check in to appointment" }
  ],
  "transitions": [
    { "from": "chg_ID", "to": "cnl_ID", "label": "Cancel" }
  ]
}

scored-breakdown

Schema
{ "type": "scored-breakdown", "title": "Match Scoring",
  "maxScore": 100,
  "dimensions": [
    { "name": "Subject", "maxPoints": 25, "description": "Subject expertise match" }
  ]
}

architecture

Schema
{ "type": "architecture", "title": "System Architecture",
  "layers": [
    { "name": "Client", "items": ["SvelteKit Frontend", "Telegram Bot"] },
    { "name": "Edge", "items": ["CF Pages", "CF Worker"] }
  ],
  "connections": [
    { "from": "SvelteKit Frontend", "to": "CF Pages", "label": "HTTPS" }
  ]
}

timeline

Schema
{ "type": "timeline", "title": "Session Day",
  "events": [
    { "time": "7:00 AM", "label": "Daily digest sent" },
    { "time": "~1 hour before", "label": "Pre-session reminder" }
  ]
}

swimlane

Schema
{ "type": "swimlane", "title": "Posting Lifecycle",
  "lanes": [
    { "label": "Parent", "color": "#3b82f6" },
    { "label": "Educator", "color": "#059669" },
    { "label": "Coordinator", "color": "#d97706" },
    { "label": "System", "color": "#552c7d" }
  ],
  "steps": [
    {
      "lane": "Parent",
      "action": "Posts tutoring need",
      "triggers": "Notification to matching tutors",
      "visibility": "Educators see on Browse",
      "backend": "posting.status = 'Open'",
      "next": "Educator applies"
    }
  ]
}

Renders horizontal swim lanes with step cards flowing left-to-right. Each lane represents an actor (e.g. Parent, Educator, System). Steps are placed in their lane and connected by arrows that curve across lanes when the actor changes.

FieldTypeRequiredDescription
lanesarrayYesArray of lane definitions with label (string) and optional color (hex)
stepsarrayYesOrdered array of step objects placed in lanes
steps[].lanestringYesWhich lane this step belongs to (must match a lane label)
steps[].actionstringYesPrimary action text shown in the step card
steps[].triggersstringNoSide-effect or notification triggered by this step
steps[].visibilitystringNoWho can see or is affected by this step
steps[].backendstringNoBackend state change (shown in monospace)
steps[].nextstringNoDescription of what happens next (for documentation only, not rendered)

Testing Blocks

test-group

Renders a labeled group of test cases with a file badge, describe block name, test count, and a row per test showing method, path, and assertion. Used to document test coverage in the docs site.

Schema
{
  "type": "test-group",
  "file": "api.test.ts",
  "describe": "Session Lifecycle",
  "tests": [
    { "method": "POST", "path": "/appointments/:id/confirm", "assertion": "200 — package deducted" },
    { "method": "POST", "path": "/appointments/:id/dispute", "assertion": "200 — package restored" },
    { "assertion": "Flow-only assertion with no HTTP method" }
  ]
}
FieldTypeRequiredDescription
filestringYesFilename displayed as a dark badge (api.test.ts, shapes.test.ts, flows.test.ts)
describestringYesThe describe() block name shown as the group heading
testsarrayYesArray of test case objects
tests[].methodstringNoHTTP method — rendered as a colour-coded badge (GET, POST, PATCH, PUT, DELETE)
tests[].pathstringNoURL path — rendered in monospace with purple tint
tests[].assertionstringYesWhat the test asserts — plain prose description
method and path are optional

For flow tests that don't map cleanly to a single endpoint, omit method and path and use only assertion. The block renders gracefully with just the assertion text.

Navigation Structure

The sidebar navigation is defined in nav.json as an array of sections. Each section has a title, optional defaultOpen boolean, and an items array. Each item has a label (display text) and a slug (URL path segment relative to /docs/).

nav.json Structure
[
  {
    "title": "Getting Started",
    "defaultOpen": true,
    "items": [
      { "label": "Overview", "slug": "" },
      { "label": "Architecture", "slug": "architecture" }
    ]
  }
]

Complete Example

A minimal but complete documentation page:

example-page.json
{
  "title": "My Feature",
  "lead": "A brief introduction to this feature.",
  "blocks": [
    { "type": "heading", "level": 2, "text": "How It Works" },
    { "type": "paragraph", "text": "This feature uses **blind matching** to connect users." },
    { "type": "callout", "variant": "info", "title": "Note", "text": "Only `Admin` users can access this." },
    { "type": "steps", "items": [
      "User submits a request.",
      "System processes and scores it.",
      "Coordinator reviews and approves."
    ] },
    { "type": "table", "headers": ["Status", "Meaning"], "rows": [
      ["**Active**", "Currently in use"],
      ["**Closed**", "No longer available"]
    ] },
    { "type": "code", "header": "API Response", "language": "json", "content": "{\n  \"ok\": true,\n  \"data\": { \"id\": 1 }\n}" }
  ]
}