59 lines
2.2 KiB
Markdown
59 lines
2.2 KiB
Markdown
# 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.
|
|
|
|
## Components (planned layout)
|
|
|
|
```
|
|
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
|
|
store.rb # reads the content directory into Post objects
|
|
markdown.rb # kramdown wrapper (render + sanitise)
|
|
server.rb # Sinatra app: JSON API + admin routes
|
|
web/
|
|
views/ # ERB templates for the admin
|
|
public/ # admin CSS + the visual-editor JS island
|
|
exe/volumen # CLI: serve, hash-password, version, help
|
|
```
|
|
|
|
## Request flow (planned)
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[HTTP request] --> B{Route}
|
|
B -->|/api/volumen/*| C[JSON API]
|
|
B -->|/admin/*| D[Admin: session + CSRF]
|
|
C --> E[Store]
|
|
D --> E
|
|
E --> F[(content_dir/*.md)]
|
|
C --> G[Markdown renderer]
|
|
D --> G
|
|
```
|
|
|
|
## 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.
|