Files
volumen/docs/architecture.md
T

70 lines
2.7 KiB
Markdown
Raw Permalink Normal View History

# Architecture
> Status: the core library, the public JSON API, and the server-rendered admin
> (login, CSRF, post CRUD, Markdown editor + live preview) are implemented.
**volumen** is a small, file-based Markdown blog engine written in CRuby. It
has no database: every post is a `.md` file on disk with a TOML frontmatter
block. The engine reads those files, exposes them as a JSON API, and ships a
server-rendered admin for editing them.
## Design goals
- **File-based** — posts are plain `.md` files, safe to commit to Git and edit
by hand or through the admin.
- **Single-admin** — one password, one content directory, one user.
- **Self-contained** — runs as a single Ruby process; no Node build step is
required to operate the engine or its admin.
- **Dependency-light** — a small, well-chosen set of gems (Sinatra, kramdown,
toml-rb, puma) rather than a full framework.
- **Markdown-first** — the visual editor round-trips through the same renderer
that powers the public API, so stored content is always Markdown.
2026-07-12 14:03:14 +02:00
## Components
```
lib/volumen/
version.rb # gem version
config.rb # loads /etc/volumen/config.toml, applies CLI overrides
frontmatter.rb # parse/serialise the `+++ … +++` TOML block
post.rb # Post model: metadata + raw body + rendered HTML
2026-07-12 14:03:14 +02:00
store.rb # reads the content directory into Post objects (mtime-cached)
markdown.rb # kramdown wrapper (render + <figure>/<figcaption> for titled images)
feed_helpers.rb # RSS / JSON Feed / sitemap generation
users.rb # users.toml + admin/author roles
password.rb # scrypt hashing/verification (OpenSSL::KDF)
api_routes.rb # /api/volumen/* (Sinatra routes)
admin_routes.rb # /admin/* (Sinatra routes)
server.rb # Sinatra app: composes the two route modules, shared helpers
cli.rb # command dispatcher
web/
views/ # ERB templates for the admin
2026-07-12 14:03:14 +02:00
public/ # static assets (volumen-logo.svg, volumen-icon.svg)
exe/volumen # CLI: serve, hash-password, version, help
```
2026-07-12 14:03:14 +02:00
## Request flow
```mermaid
graph TD
A[HTTP request] --> B{Route}
2026-07-12 14:03:14 +02:00
B -->|/api/volumen/*| C[api_routes.rb]
B -->|/admin/*| D[admin_routes.rb + CSRF + CSP]
C --> E[Store]
D --> E
2026-07-12 14:03:14 +02:00
D --> U[Users]
C --> F[FeedHelpers]
C --> G[Markdown renderer]
2026-07-12 14:03:14 +02:00
E --> H[(content_dir/*.md)]
E --> I[(content_dir/media/*)]
U --> J[(users.toml)]
F --> E
G --> K[<figure> for titled images]
```
## Public site integration
The public website (e.g. `petrbalvin.org`, a Vue 3 + Vite + Tailwind SPA)
consumes volumen's JSON API. volumen does not render the public site itself; it
is headless for the front-end and only renders its own admin.