# 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.