|
All checks were successful
CI / Build container images (pull_request) Successful in 3m53s
CI / Auth e2e pack (pull_request) Successful in 8m42s
CI / Auth e2e pack (push) Successful in 8m41s
CI / Lint, typecheck, test (pull_request) Successful in 6m30s
CI / Import/export fidelity gate (pull_request) Successful in 58s
CD / Build and push images (push) Successful in 18s
CD / Smoke tests against Test (push) Successful in 1m19s
CD / Deploy to Test (push) Successful in 16s
CD / Promote to Int (push) Successful in 12s
CI / Lint, typecheck, test (push) Successful in 6m41s
CI / Build container images (push) Has been skipped
CI / Import/export fidelity gate (push) Successful in 52s
An operator holding a font licence could only use it by baking the file into a custom image, which tied every change to a rebuild and left the file out of the backup. ADR 0016 said there is no runtime font management. It also listed this exact case under "Alternatives considered" — *may become a Site-Admin- level feature later*. The amendment takes that option and answers the two objections it raised: licensing risk (Site Admins only, licence recorded with the family) and file-format attack surface (magic-byte check and a size cap, never a parse). - `CUSTOM_FONTS_DIR` (default `./data/fonts`) — a sibling of uploads and plugins, NOT inside the image-baked `FONTS_DIR`, where a deploy would overwrite it and no backup would ever see it. - One list of data directories (`apps/backup/src/data-dirs.ts`) now feeds both the nightly archive and the restore, so they cannot drift. #306 and #307 add one line each instead of a second mechanism. - Both Dockerfiles bake the path. The backup image sets its volume paths itself ("self-sufficient without compose env" — #71's lesson) and reads no *_DIR from compose; without the ENV entry the archive would have skipped the directory silently. - The PDF path already read WOFF2 from disk at request time, so it only had to pick the other base directory for a custom family. - `fontStack`/`fontEntry` take the instance's uploaded families as an argument — they are runtime data. The catalog is searched first, and a colliding family name is rejected at upload, so a custom font can never shadow a catalog one. - Deletion is never blocked by usage: an unknown family already falls back to the system stack, so affected ponds degrade instead of breaking. The count of affected ponds travels into the audit entry. - Audit catalogue v1.6 (`font.uploaded`, `font.deleted`). Verified: api full suite against a fresh database, 102 files / 571 tests. The upload suite writes into a real temp directory and reads the bytes back off disk, so the storage layer is exercised rather than mocked. |
||
|---|---|---|
| .claude | ||
| .gitea/workflows | ||
| apps | ||
| deploy | ||
| docs | ||
| fixtures | ||
| packages | ||
| scripts | ||
| .dockerignore | ||
| .editorconfig | ||
| .gitignore | ||
| .node-version | ||
| .prettierignore | ||
| .prettierrc.json | ||
| CLAUDE.md | ||
| eslint.config.mjs | ||
| LICENSE | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
Dorfteich
Dorfteich is an open-source wiki system built around ponds (German: Teiche) — self-contained wiki spaces that people and teams organize freely with hierarchical labels, directories, and Obsidian-style page relations. Pages are edited in a collaborative WYSIWYG editor with live cursors and offline support.
- Project site: https://dorfteich.cloud
- Public flagship instance: https://dorfteich.online
- License: MIT
Key features
- Real-time collaboration — multiple people edit the same page simultaneously; everyone sees the other participants' cursors and input live. Offline edits merge conflict-free on reconnect (CRDT-based).
- Ponds — isolated wiki spaces with their own members, permissions, fonts, and page organization. Every registered person gets a personal pond.
- Flexible organization — hierarchical labels, free page ordering,
[[wikilinks]]with backlinks. A classic page tree is possible but never enforced. - Fine-grained permissions — roles (Site Admin, Pond Admin, Editor, Reader, Public) can be granted per pond, per label, or per page; the most specific setting wins.
- Import & export — Markdown as the primary exchange format, plus best-effort structural import from Word/OpenOffice and export to Word/OpenOffice/PDF.
- Plugins — sandboxed extensions (custom blocks, styles, page tools) installable at runtime without redeploying the instance.
- Self-hosting first — a single
docker compose upplus a guided first-run setup wizard yields a working instance. Start here:docs/self-hosting/README.md.
Documentation
- What is Dorfteich? —
docs/features.md - Manuals (user / pond admin / site admin / API / MCP) —
docs/manual/, auf Deutsch:docs/de/ - Extending it (plugins, core) —
docs/developer/extending.md - Running it —
docs/self-hosting/ - How it works inside —
docs/architecture/
Repository layout
| Path | Contents |
|---|---|
docs/manual/ |
User-facing manuals: user, pond-admin, site-admin, API, and MCP guides (start at docs/manual/README.md) |
docs/developer/ |
Extending Dorfteich: plugin development and core contributions |
docs/architecture/ |
Architecture documentation: ADRs, data model, permission model, collaboration and plugin concepts, deployment and operations |
docs/self-hosting/ |
Install, update, backup, and troubleshooting guide for running your own instance |
apps/ |
Application packages (web frontend, API server, collaboration server) — created as implementation proceeds |
packages/ |
Shared packages (types, permission logic, plugin SDK) |
deploy/ |
Docker Compose stacks and deployment tooling |
Development
Requirements: Node.js ≥ 22 and pnpm (npm install -g pnpm).
pnpm install # install all workspace dependencies
pnpm lint # ESLint + Prettier check across the repo
pnpm typecheck # TypeScript --noEmit in every package
pnpm test # Vitest in every package
pnpm build # build every package (dependency order)
The workspace packages live under apps/ (web, api, collab) and
packages/ (shared). Shared logic goes into packages/shared and is
imported as @dorfteich/shared — never copy code between apps.
Status
Feature-complete for a 1.0: collaboration, permissions, import/export, plugins, public REST API + MCP, backups with off-host copies and in-app restore — all shipped and release-gated. Work is tracked as issues in this repository.
Contributing
Code, comments, and documentation are written in English. Write clear code that humans can follow easily; when in doubt, prefer readability over cleverness. All contributions are accepted under the MIT license.