Skip to content

Architecture

AISiteEngine is a Nuxt dashboard on top of per-site Cloudflare infrastructure. There is no shared content database across clients — each site owns its own.

┌───────────────────────────────┐
Editors ──►│ Dashboard (Nuxt 4, SPA) │
└───────────────┬───────────────┘
│ HTTPS + JWT
▼
┌───────────────────────────────┐
│ AISiteEngine API │
│ auth · site scope · caps │
└───────────────┬───────────────┘
│
┌─────────────┴──────────────┐
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ D1 (per site) │ │ R2 (per site) │
│ content, media, │ │ images, documents │
│ users, roles, │ └────────────────────┘
│ taxonomies, terms │
└─────────┬──────────┘
│ build
▼
┌────────────────────────────────────────┐
│ Astro static site → Cloudflare Pages│
└────────────────────────────────────────┘
Visitors ────────────────────────────────────►

A Nuxt 4 single-page app. It holds no data of its own: every list, form and save is an API call. Its job is interaction — tables, the editor, media browsing, role management.

The single entry point for reads and writes. Before touching data it checks:

  1. Authentication — a signed JWT in the Authorization header.
  2. Site scope — the token’s site must match the record’s site.
  3. Capabilities — the token’s capability list must allow the operation.

The same checks run whether the call comes from the dashboard, a script or an MCP client.

Service Holds
D1 Content records, media metadata, users, roles, taxonomies, terms, collections
R2 The media files themselves (images, PDFs)
Pages The compiled Astro site

All three live in the client’s own Cloudflare account, which is what makes exit painless: the data and the site never leave the owner’s account.

Editing

browser → dashboard (Nuxt) → API (JWT) → D1 / R2 → response

Reading the site

visitor → Cloudflare edge cache → Pages (static HTML) → browser

Visitors never touch the API or the database. They get pre-built HTML, which is why pages stay fast under load.

Content saved in the dashboard is written to D1 immediately. The public site reflects it after the next build: Astro reads the content set, generates one page per record, and Pages serves the result.

  • The dashboard is treated as untrusted. Hiding a button is a convenience, never a security control.
  • The API trusts only a verified token, never a header or query parameter claiming an identity.
  • Media URLs are public by design; they contain no secrets.