Application Architecture
The layers of the backend, how tenants and languages work, and how a page reaches a reader.
Layers
Websites controllers only: they delegate
│
Services business logic and all validation
│
Abstractions repository interfaces
│
Data SQL Server and PostgreSQL implementations (Dapper)- Controllers hold no logic.
- Services depend on repository interfaces, never on a concrete class.
- Validation lives in services, not in controllers or repositories.
- Deployment is Linux and Docker. There are no Windows dependencies.
Tenants
A tenant is a subscription. Every tenant-owned row carries its subscription id, and a service resolves the current subscription from configuration or from the request’s host.
Subscriptions, their configs, roles and users are cached in process at boot. That is why a tenant has to exist before an API starts, and why a config changed directly in the database needs a restart.
One widget model, many surfaces
An editor lays out a page in the portal’s page builder as rows, columns and widgets. A widget record carries one view path per rendering surface: web, mobile, tablet, AMP, TV and headless.
A client website is the headless surface. It asks the Public API for a page with
?platform=headless and receives a list of widgets. Each has a code and a style, and the
site’s dispatcher picks a component by style.
Two consequences:
- Changing a widget’s headless style in the portal changes a live website.
- A style the site does not implement is saved, served, and rendered as nothing. Nothing warns. When a section does not appear, check the style first.
Roles and permissions
An endpoint is in one of four tiers: Public (anonymous), Lookup (any signed-in user),
Page (page:<screen>, which opens a screen and authorises its reads) and Action
(resource:verb, which authorises a write).
The two key shapes never cross. posts:* covers every posts: action and does not open the
Posts screen.
The portal never decides access itself. It asks the server, which answers from the same registry and evaluator that guard the endpoints.
Operations
Work that takes time (social sends, video uploads, preview clips) is an operation. The
Operations table is the queue: the Portal API queues an operation and the operations worker
claims it, renews a lease while it runs, and ends it. A worker that dies stops renewing, and
another worker takes the operation over.