Any authenticated user can invite an e-mail address; the mailed single-use token lets exactly one signup through even while registration is closed. Open (pending, unexpired) invitations count against the new instance setting invitations.maxOpenPerUser (default 5, 0 disables inviting) — plus a 20/day per-user rate limit so a revoke-and-recreate loop cannot become a mail cannon. Only the SHA-256 token hash is stored (auth-tokens pattern); a failed signup (taken username) un-redeems the token so the invitee can retry. Surfaces: invitations section in the user settings (list, invite, revoke, quota line; wide table in a focusable .table-scroll region), signup page reads ?invitation=<token> (preview banner, e-mail prefill, closed-mode gate opens only for a previewed-valid token), admin general card gets the quota field (flat RHF name per #322; VS-NfD marked and hideable). Governance: audit actions invitation.created/revoked/accepted (catalogue 1.10), VS-NfD profile entry (compliant: 0) + hardening-guide row, i18n de+en including the invitation mail template. Tests: api e2e-db (mail link, closed-mode single-use signup with un-redeem on failure, quota + revoke frees slot, quota 0 = 403, auth matrix), new web e2e pack invitations.spec.ts (full UI loop through Mailpit, wired into ci.yml with its own rate-limit reset), a11y scan waits for the new section. Full api suite (107 files / 607 tests), auth/admin-settings/a11y packs green against a fresh local stack. Closes #332 |
||
|---|---|---|
| .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.