Go to file
Claude Opus 5 3310ae3926
All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 7m19s
CI / Build container images (pull_request) Successful in 1m23s
CI / Auth e2e pack (pull_request) Successful in 8m55s
CI / Import/export fidelity gate (pull_request) Successful in 57s
CD / Build and push images (push) Successful in 14s
CD / Deploy to Test (push) Successful in 16s
CD / Smoke tests against Test (push) Successful in 1m28s
CD / Promote to Int (push) Successful in 13s
CI / Lint, typecheck, test (push) Successful in 6m52s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 9m6s
CI / Import/export fidelity gate (push) Successful in 58s
#305: a full pond archive before deletion and before purge
Deleting a pond already had a strict prompt — typing the pond name, stricter
than a confirm dialog. That was never the gap. The gap is that the person who
deletes it loses access the moment they do: the pond leaves their view, only a
Site Admin can bring it back, and the export is no longer reachable for them.
So the archive is offered INSIDE the deletion flow, before the button.

What it contains, and why it is not the existing export:

- Every page the requester may read, as Markdown, as before.
- **Every attachment of the pond**, not only the embedded ones. An
  attachment nobody put on a page would otherwise vanish unnoticed — which
  is the whole reason this issue exists.
- `manifest.json`: pond settings (EFFECTIVE, defaults filled in — a
  preservation format must not require its reader to know Dorfteich's
  defaults), labels, the page hierarchy and sort keys, comments, and
  attachment metadata including the #199 hash so a reader can verify bytes.
  It extends the #210 manifest rather than adding a second descriptor, and
  carries an explicit `formatVersion`.
- `README.txt`, because the manifest is for machines: whoever unpacks a
  folder of Markdown a year from now must not believe they hold a one-click
  restore.

Decisions worth naming:

- **"Complete" describes the RESULT, not the route.** A pond admin who may
  read every page gets `complete: true`; only an archive that actually
  leaves pages out is incomplete. The Site-Admin route skips the read filter
  (an archive taken before an irreversible purge must not depend on which
  ponds the operator happens to be a member of) — those are two different
  questions and the first version of this conflated them.
- **The omission is named before the download**, with its number, in the UI
  and in the manifest. An archive silently missing content is worse than no
  archive, because it ends the search.
- **Not downloading stays allowed.** A pond of test pages should not require
  one, and the server cannot tell whether a file arrived anyway — so the
  finality is stated in text instead of enforced.
- **A plain link, not fetch-into-a-blob.** The api streams the ZIP; buffering
  a whole pond in the tab to draw a progress bar would trade memory for
  cosmetics. The browser reports progress and completion; what it cannot say
  — that the archive is being BUILT — is announced in a live region.
- Read trail unchanged in kind (ADR 0023): one `export` event per classified
  page before any classified byte enters the stream. Attachments never travel
  without their page, so the same events cover them.
- New audit action `pond.archived` (catalogue v1.7) with page and attachment
  counts, omitted pages, and completeness.

Format documented in `docs/architecture/pond-archive-format.md`, including
what is deliberately NOT in it (history, permissions, trash).

Verified by hand, not only asserted: a real pond's archive downloaded and
unpacked — README, manifest, three page files, the media file; the manifest's
effective settings, per-page classification, the VS-NfD frontmatter and
marking preserved in the classified page's Markdown, and the attachment's
sha256 present. Plus six api tests (including that an unembedded attachment
travels and that a Site Admin gets a complete archive without membership) and
the a11y pack 11/11 in both schemes, which now also scans the pond settings
screen.

Not done, because there is nothing to attach it to: the Site Admin's purge
dialog (#193) exists only as an api endpoint — there is no pond-trash UI in
the web app. The api half is here and tested, so it becomes a link when that
screen is built.
2026-08-01 20:24:35 +02:00
.claude graphify: CLAUDE.md-Sektion + PreToolUse-Hooks, graphify-out/ gitignored 2026-07-19 00:46:00 +02:00
.gitea/workflows #303 follow-up: the fonts volume must mount node-owned 2026-08-01 15:12:06 +02:00
apps #305: a full pond archive before deletion and before purge 2026-08-01 20:24:35 +02:00
deploy #306: instance branding — logo and favicon, cropped in the browser 2026-08-01 19:30:52 +02:00
docs #305: a full pond archive before deletion and before purge 2026-08-01 20:24:35 +02:00
fixtures Fix the gates the #116 commit skipped past 2026-07-14 16:53:11 +02:00
packages #305: a full pond archive before deletion and before purge 2026-08-01 20:24:35 +02:00
scripts #202: SBOM and license report in CI 2026-07-31 04:21:58 +02:00
.dockerignore Add production Dockerfiles and the Compose stack with dev overlay 2026-07-04 19:30:21 +02:00
.editorconfig Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +02:00
.gitignore graphify: CLAUDE.md-Sektion + PreToolUse-Hooks, graphify-out/ gitignored 2026-07-19 00:46:00 +02:00
.node-version #236: pin the Node version 2026-07-31 04:14:55 +02:00
.prettierignore chore: graphify/agent-Config aus Prettier ausnehmen 2026-07-19 01:02:58 +02:00
.prettierrc.json Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +02:00
CLAUDE.md #300: route icon-only controls through IconButton/IconLink 2026-08-01 06:56:13 +02:00
eslint.config.mjs #300: route icon-only controls through IconButton/IconLink 2026-08-01 06:56:13 +02:00
LICENSE Add architecture documentation, ADRs, and operations concept 2026-07-04 14:36:16 +02:00
package.json #202: SBOM and license report in CI 2026-07-31 04:21:58 +02:00
pnpm-lock.yaml #214: OIDC Authorization Code with PKCE, Keycloak as reference IdP 2026-07-31 12:44:52 +02:00
pnpm-workspace.yaml #136 Excalidraw-Block-Plugin 2026-07-19 04:18:04 +02:00
README.md German translations of the seven user-facing docs under docs/de/ 2026-07-12 19:28:50 +02:00
tsconfig.base.json Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +02:00

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.

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 up plus a guided first-run setup wizard yields a working instance. Start here: docs/self-hosting/README.md.

Documentation

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.