# Platform Deep Dive

Everything under the hood — and why it's there.

By AgentSite · Updated 2026-05-23

## The Platform

This isn't a boilerplate. It's a production‑grade SaaS foundation built from years of shipping real products — every layer deliberate, every pattern battle‑tested. Here's everything under the hood.

## Architecture Overview

External  
Data  
Application  
Edge  
Client  

Vue 3 SPA  
Service Worker  
CDN / Static Assets  
Load Balancer  
NestJS API Server  
WebSocket Gateway  
Mastra AI Agents  
Scheduled Jobs  
PostgreSQL  
Redis - Sessions  
Stripe Billing  
SendGrid Email  
Google OAuth  
Uploadcare CDN  

## Authentication & Identity

Four auth strategies, zero compromise. Every path leads to a secure JWT session stored in HTTP‑only cookies — not localStorage, not session tokens in headers. Cookies. Because the browser's built-in security model is better than anything we'd build.

Protected  
Auth Pipeline  
Entry Points  
Magic Link Email  
Password + Argon2  
Google OAuth  
Ghost Mode  
Validate Credentials  
Sign JWT  
Set HTTP‑Only Cookie  
Create Session  
AuthGuard  
Role Check  
API Access  

**Magic Links** — Passwordless login. User enters email, gets a signed token link, clicks it, done. No password to forget, no credential stuffing to worry about. The token is single‑use, time‑limited, and tied to the requesting IP.

**Password Auth** — Argon2id hashing. Not bcrypt, not SHA‑256. Argon2id — memory‑hard, GPU‑resistant, winner of the Password Hashing Competition. Password reset flows with signed tokens, not security questions.

**Google OAuth** — One‑click sign‑in with automatic account linking. If the email already exists, it links. If not, it creates. No friction, no "which account did I use?" confusion.

**Ghost Mode** — Development and demo sessions without real accounts. Perfect for trade shows, investor demos, or automated testing. Full platform access with a synthetic identity that self‑destructs.

**Role‑Based Access** — Three decorator‑driven authorization levels: `@Public()` (no auth), `@RequireAuth()` (any authenticated user), `@RequireEdit()` (admin/editor). Applied at the controller method level. No middleware chains to debug.

## Database Philosophy

### Flyway Over ORMs

We use Flyway for migrations. Not TypeORM migrations, not Knex migrations, not Prisma migrations. Flyway.

Why? Because database migrations are **SQL**. They should be written in SQL, reviewed as SQL, and executed as SQL. ORM‑generated migrations are a leaky abstraction — they guess what you want, generate bloated DDL, and break in ways that are hard to debug.

Guarantees  
Migration Pipeline  
Developer writes SQL  
Versioned file: V01__description.sql  
Flyway validates + applies  
PostgreSQL  
flyway_schema_history table  
Strict ordering  
Checksum verification  
Repeatable migrations  
Full audit trail  

Every migration is a versioned `.sql` file: `V01__create_users.sql`, `V02__add_billing_tables.sql`. Flyway checksums them — if someone modifies a migration that already ran, deployment fails. Loudly. That's a feature.

The result: migrations that are readable, auditable, and identical across every environment. No ORM version drift. No "works on my machine."

### TypeORM for Application Code

TypeORM handles the application layer — entity mapping, query building, repository pattern. But it doesn't touch the schema. Clean separation: SQL owns the structure, TypeORM owns the access.

**Snake case everywhere.** A `NamingStrategy` maps TypeScript's `camelCase` properties to PostgreSQL's `snake_case` columns automatically. No `@Column({ name: 'user_id' })` decorators cluttering entity files.

**Entities are simple.** No active record pattern, no lifecycle hooks on entities, no magic. An entity is a typed row. Services contain the logic.

## Entity System

has  
has  
has  
has  
has  
has  
references  
parent  
receives  

User  
string  
id  
PK  
string  
email  
string  
name  
string  
role  
string  
status  

Membership  
string  
id  
PK  
string  
userId  
FK  
string  
orgId  
FK  
string  
role  

Session  

Profile  

Organization  
string  
id  
PK  
string  
name  
string  
slug  
string  
domain  

Subscription  

BillingCustomer  

Plan  

Content  
string  
id  
PK  
string  
slug  
string  
title  
string  
type  
string  
status  
jsonb  
metadata  
text  
data  

Form  
string  
id  
PK  
string  
title  
jsonb  
schema  
string  
status  

FormResponse  

Every entity ID is generated with **ashid** — prefixed, collision‑resistant, sortable identifiers. `usr_abc123`, `org_def456`, `cnt_ghi789`. You can look at an ID and know what it is. Grep a log file and find every user mention. No UUIDs, no auto‑incrementing integers leaking your row count.

## Billing & Subscriptions

Full Stripe integration — not a wrapper, not a "billing microservice." Direct Stripe API usage with webhook‑driven state management.

StripeBackendFrontendUserStripeBackendFrontendUserSelect PlanPOST /billing/checkoutCreate Checkout SessionSession URLRedirect URLStripe Checkoutwebhook: checkout.session.completedCreate Subscription RecordUpdate Organization Planwebhook: invoice.paidExtend Subscription Periodwebhook: customer.subscription.deletedDowngrade to Free  

**Checkout Sessions** — Not custom payment forms. Stripe Checkout handles PCI compliance, 3D Secure, Apple Pay, Google Pay, and every edge case we'd never think to handle.

**Webhook‑Driven** — Subscription state is never polled. Stripe tells us when something changes. `invoice.paid`, `customer.subscription.updated`, `customer.subscription.deleted` — each one triggers precise state transitions.

**Plan Enforcement** — Middleware checks subscription status on protected routes. Expired? Graceful degradation, not a brick wall. Usage limits? Tracked per‑organization with clear upgrade paths.

## Admin Dashboard

A full admin panel at `/admin` with granular control over every entity in the system. Not a bolted‑on afterthought — it's built with the same component library (NaiveUI) and shares the same API layer.

**What's in the admin:**

- **User Management** — Search, filter, view activity, impersonate, suspend, change roles  
- **Organization Management** — View members, subscription status, usage metrics  
- **Content Editor** — WYSIWYG markdown editing with live preview, draft/publish workflow  
- **Form Builder** — Dynamic form creation with schema‑driven fields  
- **Billing Overview** — Subscription status across all organizations, revenue metrics  
- **System Health** — Active sessions, error rates, webhook delivery status  

Every admin action is audit‑logged. Who did what, when, to what entity. Not optional, not configurable — always on.

## Content Management System

A file‑based CMS that syncs markdown files to the database on startup. No headless CMS vendor, no API rate limits, no monthly fees.

Delivery  
Database  
ContentSyncService  
File System  

content/about.md  
content/blog/post-1.md  
content/platform.md  

Parse YAML Frontmatter  
Date‑Based Merge  
Upsert to DB  

Content Table  

GET /content/:slug  

Markdown Component  
Mermaid Renderer  

**Date‑Based Merge** — File wins only if its date is newer than the database record. Edit content in the admin panel? Those changes stick until the file is explicitly updated. No accidental overwrites.

**YAML Frontmatter** — Standard metadata: slug, title, type, status, date. Arbitrary metadata in a nested object for flexibility.

**Mermaid Diagrams** — Fenced code blocks with `mermaid` language tags render as interactive SVG diagrams. Architecture charts, flow diagrams, sequence diagrams — all in markdown.

**Admin Editing** — Content synced from files can also be edited through the admin CMS. The merge strategy ensures neither side clobbers the other.

## Frontend Architecture

### Component System

Vue 3 with TypeScript, class‑based components via `vue-facing-decorator`, and auto‑imported components via `unplugin-vue-components`. Write a component, use it anywhere — no import statements needed.

Syntax error in textmermaid version 11.17.0

### File‑Based Routing

No router configuration files. Drop a `.vue` file in `src/pages/`, it becomes a route. `pages/about/index.vue` → `/about`. `pages/settings/billing.vue` → `/settings/billing`. Nested layouts, dynamic segments, route meta — all from file conventions.

### Design Token System

CSS custom properties mirrored in TypeScript. Change a color in one place, it updates across CSS, Tailwind utilities, NaiveUI theme overrides, and Storybook simultaneously.

```typescript
// design-tokens.ts — single source of truth
export const colors = {
  brand: {
    primary: 'var(--color-brand-primary)',     // #11203C
    accent: 'var(--color-brand-accent)',        // #DDDAC0
    secondary: 'var(--color-brand-secondary)',  // #0e7490
  },
  ui: {
    bgPrimary: 'var(--ui-bg-primary)',         // #09090b
    textPrimary: 'var(--ui-text-primary)',      // #fafafa
  }
} as const
```

### Tailwind CSS v4

No `tailwind.config.js`. Tailwind v4 uses CSS‑native configuration with `@theme` blocks. Custom utilities defined with `@utility`. A Vite plugin auto‑injects `@reference` directives into Vue style blocks — Tailwind utilities work everywhere without manual imports.

### Rich Text Editing

Tiptap editor with markdown import/export via `tiptap-markdown`. Supports images (Uploadcare CDN), links, text alignment, subscript/superscript, character counts, and placeholder text. Content stored as markdown, rendered as HTML.

## API Layer

### Object‑Oriented First

Every service is a class. Every controller is a class. Dependency injection via NestJS's IoC container. No scattered utility functions, no "just import this helper." Services have clear boundaries, single responsibilities, and injectable dependencies.

Cross‑Cutting  
Services  
Controllers  

UserController  
OrgController  
ContentController  
BillingController  
FormController  

UserService  
OrgService  
ContentService  
BillingService  
FormService  
EmailService  
TrackingService  

AuthGuard  
LoggDecorator  
ValidationPipe  
ExceptionFilter  

### Structured Logging

The `@Logged()` decorator wraps any service method with structured logging — method name, duration, parameters, result flags. Not `console.log`. Not a logging library you have to configure. A decorator that makes every service method observable with zero boilerplate.

### API Client Pattern

Frontend API calls go through `ApiCore` — a typed Axios wrapper that handles auth headers, error normalization, pagination, and response unwrapping. One import, consistent behavior everywhere:

```typescript
const users = await api.get<User[]>('/user')
const user = await api.post<User>('/user', { name: 'Alice' })
```

## Real‑Time Communication

### WebSocket Gateway

Socket.IO‑based real‑time channel. Authenticated connections tied to user sessions. Server‑pushed events for notifications, live updates, and AI streaming responses.

### AI Agent Integration

Mastra framework for AI agent orchestration. Agents stream responses over WebSocket — not polling, not long‑polling. The user sees tokens appear as they're generated.

Language ModelMastra AgentWebSocketUserLanguage ModelMastra AgentWebSocketUserloop[Token streaming]Send promptExecute agentStream requestTokenPush tokenRender tokenCompleteDone

## DevOps & Deployment

### CI/CD Pipeline

GitHub Actions with a two‑stage pipeline: test everything, then deploy. No manual steps, no "just SSH in and restart."

CD  
CI  
Git Push  
Run Tests  
Type Check  
Build Images  
Push to Registry  
Apply K8s Manifests  
Run Flyway Migrations  
Rolling Update  
Health Check  

### Kubernetes Deployment

Production runs on Kubernetes with:

- **Rolling updates** — Zero‑downtime deployments. New pods spin up, health checks pass, old pods drain.  
- **Resource limits** — CPU and memory bounds per container. No runaway processes eating the node.  
- **ConfigMaps & Secrets** — Environment configuration without baking values into images.  
- **DigitalOcean Container Registry** — Private image storage. Images tagged with commit SHA for traceability.

### DevOps Scripts

A comprehensive `devops/scripts/` toolkit:

- **`start-backend.sh`** — Runs Flyway migrations, then starts NestJS. Migrations always run first. Always.  
- **`local-docker-compose.sh`** — Full local stack: PostgreSQL, Redis, backend, frontend. One command.  
- **`generate-dev-env-js.sh`** — Injects environment variables into the frontend at build time without rebuilding.  
- **`repo-discovery.sh`** — Finds sibling projects using this template. Powers the update‑child sync workflow.  
- **`util-diff.sh`** — Diffs a child project against the template. Shows what's customized vs. what can be synced.

## Testing Infrastructure

### Unit Tests

Jest with TypeScript via `ts-jest`. Backend services tested with real database connections — not mocks. When a test passes, it means the SQL actually works against a real PostgreSQL instance.

### End‑to‑End Tests

Playwright for browser automation. Full user journey tests: sign up, create content, manage billing, admin workflows. Tests run in CI against a deployed preview environment.

### Storybook

Component development and visual testing with Storybook 10. NaiveUI theme integration, accessibility auditing (`@storybook/addon-a11y`), dark/light theme switching. Every shared component has a story.

## Form System

Dynamic form builder with schema‑driven rendering and AI‑powered question generation.

AI Optional  
Runtime  
Builder  

JSON Schema Definition  
Field Types: text, select, rating, etc.  
Validation Rules  

Dynamic Renderer  
Response Collection  

FormResponse Entity  
Tag‑Based Context  

AI Question Generation  
Adaptive Follow‑ups  

Forms are stored as JSONB schemas — not hardcoded templates. Create a form through the admin, it renders automatically. Add validation rules, they enforce automatically. The entire form lifecycle is data‑driven.

## Email System

SendGrid integration with template‑based transactional emails. Not raw HTML strings concatenated in a service method.

- **Magic link login** — Branded email with single‑use auth link  
- **Password reset** — Time‑limited token with clear expiration messaging  
- **Welcome emails** — Post‑registration onboarding  
- **Notification digests** — Batched updates, not individual spam  

Email templates are maintainable HTML with variable interpolation. Preview them locally before deploying.

## Tracking & Analytics

PostHog integration for product analytics with a backend `TrackingService` for server‑side events. Client‑side page views and interactions. Server‑side conversion events, API usage metrics, and funnel tracking.

Events are typed — not arbitrary strings. A `TrackingEvent` enum ensures consistency across the codebase. No "did we call it `user_signup` or `userSignup` or `sign_up`?" confusion.

## Protocol System

Knowledge management through protocol files — executable documentation that lives alongside the code.

Examples  
Lifecycle  
Protocol Types  

Procedures - How to do things  
Implementations - How to build things  
References - Where to find things  

Write Protocol  
Publish to API  
Fetch On‑Demand  
Follow Steps  

@codebase/setup  
@codebase/update-parent  
@codebase/feature/*  
@codebase/innovations  

Protocols are published to an API and fetched on demand. They're not stale wiki pages — they're versioned, searchable, and used by both humans and AI agents. When you bootstrap a session, you load the protocols that matter. When you need to do something, you fetch the procedure.

## What This Adds Up To

This isn't a starter template you'll outgrow in a month. It's the infrastructure layer of a real SaaS product — authentication, billing, content, email, real‑time, AI, admin, deployment, testing, and documentation. All integrated. All production‑ready. All yours to build on.

Every pattern here exists because we hit the wall without it. Every architectural decision has a scar behind it. This is what years of shipping looks like, compressed into a single `git clone`.

## Further reading

The architecture above implements the technical layers of [agent readability](/agent-readability). The five‑layer model the system delivers against is documented in [the five layers of AEO](/five-layer-aeo). The specific Layer‑1 failure modes that drive most install conversations are catalogued in [SSR‑junk and bot walls](/ssr-junk-bot-wall).