Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

Overview

Substrukt is a single Rust binary that handles everything: web UI, REST API, file storage, background tasks, and database management. There are no external services beyond the filesystem and embedded SQLite.

                          +------------------+
                          |   Web Browser    |
                          | (htmx + twind)   |
                          +--------+---------+
                                   |
                          +--------+---------+
                          |   Axum Router    |
                          |  (tower layers)  |
                          +--------+---------+
                                   |
              +--------------------+--------------------+
              |                    |                     |
     +--------+--------+  +-------+--------+  +---------+---------+
     |  UI Routes       |  |  API Routes    |  |  Metrics/Health   |
     |  (SSR + htmx)    |  |  (/api/v1/*)   |  |  (/metrics)       |
     +--------+---------+  +-------+--------+  +-------------------+
              |                    |
     +--------+--------+  +-------+--------+
     |  Session Auth    |  |  Bearer Token  |
     |  (cookies)       |  |  Auth          |
     +--------+---------+  +-------+--------+
              |                    |
              +--------------------+
                        |
         +--------------+--------------+
         |              |              |
  +------+------+ +-----+-----+ +-----+------+
  |  Schemas    | | Content   | | Uploads    |
  |  (JSON      | | (JSON     | | (SHA-256   |
  |   files)    | |  files)   | |  files)    |
  +------+------+ +-----+-----+ +-----+------+
         |              |              |
         +--------------+--------------+
                        |
                  +-----+------+
                  | Filesystem |
                  | (data dir) |
                  +-----+------+
                        |
         +--------------+--------------+
         |                             |
  +------+------+            +--------+--------+
  | substrukt.db|            |    audit.db     |
  | (users,     |            | (audit log,     |
  |  tokens,    |            |  deployments,   |
  |  apps,      |            |  backup config) |
  |  uploads)   |            +-----------------+
  +-------------+

Request flow

  1. HTTP request arrives at the Axum router
  2. Tower layers run in order: CatchPanic, TraceLayer, metrics tracking, session management
  3. Route matching: UI routes go through session auth middleware; API routes go through bearer token extraction
  4. CSRF verification runs for mutating UI requests (POST/PUT/DELETE)
  5. Handler processes the request, interacting with schemas, content, or uploads
  6. Response is rendered (HTML via minijinja for UI, JSON for API)

Key modules

ModuleResponsibility
main.rsCLI parsing, server startup, shutdown signal
config.rsConfiguration struct and directory helpers
state.rsShared application state (AppState)
templates.rsminijinja environment with auto-reload
cache.rsDashMap content cache, file watcher, populate/rebuild
rate_limit.rsPer-IP sliding window rate limiter
metrics.rsPrometheus recorder and metrics middleware
audit.rsAudit logger with async writes, dirty tracking
webhooks.rsDeployment webhook firing and auto-deploy background tasks
backup.rsS3 backup archive creation and scheduled uploads
history.rsContent version history snapshots
openapi.rsAuto-generated OpenAPI specification
app_context.rsApp-scoped request context extraction
db/SQLite pool initialization and migrations
db/models.rsUser, ApiToken queries
auth/Session management, CSRF, login/logout
auth/token.rsBearer token generation, hashing, extraction
schema/Schema file CRUD and validation
schema/models.rsSubstruktMeta, StorageMode, Kind types
content/Content entry CRUD (directory and single-file)
content/form.rsJSON Schema to HTML form generation and parsing
uploads/Content-addressed file storage
sync/tar.gz export/import
routes/All HTTP route handlers

Technology choices

ComponentTechnologyWhy
Web frameworkAxum 0.8Tower middleware ecosystem, async, type-safe extractors
DatabaseSQLite via sqlxEmbedded, no external service, WAL mode for concurrency
TemplatingminijinjaFast, safe, Jinja2-compatible, auto-reload support
Frontendhtmx + twindNo build step, minimal JS, responsive styling
Content cacheDashMapConcurrent reads without locks, lock-free updates
File watchingnotifyCross-platform filesystem events with debouncing
Metricsmetrics + metrics-exporter-prometheusStandard Prometheus format
Password hashingArgon2Memory-hard, recommended by OWASP
Session storagetower-sessions-sqlx-storeSQLite-backed, integrates with Axum

Concurrency model

  • tokio async runtime handles all I/O
  • DashMap provides lock-free concurrent reads for the content cache
  • Async audit writes – audit log entries are spawned as fire-and-forget tasks
  • File watcher runs in a background thread with debounced events
  • Auto-deploy tasks run as independent background tokio tasks per deployment target
  • Rate limiters use DashMap for lock-free per-IP tracking

Data ownership

DataStored inManaged by
Users, passwordssubstrukt.dbdb/models.rs
Sessionssubstrukt.dbtower-sessions
API tokenssubstrukt.dbdb/models.rs
Upload metadatasubstrukt.dbuploads/mod.rs
Upload referencessubstrukt.dbuploads/mod.rs
SchemasJSON filesschema/mod.rs
Content entriesJSON filescontent/mod.rs
Upload filesBinary filesuploads/mod.rs
Audit logaudit.dbaudit.rs
Deploymentsaudit.dbaudit.rs
Backup configaudit.dbaudit.rs
Appssubstrukt.dbdb/models.rs