Getting started
Requirements
- Node.js 22 (the container build uses
node:22) and npm. - Git.
- For the Playwright suites: browsers installed with
npx playwright install(once). - Only if you regenerate schemas: Python 3 in the schemas repository. See ADR 0004.
Install and run
From the monorepo root:
git clone https://gitlab.com/sidedoc/sidedoc.git && cd sidedoc
npm ci # one lockfile for all workspaces
npm run dev -w sidedoc-frontend # http://127.0.0.1:5173/standalone.html
npm run typecheck # tsc for the backend, vue-tsc for the frontendThere is no backend build step. The frontend resolves @sidedoc/backend to app/sidedoc-backend/src/index.ts: an alias in app/sidedoc-frontend/vite.config.ts, mirrored by paths in tsconfig.app.json. Vite dev, vite build, Vitest, vue-tsc and the Playwright suites all use the backend source, so a backend edit shows up in the running dev server through HMR, and a stale app/sidedoc-backend/dist/ is never picked up. Keep the alias and the paths entry in sync if you move the entry file.
The backend's package.json exports still point at dist/. That is the library for consumers outside the monorepo; build it with npm run build -w @sidedoc/backend (needs the schemas, see below).
Schemas and SIDEDOC_SCHEMAS_DIR
The schemas are not in the monorepo; they live in their own repository. What the app needs from them is committed here as generated files:
app/sidedoc-backend/src/lib/application/services/core/materialized-vocabulary-index.generated.jsonapp/sidedoc-backend/src/lib/application/services/transformers/dcat/*.mapping.generated.jsonapp/sidedoc-frontend/public/vocabs/*.vocab.json(large vocabularies, lazy-loaded)app/sidedoc-frontend/public/schemasandpublic/vocab(copies served by the app)
So dev, typecheck, the frontend tests, vite build and the Docker image work without a schemas checkout. You need one only for:
npm test: some backend tests read the example datasheets from the schemas repository.npm run buildornpm run build -w @sidedoc/backend: the backend'sprebuildregenerates the generated files above.- Picking up schema changes: run
npm run prebuild -w @sidedoc/backendand commit the regenerated files. The output is deterministic, so an unchanged checkout gives no diff.
git clone https://gitlab.com/sidedoc/schemas.git ../schemas
export SIDEDOC_SCHEMAS_DIR=$(cd ../schemas && pwd)
npm test # backend unit tests, then frontend unit testsWithout SIDEDOC_SCHEMAS_DIR the scripts look for a schemas/ folder in the monorepo root and stop with a clear message if it does not exist. Put the export in your shell profile or a local env file so every test run sees it.
prebuild runs two scripts:
scripts/build-materialized-vocab-index.mjswritessrc/lib/application/services/core/materialized-vocabulary-index.generated.jsonfrom the SKOS files in the schemas checkout.scripts/sync-dcat-mappings.mjscopiesrdf-targets/dcat-ap/*.dcat-ap.mapping.jsontosrc/lib/application/services/transformers/dcat/*.mapping.generated.json.
Entry points
npm run dev -w sidedoc-frontend starts Vite on http://127.0.0.1:5173 and opens /standalone.html, the datasheet editor that is deployed at sidedoc.app. The dev server also serves the other two entry points:
| Page | Entry | What it is |
|---|---|---|
/standalone.html | src/main-standalone.ts -> StandAlone.vue | The editor users see. |
/index.html | src/main.ts -> App.vue -> BackendDemo.vue | Older backend demo with workspace, folder, QA and storage-provider panels. |
/testbench.html | src/main-testbench.ts -> TestbenchApp.vue | Component testbench. |
All three call initializeBackend() from src/services/backend-setup.ts, which wires the backend services to IndexedDB and provides them to the app as backend.
Testbench
npm run dev:testbench -w sidedoc-frontendThe testbench mounts single editor component families (for example the Term or Agent field) with fixture data, so you can try a renderer without building a whole document. It is driven by two JSON-Schema-validated catalogs:
- descriptors (
src/testbench/model/): which component, profile, field path and initial context; - scenarios (
src/testbench/scenarios/): ordered actions and assertions, with a baseline per state (happy, validation, edge) for priority components.
src/testbench/harness/ supplies a stand-in editorCtx and backend service doubles. The READMEs in those three folders describe the formats. The smoke test and quality gate are described in Testing.
Production builds
The frontend has several Vite modes. Each selects which HTML entry points end up in dist/:
Command (in app/sidedoc-frontend) | Mode | Output |
|---|---|---|
npm run build | default | index.html (demo app) |
npm run build:app | app | index.html (demo app) |
npm run build:full | full | demo app and testbench |
npm run build:testbench | testbench | testbench only |
npx vite build --base=./ --mode standalone | standalone | standalone.html (the editor) |
npm run build:combined-dist | standalone | editor as index.html, plus backend dist, SKOS vocabularies and rewrite rules |
To build the deployable editor the way the container image does (no backend build needed):
SIDEDOC_CSP_META=false npx vite build --base=./ --mode standalone # in app/sidedoc-frontend
mv dist/standalone.html dist/index.htmlscripts/build-static.sh in the repository root does the same, with the <meta> CSP left in.
--base=./ makes asset paths relative, so the build also works under a sub-path. By default the build injects a Content-Security-Policy <meta> tag (the inject-csp-meta plugin in vite.config.ts, build only, because a strict script-src would break dev HMR). SIDEDOC_CSP_META=false leaves it out for servers that send the policy as a header: the container does, so operators can extend it, for example with SIDEDOC_CSP_CONNECT_SRC. A header cannot loosen a <meta> policy, because the browser enforces both. The <meta> policy's connect-src allows only 'self' and the Sentry ingest hosts. Keep it in sync with the policy in docker/entrypoint.sh. Builds read run-time settings from config.js; see ADR 0003 and the deployment guide.
build:combined-dist reads SKOS files from SIDEDOC_SCHEMA_DIR (singular, resolved relative to app/sidedoc-frontend) and otherwise from ../../Schemas, a path from the old split-repo layout. Set SIDEDOC_SCHEMA_DIR=$SIDEDOC_SCHEMAS_DIR when you use it.
If SENTRY_ORG, SENTRY_PROJECT and SENTRY_AUTH_TOKEN are set at build time, the build uploads hidden source maps to Sentry and deletes them from dist/.
Documentation site
npm run docs:dev # API reference generation, then the VitePress dev server
npm run docs:build # API reference generation, then a static build in docs/.vitepress/distSee Contributing for how the site is organised.