Technical Specifications
A consolidated reference for runtimes, limits, the technology stack and the build/deploy workflow.
Technology stack
Layer | Technology |
|---|---|
Admin UI | React 18 + TypeScript, Vite, Tailwind CSS, React Router, TanStack Query, Zustand |
Lambda runtime | Node.js 22 (nodejs22.x), ES modules |
AWS SDK | AWS SDK for JavaScript v3 (@aws-sdk/*) |
Data store | Amazon DynamoDB (single table, 2 GSIs, on-demand, PITR) |
Object storage | Amazon S3 (asset, component, publish, backup, artifact buckets) |
API | Amazon API Gateway (two endpoints) |
Identity | Amazon Cognito (email login, optional MFA, groups) |
CDN / delivery | Amazon CloudFront (admin app + per-site distributions) |
DNS / TLS | Amazon Route 53 + AWS Certificate Manager |
Email / SMS | Amazon SES / Amazon SNS |
Scheduling | Amazon EventBridge Scheduler (stepwise backup/restore) |
Build & deploy | Maven + the Serverless Maven Plugin |
Packaging | adm-zip (function/backup zips), busboy (multipart uploads) |
Tests | Jest (functions), Vitest (admin UI), fast-check (property tests) |
Function runtime specifications
All functions run on nodejs22.x. Non-default memory/timeout settings:
Function | Memory | Timeout | Role |
|---|---|---|---|
publisher | 1024 MB | 60 s | Render pages to static HTML |
provision-site | 512 MB | 120 s | Provision DNS/TLS/CloudFront/storage |
bulk-publish-worker | 512 MB | 300 s | Render many pages per run |
backup-process-step | 512 MB | 60 s | Gather + stage + zip site content |
delete-site-step | 256 MB | 30 s | Tear a site down |
restore-process-step | 512 MB | 120 s | Restore from a zip (incl. assets) |
platform-status, platform-initialize | default | 300 s | Inspect/seed platform records |
All other cms-functions and public-functions use the platform default memory and timeout.
Data store specification
Content_Store (DynamoDB):
- Composite key PK (S) + SK (S)
- GSI1 (GSI1PK/GSI1SK) and GSI2 (GSI2PK/GSI2SK)
- Billing mode PAY_PER_REQUEST
- Point-in-time recovery enabled
See the Data model for key patterns.
Storage specification
Bucket | Purpose | Notable prefixes |
|---|---|---|
Asset_Store | Media & fonts | assets/{siteId}/… |
Component_Store | Component bundles | {componentId}/component.{html,css,js} |
Publish_Store | Rendered sites | per-site prefixes, sitemap, robots.txt, error.html |
Backup_Store | Backups | backups/{siteId}/{backupId}/backup.zip, …/staging/*.json |
deploy-artifacts | Lambda zips | releases/{group}/…zip |
Domains
Derived from the rootDomain variable in config.json:
Host | Component |
|---|---|
admin.<rootDomain> | Admin UI (Admin_Tool) |
cms-api.<rootDomain> | Admin API (CMS_API) |
api.<rootDomain> | Public delivery API (Public_API) |
<per-site domain> | Published site (CloudFront → Publish_Store) |
The rootDomain must be a registered domain with a Route 53 hosted zone; the plugin provisions DNS records and ACM certificates automatically.
Regions
Deployment region | Components |
|---|---|
global | Auth_Service, Email_Service, SMS_Service |
eu-west-2 | All stores, function groups, both APIs and the admin site |
Known limits & how they're handled
Limit | Mitigation |
|---|---|
DynamoDB item ≤ 400 KB | Bulk data kept in S3; backups stage slices in Backup_Store rather than on the record |
Lambda timeout | Long jobs are stepwise (backup/restore, provisioning, bulk publish) and rescheduled via EventBridge Scheduler |
Cold starts | SDK clients are created once at module scope and reused across warm invocations |
Large sites | Publishing is per-page; whole-site work runs in background workers |
Configuration surface
The deployment is controlled by src/main/serverless/config.json:
Field | Purpose |
|---|---|
name, application | Project identity |
provider | Cloud provider (aws) |
credentials | Deploy credentials (profile-based) |
variables.rootDomain | Base domain for all hostnames |
variables.version | Release version, interpolated into artifact paths |
regions[] | Which components deploy to which region |
Per-component settings live in src/main/serverless/components/*.json and are summarised in the component inventory.
Build & deploy workflow
The project builds with Maven, which packages the admin UI and each Node.js function group into artifacts, then deploys them via the Serverless Maven Plugin goals:
# Build all artifacts (admin UI + function zips)
mvn clean package
# Validate the serverless configuration
mvn serverless:validate
# Preview the changes that would be applied
mvn serverless:plan
# Deploy to AWS
mvn serverless:deploy
# Verify health after deploy
mvn serverless:verify
# Tear everything down
mvn serverless:undeploy
Function code is deployed as zips uploaded to the deploy-artifacts bucket and referenced by each functions component's codePath. The admin UI zip is unpacked onto the Admin_Tool website bucket.
For step-by-step setup (AWS account prerequisites, domain configuration,
initial platform seeding and verification), follow the
installation guide.
Testing & quality
- Functions: Jest unit tests plus fast-check property tests (run per package with npm test). Bundled components are synced before the cms-functions suite via scripts/sync-bundled-components.sh.
- Admin UI: Vitest + Testing Library, with @fast-check/vitest for property-based tests; ESLint and tsc --noEmit for static checks.
- Config: the serverless configuration is validated (mvn serverless:validate) before deployment.
_Back to the architecture index._