# Dorfteich — Architecture Overview This directory is the authoritative architecture documentation. Every implementation story references the documents here; when a story and this documentation disagree, clarify before coding. ## System context Dorfteich is shipped as a set of Docker containers behind a reverse proxy. One deployment = one **instance** (e.g. `dorfteich.online`, or a self-hosted installation). ```mermaid flowchart LR subgraph clients [Clients] B[Browser SPA
React + TipTap + Yjs] end subgraph instance [Dorfteich instance - Docker Compose] RP[Reverse proxy] WEB[web
static SPA assets] API[api
NestJS REST] COLLAB[collab
Hocuspocus WebSocket] PG[(PostgreSQL)] PAN[pandoc-server
doc conversion] GOT[Gotenberg
HTML to PDF] VOL[/uploads + plugins volume/] end B -- HTTPS --> RP RP --> WEB RP -- /api --> API RP -- /collab WebSocket --> COLLAB API --> PG COLLAB --> PG API --> PAN API --> GOT API --> VOL COLLAB -. permission checks .-> API ``` - **web** serves the single-page application (static assets). - **api** owns all business logic: auth, ponds, pages, labels, permissions, quotas, import/export, plugin management, admin functions. - **collab** synchronizes CRDT documents (page content) and awareness (cursors) over WebSocket and persists document state to PostgreSQL. It authenticates clients with short-lived tokens issued by **api**. - **pandoc-server** and **Gotenberg** are internal-only conversion sidecars (Word/OpenOffice import/export, PDF export). - All page content lives in PostgreSQL; binary uploads (images, attachments) and installed plugins live on a Docker volume. ## Documents ### Architecture Decision Records (`adr/`) | ADR | Decision | | --- | --- | | [0001](adr/0001-typescript-monorepo.md) | TypeScript everywhere, pnpm monorepo | | [0002](adr/0002-postgresql.md) | PostgreSQL as the only database | | [0003](adr/0003-yjs-crdt-collaboration.md) | Yjs CRDT + Hocuspocus for real-time and offline collaboration | | [0004](adr/0004-tiptap-editor.md) | TipTap (ProseMirror) as the WYSIWYG editor | | [0005](adr/0005-react-vite-frontend.md) | React + Vite single-page application | | [0006](adr/0006-nestjs-prisma-backend.md) | NestJS + Prisma for the API server | | [0007](adr/0007-auth-sessions-oidc-ready.md) | Cookie sessions, Argon2id, OIDC-ready identity model | | [0008](adr/0008-plugin-sandbox.md) | Sandboxed iframe plugins with a message-based API | | [0009](adr/0009-import-export-converters.md) | Pandoc + Gotenberg sidecars for import/export | | [0010](adr/0010-postgres-fulltext-search.md) | PostgreSQL full-text search behind a search interface | | [0011](adr/0011-file-storage-quotas.md) | Filesystem volume for uploads, DB-tracked quotas | | [0012](adr/0012-i18n.md) | i18next with German and English from the start | | [0013](adr/0013-versioning-and-trash.md) | Page version history via Yjs snapshots, soft-delete trash | | [0014](adr/0014-gitea-actions-cicd.md) | CI/CD with Gitea Actions, staged promotion | | [0015](adr/0015-backup-strategy.md) | Nightly pg_dump + uploads sync, 30-day retention, off-host mirror | | [0016](adr/0016-self-hosted-fonts.md) | Self-hosted Google Fonts, per-pond font configuration | ### Concept documents | Document | Contents | | --- | --- | | [data-model.md](data-model.md) | Entities and relations: users, ponds, pages, labels, grants, quotas, plugins | | [permissions.md](permissions.md) | Role model and the "most specific setting wins" resolution algorithm | | [realtime-collaboration.md](realtime-collaboration.md) | CRDT document lifecycle, cursor sync, offline behavior, versioning hooks | | [plugin-architecture.md](plugin-architecture.md) | Plugin manifest, packaging, sandbox runtime, extension points, admin flows | | [deployment.md](deployment.md) | Compose stacks for Dev/Test/Int/Prod, environments, promotion pipeline | | [operations.md](operations.md) | Monitoring, logging, backup/restore, update strategy for self-hosters | | [security.md](security.md) | Threat-driven security concept: authn/authz, sandboxing, uploads, secrets | | [roadmap.md](roadmap.md) | Epics and milestones; the order stories are implemented in | ## Terminology | German (product vision) | English (code, docs, issues) | | --- | --- | | Teich | pond | | Seite | page | | Teich-Admin | Pond Admin | | Bearbeitende | Editor | | Lesende | Reader | | Öffentlichkeit | Public | ## Conventions for implementers - Language: English for code, comments, commit messages, and issues. - Write clear, human-readable code; document the "why", not the "what". - UI strings never appear hard-coded — always through i18n resources (see ADR 0012), with German and English translations added in the same change. - Every story lists the ADRs it depends on; read them before starting.