Contributing
Branches and merge requests
mainis the default branch of the monorepo. (The old split repositories usedmaster.)Work on a short-lived branch named after its type:
feature/<topic>,fix/<topic>,chore/<topic>.prototype/<topic>is for experiments that may never merge.Open a merge request on GitLab (
gitlab.com/sidedoc/sidedoc) intomain. Before you ask for a review, run from the root:shnpm run typecheck npm test npm run test:a11y -w sidedoc-frontend # if you changed UI npm run docs:build # if you changed docs or exported APIChanges that span this repository and the schemas repository (a new field type, a mapping change) need a merge request in each. Merge the schemas side first and sync the generated files in the same merge request as the code that needs them.
Commit messages
The history follows Conventional Commits:
type(scope): summary in the imperative, lower case
Body: what changed and why, wrapped at about 100 characters. Mention test results or
behaviour that did not change when it helps the reviewer.- Types in use:
feat,fix,refactor,test,chore,docs,style,release. - Common scopes:
editor,a11y,frontend,backend,schema,dcat,outline,validation,persistence,export,standalone,docker. Leave the scope out for changes across the repository. - One logical change per commit. Regenerated files (bundled schemas, vocabulary index, mapping copies) go in their own
chore:commit, for examplechore: regenerate bundled schema and vocab files. - AI-assisted commits carry a
Co-Authored-By:trailer.
Code style
- TypeScript in strict mode in both packages. The backend also has
noUnusedLocals,noUnusedParametersandnoImplicitReturns;npm run typecheckmust pass. - Backend: four-space indentation, ESLint with
@typescript-eslint(npm run lint -w @sidedoc/backend). - Frontend: Vue 3 single-file components;
<script setup>for most components, render functions (h()) in the recursive editor renderers. Two-space indentation in.vuefiles, four spaces in most.tsfiles; follow the file you are in. - Keep logic in the backend. Schema traversal, normalization, validation and export belong in
@sidedoc/backend; Vue components render and forward events. - Never hard-code profile fields. Read labels, limits and hints from the schema (
x-sidedoc). - Styles: change the SCSS source and the committed
src/assets/tcc.csstogether (see Accessibility). - Comments explain why, not what. Reference the issue or RFC id (
TD-001,WCAG-03A) when a decision comes from one. - Files that end in
.generated.jsonare build output. Change their source in the schemas repository instead.
TSDoc conventions
Everything exported from @sidedoc/backend (src/index.ts and the barrels it re-exports) needs a /** ... */ comment. The API reference is generated from these comments, so a missing comment is a gap in the documentation.
- Start with one sentence that says what the symbol does or is, in the present tense: "Builds the editing shadow of a document." Add a second sentence only for something the signature does not show: side effects, defaults, when it throws.
- Use
@param name - textand@returnsonly when they add information. Do not repeat the type. - Use
@throwsfor errors callers are expected to handle. - Use
@examplefor entry points (ShadowApplicationService,ActiveRecordSession,applyRdfMapping), with a fencedtsblock. - Use
{@link Symbol}only for symbols that are exported from the package; for internal names use backticks. TypeDoc warns about links it cannot resolve. - Mark deprecated aliases with
@deprecatedand name the replacement. - Put code, tags and anything with angle or curly brackets in backticks. The generated Markdown is rendered by VitePress, which treats raw
<tag>text and double curly braces as Vue. - Write plain English: no em-dashes, no marketing words.
Frontend composables and helper modules in src/composables/ and src/components/editor/ get a short header comment on their main export: what it renders or returns and what it needs from editorCtx.
Regenerating the API reference
npm run docs:api -w sidedoc-docs # or: cd docs && npm run docs:apiThis runs TypeDoc with docs/typedoc.json: entry point app/sidedoc-backend/src/index.ts, the backend's tsconfig.json, typedoc-plugin-markdown and typedoc-vitepress-theme, output in docs/dev/api/. The output is not committed (.gitignore); npm run docs:build and npm run docs:dev regenerate it first. The intro text of the API index page comes from docs/.typedoc/README.md.
Documentation
The site at docs.sidedoc.app is the VitePress project in docs/ (ADR 0006).
| Section | Folder | Audience |
|---|---|---|
| User guide | docs/user/ | People filling in datasheets. |
| Deployment | docs/deploy/ | Operators. |
| Profiles and schemas | docs/profiles/ | Schema authors; reference pages are generated per version. |
| Developer guide | docs/dev/ | This guide, ADRs in docs/dev/adr/, API reference in docs/dev/api/. |
- Sidebars are built from the files: a page sets
title:andorder: <n>in its frontmatter. Adding a page needs no config change. - VitePress parses Markdown as Vue templates. Escape double curly braces and HTML-like text outside code, or wrap a block in
::: v-pre. - Write an ADR in
docs/dev/adr/NNNN-short-title.mdfor a decision that is hard to reverse: context, decision, consequences. Keep it short and link to the commits or files that show it. app/sidedoc-frontend/doc/issues/holds backlogs and test-session notes. They are working notes, not documentation.