Go to file
Claude Opus 4.8 91dfccf226
All checks were successful
CD / Build and push images (push) Successful in 3m5s
CI / Lint, typecheck, test (push) Successful in 2m19s
CI / Auth e2e pack (push) Successful in 2m51s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m13s
CD / Promote to Int (push) Successful in 12s
Add SearchProvider interface with PostgreSQL FTS (#49)
Full-text search behind a swappable interface (ADR 0010).

- prisma: `page_content_cache.search_vector tsvector` (Unsupported column);
  migration adds it plus a GIN index (raw SQL — the index is a production
  perf optimization; correctness holds without it, so schema-pushed test DBs
  work unchanged).
- shared: `normalizeForSearch` (NFKD + strip diacritics + lowercase) folds
  both the indexed text and the query, so 'Baume' finds 'Bäume' without the
  Postgres `unaccent` extension; search query schema + result view + highlight
  sentinels.
- api search module:
  - abstract `SearchProvider` (DI token: indexPage / removePage / search /
    reindexAll) so an external engine can replace the binding — a fake proves
    the seam in a test.
  - `PostgresSearchProvider`: weighted vector (title A, labels B, body C),
    `websearch_to_tsquery`, `ts_headline` snippets, results filtered to the
    ponds the user may read; `GET /search?q=&pondId=&labels=`.
  - `search:reindex` CLI (rebuilds from the content cache, idempotent).
  - reindex hooks: page create/rename (title) and label assign/unassign/
    rename/delete (labels are weight-B).
- collab: the persistence hook maintains `search_vector` in the same
  transaction as the content cache (same weighting, normalized).
- tests: shared normalize/schema; api db (title ranks above body, highlight,
  diacritic-insensitive match, permission filter, idempotent reindex) and the
  fake-provider DI test; collab persistence already covers the write path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PGdhRiwU1WRL4XxJfZYipY
2026-07-09 13:25:05 +02:00
.gitea/workflows Add backlinks panel and phantom-pages view (#48) 2026-07-09 13:05:32 +02:00
apps Add SearchProvider interface with PostgreSQL FTS (#49) 2026-07-09 13:25:05 +02:00
deploy Add collaboration token issuance and connection authentication (#34) 2026-07-08 15:52:19 +02:00
docs/architecture Add collaboration server skeleton (Hocuspocus) with health, container, and CI/CD (#33) 2026-07-08 14:53:44 +02:00
packages/shared Add SearchProvider interface with PostgreSQL FTS (#49) 2026-07-09 13:25:05 +02:00
scripts Fix e2e static server crashing on an abruptly-dropped collab WebSocket (#38) 2026-07-08 22:34:01 +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 Add file storage service and image upload API (#27) 2026-07-08 10:35:03 +02:00
.prettierignore Add M2 fixtures and content regression pack (#32) 2026-07-08 13:14:48 +02:00
.prettierrc.json Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +02:00
eslint.config.mjs Run the CI auth pack against the production build 2026-07-05 06:16:27 +02:00
LICENSE Add architecture documentation, ADRs, and operations concept 2026-07-04 14:36:16 +02:00
package.json Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +02:00
pnpm-lock.yaml Add offline editing: local persistence, PWA shell, offline resolution (#38) 2026-07-08 22:08:55 +02:00
pnpm-workspace.yaml Add user, identity, session, and auth-support data model 2026-07-05 00:42:22 +02:00
README.md Scaffold pnpm monorepo with lint, format, and test tooling 2026-07-04 19:06:27 +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.

Repository layout

Path Contents
docs/architecture/ Architecture documentation: ADRs, data model, permission model, collaboration and plugin concepts, deployment and operations
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

The project is in the architecture and backlog phase. Implementation stories are tracked as issues in this repository. Start reading at docs/architecture/README.md.

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.