# perber/leafwiki architecture

> Architecture diagram of the GitHub repository perber/leafwiki, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-18). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/perber/leafwiki
- Repository: https://github.com/perber/leafwiki

## Overview

1. **Overall shape**
   LeafWiki is a **single Go backend binary** that serves both the API and the built frontend. It stores **page content as Markdown on disk** and uses **SQLite for metadata/indexing state**. The architecture is intentionally simple: a local data directory plus an HTTP server, with no external DB or queue dependencies.

2. **Entry points and process startup**
   The main runtime is `cmd/leafwiki/main.go`. From there, the server is configured by CLI flags / env vars such as host, port, data directory, base path, auth mode, revision history, and link refactoring. The binary also exposes an admin reset command, and the Docker/container scripts mainly adjust defaults like binding to `0.0.0.0`.

3. **Backend layering**
   The backend is split into:
   - `internal/wiki/*`: application use cases and route wiring
   - `internal/core/*`: domain services and persistence-facing logic
   - `internal/http/*`: HTTP router, middleware, DTOs, and static asset serving  
   This separation matters: the HTTP layer is thin, the wiki layer coordinates user-facing operations, and the core layer owns business rules like pages, links, tags, auth, search, revisions, and importing.

4. **Primary domain boundary: pages and the tree**
   The central model is a **hierarchical wiki tree**, not a flat note list. Tree and slug behavior live in `internal/core/tree`, with page records, path lookup, and node storage. Higher-level page actions in `internal/wiki/pages` cover create, update, move, copy, delete, convert, and path ensuring. This is the main data model most other features hang off.

5. **Save pipeline and side effects**
   Page saves are not a single write; they flow through `internal/wiki/pagesave`, which orchestrates effects after content changes. The save pipeline updates:
   - link data
   - tags
   - properties / frontmatter
   - search index
   - revisions, if enabled  
   This is a key architectural boundary: editing a page triggers multiple synchronized subsystems.

6. **Content intelligence: Markdown, links, tags, properties**
   Markdown parsing and frontmatter handling are in `internal/core/markdown`. Link extraction/refactoring/backlinks are in `internal/links`. Tags have their own service/store in `internal/tags`. Page metadata/property handling is in `internal/properties`. Together these form the content analysis layer that powers backlinks, broken links, tag views, page metadata, and link rewriting on rename/move.

7. **Persistence model**
   Persistence is mixed:
   - **Markdown files / assets on disk** for readable page content and uploads
   - **SQLite** for structured state such as tree metadata, users/sessions, search index, tags/links/properties, and other app state  
   There are dedicated stores under `internal/core/*/*_store.go`, plus SQLite utilities in `internal/core/shared/sqliteutil` and search indexing in `internal/search/sqlite_index.go`. The filesystem is also used for revisions (`internal/core/revision/fs_store.go`) and imports/extracted archives.

8. **Authentication, sessions, and security**
   Auth is a first-class subsystem under `internal/core/auth` and `internal/wiki/auth`. It supports roles (admin, editor, viewer), JWT-based sessions, password/login flows, and reverse-proxy auth via trusted headers. Security middleware adds CSRF protection, rate limiting, secure cookies, and secure transport checks. The app also supports `--disable-auth` and `--public-access`, which change the request authorization boundary substantially.

9. **Import, backup, and maintenance operations**
   There are operational subsystems for content lifecycle outside normal page editing:
   - `internal/importer`: ZIP extraction, workspace/planning, content transformation, import execution
   - `internal/backup`: repository backup scheduling/status and `.gitignore` handling
   - `internal/core/tools`: admin reset utilities
   - `internal/core/treemigration`: structural migrations of the page tree  
   These are separate from the live editor flow and are exposed through their own routes/use cases.

10. **HTTP API and route organization**
   `internal/http/router.go` and `internal/http/registrar.go` assemble the API, middleware, and route groups. The `internal/wiki/*/routes.go` files define feature-specific endpoints for pages, auth, search, tags, links, revisions, importer, assets, backup, branding, and health. This makes the public surface modular: each feature has its own route/use-case pair rather than one monolithic controller.

11. **Frontend architecture**
   The UI lives in `ui/leafwiki-ui` as a **React + Vite** application. It is organized by feature folders rather than by generic component type:
   - editor, viewer, tree, search, tags, auth, importer, backup, branding, users, shortcuts, toolbar, etc.  
   Frontend state is split across stores in `src/stores`, while API access is wrapped in `src/lib/api/*`. The app is built to consume the Go backend’s REST endpoints and render the wiki experience, including dialogs, sidebar tree, page viewer/editor, and mobile-friendly navigation.

12. **Frontend-to-backend data flow**
   User actions in the UI typically flow as:
   **React feature component → store/API client → HTTP endpoint → wiki use case → core service/store → SQLite/filesystem**
   The reverse flow for display is the backend shaping DTOs in `internal/http/dto` and the frontend using those responses to populate the tree, viewer, editor, search, and metadata panels. This split is especially visible for page editing, where the UI must coordinate optimistic changes, autosave, navigation guards, and conflict handling.

13. **Import/export and media handling**
   Assets are treated separately from page Markdown. The backend has an assets subsystem (`internal/core/assets`, `internal/wiki/assets`) and the UI includes asset managers and upload/preview features. Importing ZIP archives can bring in pages and attachments, with special handling for Obsidian-style wiki links and nested folder structures.

14. **Testing and deployment signals**
   The repo is built around a strong test surface: Go unit/integration tests across core services, Playwright-based end-to-end tests in `e2e`, and a dedicated proxy-auth e2e harness in `e2e-proxy`/`hacks/proxy-auth`. CI workflows cover backend, frontend, E2E, linting, dependency review, and release. Deployment is mainly via Docker, a Linux installer, or a standalone binary, which reinforces the “single-process, self-hosted” architecture.

Main entry points: [`internal/wiki/pagesave`](https://github.com/perber/leafwiki/tree/main/internal/wiki/pagesave) (Save Pipeline), [`ui/leafwiki-ui/src/features`](https://github.com/perber/leafwiki/tree/main/ui/leafwiki-ui/src/features) (Feature UI), [`internal/wiki/wiki.go`](https://github.com/perber/leafwiki/blob/main/internal/wiki/wiki.go) (Wiki API), [`internal/http/router.go`](https://github.com/perber/leafwiki/blob/main/internal/http/router.go) (HTTP Router)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_cmd_main["Main<br/>Go entrypoint<br/>[main.go]"]
end

subgraph group_backend["Backend"]
  node_http_router["HTTP Router<br/>HTTP assembly<br/>[router.go]"]
  node_http_registrar["Route Registrar<br/>route wiring<br/>[registrar.go]"]
  node_http_middleware["Middleware<br/>security/auth"]
  node_wiki_facade["Wiki API<br/>use-case facade<br/>[wiki.go]"]
  node_pages_uc["Pages<br/>page use cases"]
  node_pagesave["Save Pipeline<br/>save orchestration"]
  node_tree_core["Tree Model<br/>hierarchy service"]
  node_markdown_core["Markdown<br/>content parser"]
  node_links_core["Links<br/>link graph"]
  node_tags_core["Tags<br/>tag service"]
  node_properties_core["Properties<br/>metadata service"]
  node_search_core["Search<br/>sqlite index"]
  node_revision_core["Revisions<br/>history store"]
  node_auth_core["Auth<br/>identity/session"]
  node_assets_core["Assets<br/>media store"]
end

subgraph group_frontend["Frontend"]
  node_ui_app["UI App<br/>React/Vite app<br/>[App.tsx]"]
  node_ui_features["Feature UI<br/>feature modules"]
  node_ui_api["API Client<br/>frontend API layer"]
end

subgraph group_ops["Operations"]
  node_importer["Importer<br/>zip import"]
  node_backup["Backup"]
end

node_cmd_main -->|"starts server"| node_http_router
node_cmd_main -->|"wires app"| node_wiki_facade
node_http_router -->|"registers"| node_http_registrar
node_http_router -->|"applies"| node_http_middleware
node_http_registrar -->|"dispatches to"| node_wiki_facade
node_wiki_facade -->|"pages"| node_pages_uc
node_wiki_facade -->|"auth"| node_auth_core
node_wiki_facade -->|"import"| node_importer
node_wiki_facade -->|"backup"| node_backup
node_pages_uc -->|"uses"| node_tree_core
node_pages_uc -->|"saves through"| node_pagesave
node_pagesave -->|"parses"| node_markdown_core
node_pagesave -->|"updates"| node_links_core
node_pagesave -->|"updates"| node_tags_core
node_pagesave -->|"updates"| node_properties_core
node_pagesave -->|"indexes"| node_search_core
node_pagesave -->|"records"| node_revision_core
node_links_core -->|"renames with"| node_tree_core
node_search_core -->|"indexes pages"| node_tree_core
node_importer -->|"creates"| node_tree_core
node_importer -->|"extracts assets"| node_assets_core
node_ui_app -->|"composes"| node_ui_features
node_ui_features -->|"calls"| node_ui_api
node_ui_api -->|"requests"| node_http_router
node_ui_features -->|"edit pages"| node_pages_uc
node_ui_features -->|"run imports"| node_importer
node_ui_features -->|"manage backups"| node_backup
node_ui_features -->|"authenticate"| node_auth_core

click node_cmd_main "https://github.com/perber/leafwiki/blob/main/cmd/leafwiki/main.go"
click node_http_router "https://github.com/perber/leafwiki/blob/main/internal/http/router.go"
click node_http_registrar "https://github.com/perber/leafwiki/blob/main/internal/http/registrar.go"
click node_http_middleware "https://github.com/perber/leafwiki/tree/main/internal/http/middleware"
click node_wiki_facade "https://github.com/perber/leafwiki/blob/main/internal/wiki/wiki.go"
click node_pages_uc "https://github.com/perber/leafwiki/tree/main/internal/wiki/pages"
click node_pagesave "https://github.com/perber/leafwiki/tree/main/internal/wiki/pagesave"
click node_tree_core "https://github.com/perber/leafwiki/tree/main/internal/core/tree"
click node_markdown_core "https://github.com/perber/leafwiki/tree/main/internal/core/markdown"
click node_links_core "https://github.com/perber/leafwiki/tree/main/internal/links"
click node_tags_core "https://github.com/perber/leafwiki/tree/main/internal/tags"
click node_properties_core "https://github.com/perber/leafwiki/tree/main/internal/properties"
click node_search_core "https://github.com/perber/leafwiki/tree/main/internal/search"
click node_revision_core "https://github.com/perber/leafwiki/tree/main/internal/core/revision"
click node_auth_core "https://github.com/perber/leafwiki/tree/main/internal/core/auth"
click node_importer "https://github.com/perber/leafwiki/tree/main/internal/importer"
click node_backup "https://github.com/perber/leafwiki/tree/main/internal/backup"
click node_assets_core "https://github.com/perber/leafwiki/tree/main/internal/core/assets"
click node_ui_app "https://github.com/perber/leafwiki/blob/main/ui/leafwiki-ui/src/App.tsx"
click node_ui_features "https://github.com/perber/leafwiki/tree/main/ui/leafwiki-ui/src/features"
click node_ui_api "https://github.com/perber/leafwiki/tree/main/ui/leafwiki-ui/src/lib/api"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cmd_main toneBlue
class node_http_router,node_http_registrar,node_http_middleware,node_wiki_facade,node_pages_uc,node_pagesave,node_tree_core,node_markdown_core,node_links_core,node_tags_core,node_properties_core,node_search_core,node_revision_core,node_auth_core,node_assets_core toneAmber
class node_ui_app,node_ui_features,node_ui_api toneMint
class node_importer,node_backup toneRose
```

## Components

### Runtime

Single Go binary plus the built web UI it serves

- [Main](https://github.com/perber/leafwiki/blob/main/cmd/leafwiki/main.go): Go entrypoint · CLI flags, env config, startup, and admin reset command · `cmd/leafwiki/main.go`

### Backend

Go API, wiki use cases, domain services, and persistence

- [HTTP Router](https://github.com/perber/leafwiki/blob/main/internal/http/router.go): HTTP assembly · Registers middleware, routes, and static asset serving · `internal/http/router.go`
- [Route Registrar](https://github.com/perber/leafwiki/blob/main/internal/http/registrar.go): route wiring · Builds feature route groups and attaches handlers · `internal/http/registrar.go`
- [Middleware](https://github.com/perber/leafwiki/tree/main/internal/http/middleware): security/auth · Auth, CSRF, rate limiting, secure cookies, and proxy trust checks · `internal/http/middleware`
- [Wiki API](https://github.com/perber/leafwiki/blob/main/internal/wiki/wiki.go): use-case facade · Coordinates feature-specific use cases and routes · `internal/wiki/wiki.go`
- [Pages](https://github.com/perber/leafwiki/tree/main/internal/wiki/pages): page use cases · Create, update, move, copy, delete, convert, and path ensuring · `internal/wiki/pages`
- [Save Pipeline](https://github.com/perber/leafwiki/tree/main/internal/wiki/pagesave): save orchestration · Runs link, tag, property, search, and revision side effects after edits · `internal/wiki/pagesave`
- [Tree Model](https://github.com/perber/leafwiki/tree/main/internal/core/tree): hierarchy service · Hierarchical page tree, slugs, lookups, node storage, and migrations · `internal/core/tree`
- [Markdown](https://github.com/perber/leafwiki/tree/main/internal/core/markdown): content parser · Markdown and frontmatter parsing/serialization · `internal/core/markdown`
- [Links](https://github.com/perber/leafwiki/tree/main/internal/links): link graph · Backlinks, outgoing links, extraction, and refactoring · `internal/links`
- [Tags](https://github.com/perber/leafwiki/tree/main/internal/tags): tag service · Tag extraction and tag store · `internal/tags`
- [Properties](https://github.com/perber/leafwiki/tree/main/internal/properties): metadata service · Frontmatter-backed page properties and property store · `internal/properties`
- [Search](https://github.com/perber/leafwiki/tree/main/internal/search): sqlite index · Search indexing and result retrieval · `internal/search`
- [Revisions](https://github.com/perber/leafwiki/tree/main/internal/core/revision): history store · Filesystem-backed revision history and restore support · `internal/core/revision`
- [Auth](https://github.com/perber/leafwiki/tree/main/internal/core/auth): identity/session · Roles, login, JWT sessions, proxy auth, and user/session stores · `internal/core/auth`
- [Assets](https://github.com/perber/leafwiki/tree/main/internal/core/assets): media store · Uploads and asset lifecycle on disk · `internal/core/assets`

### Frontend

React/Vite UI organized by feature

- [UI App](https://github.com/perber/leafwiki/blob/main/ui/leafwiki-ui/src/App.tsx): React/Vite app · Browser UI served by the backend binary · `ui/leafwiki-ui/src/App.tsx`
- [Feature UI](https://github.com/perber/leafwiki/tree/main/ui/leafwiki-ui/src/features): feature modules · Editor, viewer, tree, search, tags, auth, importer, backup, and branding screens · `ui/leafwiki-ui/src/features`
- [API Client](https://github.com/perber/leafwiki/tree/main/ui/leafwiki-ui/src/lib/api): frontend API layer · Typed clients for backend REST endpoints · `ui/leafwiki-ui/src/lib/api`

### Operations

Import, backup, deployment, and maintenance flows

- [Importer](https://github.com/perber/leafwiki/tree/main/internal/importer): zip import · ZIP extraction, planning, transformation, and execution · `internal/importer`
- [Backup](https://github.com/perber/leafwiki/tree/main/internal/backup): repo backup · Backup scheduling, status, and gitignore handling · `internal/backup`

## Connections

- Main → HTTP Router: starts server · Main binary configures and launches the HTTP server
- Main → Wiki API: wires app · Bootstraps wiki services and use cases
- HTTP Router → Route Registrar: registers · Router composes feature route groups
- HTTP Router → Middleware: applies · Security and auth middleware wrap requests
- Route Registrar → Wiki API: dispatches to · Feature handlers call into wiki use cases
- Wiki API → Pages: pages · Page operations are coordinated through the wiki layer
- Wiki API → Auth: auth · Login, sessions, roles, and proxy auth flow through the auth subsystem
- Wiki API → Importer: import · Import routes and use cases execute content ingestion
- Wiki API → Backup: backup · Backup settings and status are exposed through wiki operations
- Pages → Tree Model: uses · Page actions operate on the hierarchical tree model
- Pages → Save Pipeline: saves through · Content edits flow into the save pipeline
- Save Pipeline → Markdown: parses · Save processing reads/writes markdown and frontmatter
- Save Pipeline → Links: updates · Link extraction and refactoring are synchronized after edits
- Save Pipeline → Tags: updates · Tag state is refreshed on save
- Save Pipeline → Properties: updates · Frontmatter properties are synchronized on save
- Save Pipeline → Search: indexes · Search index is refreshed after content changes
- Save Pipeline → Revisions: records · Revision history is written when enabled
- Links → Tree Model: renames with · Link refactoring follows tree moves and slug changes
- Search → Tree Model: indexes pages · Search uses page/tree metadata for lookup and results
- Importer → Tree Model: creates · Imports materialize content into the wiki tree
- Importer → Assets: extracts assets · ZIP imports can include attachments and media
- UI App → Feature UI: composes · Application shell mounts feature modules
- Feature UI → API Client: calls · Feature views use API clients for server data
- API Client → HTTP Router: requests · Frontend talks to backend REST endpoints
- Feature UI → Pages: edit pages · Editor, tree, viewer, and dialogs drive page operations
- Feature UI → Importer: run imports · Importer screen invokes import workflows
- Feature UI → Backup: manage backups · Backup settings and status are surfaced in the UI
- Feature UI → Auth: authenticate · Login and role-gated UI depends on auth state
