Skip to content

Architecture

P7CO edited this page Jul 20, 2026 · 6 revisions

Architecture

A layered monorepo: each package has one responsibility and depends only downward. The full decision history lives in docs/adr/.

apps/admin (cms-admin)      Interface: FastAPI + server-rendered UI
packages/cms-cli            Interface: the `cms` command (Typer)
packages/cms-build          Application: deterministic builder, themes, targets
packages/cms-validation     Application: composable validation rules
packages/cms-core           Domain: models, translation states, storage
  • cms-core — content models (articles, pages, sections, media, accounts), the checksum-derived translation-state machinery, and the storage contract with its factory (create_storage(url)) and shared migrations.
  • cms-validation — the rule engine (Rule protocol, RuleSet, Report) and the built-in rules. Publishing is gated on zero errors.
  • cms-build — the deterministic builder (same input → byte-identical output), the head contract (canonical/hreflang/OG/JSON-LD, generated in exactly one place), safe Markdown rendering, localized UI labels, theme discovery and deployment targets.
  • cms-cli — project loading (sardine.toml), the commands, seeding and scaffolding.
  • cms-admin — the browser admin. It drives the packages through public APIs only; the exporter and builder never require the admin to be running.

Key decisions (ADRs)

ADR Decision
0001 Python engine, FastAPI admin, monorepo, SQLite→PostgreSQL, JSON/Markdown as source of truth
0002 Apache-2.0
0003 SQLite persistence with user_version migrations
0004 Storage backend interface + URL factory
0006 Layered architecture (domain / application / interface)
0007 Theme overrides (layered template/asset lookup)
0009 PostgreSQL backend (psycopg 3, optional extra, shared migrations)
0010 Frontend: native web platform, Web-Component islands, no frameworks
0012 Extension discovery via entry points (sardine.themes, targets)
0013 Admin UI: server-rendered FastAPI + Jinja
0014 Distributions: sardine-cms-*, lockstep versions, trusted publishing
0015 Admin styled natively with ph7x (superseded by 0017)
0017 Admin UI on vendored AdminLTE 4 (Bootstrap 5)
0020 Vendored AdminLTE behaviors, no CDN or inline scripts
0027 Design-aware editing with scoped themed preview and autosave
0028 One explicit extension contract for fields, rules, themes, targets and build steps
0029 Opt-in deterministic image derivatives at build time
0030 Foreign blog imports as explicit, offline adapters

Invariants worth knowing

  • Determinism: no wall-clock, no randomness, no dict-order dependence anywhere in the build.
  • The head contract is computed once, from the content model — templates render it, never assemble it.
  • Translation states are always derived from checksums, never stored.
  • The exporter is independent of the admin; static artifacts never require a server.

Clone this wiki locally