System Architecture
Purpose: Comprehensive mental model of the Webspresso runtime, layers, subsystem boundaries, and architectural principles.
1. Architectural Principles #
Webspresso is designed around four core tenets:
- Zero-Dependency Sprawl: Core runtime features (Dual Authentication, JWT signing, Error handling, Streaming Compression, Graceful Shutdown, and Template Helpers) rely strictly on Node.js built-ins (
crypto,path,fs,events,zlib,async_hooks) without bloated npm dependency trees. - File-Based Simplicity: File structure explicitly reflects the application's URL routing (
pages/), API endpoints (pages/api/), and domain business logic (services/). - Ambient Context & Transactions: Leveraging Node.js
AsyncLocalStorage, database transactions propagate seamlessly across nested services and repositories without manual parameter passing (trx). - Isolated Layer Boundaries: The HTTP server layer, business logic services, data repositories, and client admin panel are strictly separated with predictable interfaces.
2. Layered Architecture Overview #
The system processes incoming web traffic through clearly defined horizontal layers:
View diagram source
graph TD
Client["Browser / API Client"] --> HTTP["HTTP Engine (Express 5 Stack)"]
subgraph "Edge & Transport Layer"
HTTP --> Shutdown["Shutdown & Rate-Limiter Boundary"]
Shutdown --> ContextMW["Request Context Container (req.context)"]
ContextMW --> Auth["Dual Auth (Session + Cookie / JWT Middleware)"]
end
subgraph "Routing & Controller Layer"
Auth --> Router["File Router (pages/ & pages/api/)"]
Router -->|SSR Page| SSR["SSR Pipeline (Nunjucks Engine + fsy Helpers)"]
Router -->|JSON API| API["API Validation (Zod req.input)"]
end
subgraph "Domain & Business Logic Layer"
SSR --> Services["Services Layer (core/services)"]
API --> Services
Services --> Pipeline["Service Pipeline (Sanitize → Validate → Auth → Trx → Cache)"]
end
subgraph "Data & Persistence Layer"
Pipeline --> ORM["ORM & Scoped Repositories (core/orm)"]
ORM --> Cache["ORM Query Cache (Memory / Provider)"]
Cache --> Knex["Knex Query Builder"]
Knex --> DB[("SQL Database (SQLite / Postgres / MySQL)")]
end
3. Subsystem Boundaries #
3.1 HTTP Server & Transport (src/server.js)
#
- Mounts Express 5 with streaming zlib compression (
server.compression), connection tracking, and graceful shutdown handlers. - Instantiates Nunjucks with layout search paths, caching controls (
isDev), and circular extension guards. - Establishes
req.contexton every incoming request, attachingreq,res,db,app, andserviceRegistry.
3.2 File-Based Router (src/file-router.js)
#
- Recursively scans
pages/at process boot. - Classifies routes into 4 deterministic registration tiers:
- Static literal paths (e.g.
/about,/users/new) - Nested dynamic paths (e.g.
/users/:id/settings) - Dynamic parameter paths (e.g.
/users/:id) - Catch-all wildcards (e.g.
/*,/docs/*)
- Static literal paths (e.g.
- Manages the SSR
load({ req, res, db, ctx })data prefetching lifecycle and global/route lifecycle hooks (onRequest,onRoute,beforeMiddleware,beforeRender,afterRender,onError).
3.3 Services Layer (core/services/)
#
- Pure business logic layer decoupled from HTTP request objects.
- Automatically maps filesystem paths to dot-separated service names (
services/billing/invoice.js→'billing.invoice'). - Wraps handlers in declarative pipeline middleware: input sanitization against prototype pollution, Zod schema validation, auth role/predicate checks, automatic ACID transaction wrapping (
transaction: true), and caching.
3.4 Knex ORM & Repositories (core/orm/)
#
- Provides schema builder (
zdb) and declarative model definitions (defineModel). - Automatically resolves ambient database transactions via
AsyncLocalStorage(core/orm/transaction.js). - Manages soft delete scopes, tenant filters, relation eager loading (
belongsTo,hasMany,hasOne), and query complexity DoS protection.
3.5 Mithril.js Admin Panel SPA (plugins/admin-panel/)
#
- Standalone single-page CRUD application mounted at configurable admin prefix (default
/_admin). - Employs dedicated staff session isolation (
req.session.adminUser) completely separated from public site authentication. - Automatically wraps custom pages in admin layout and breadcrumbs, supporting custom field renderers, widgets, and bulk table actions.
4. Architectural Rules for Contributors #
- No External Dependencies for Core Features: Never introduce third-party npm packages for authentication, CORS, compression, shutdown, or errors.
- Ambient Transaction Propagation: Repositories must bind to
getAmbientTransaction()rather than expectingtrxto be passed manually through every function argument. - Isolated Component Separation: Custom admin pages and client widgets must reside in standalone JavaScript files (
component.js), never escaped inside inline template strings.