Architecture¶
System Overview¶
graph TB
subgraph "Cloudflare"
CF_DNS[DNS + Proxy]
end
subgraph "Clerk"
CLERK[Clerk Auth<br/>JWT Issuance]
end
subgraph "AWS eu-west-2"
subgraph "CloudFront CDN"
WEB_CF[Web CDN]
ADMIN_CF[Admin CDN]
end
subgraph "API Gateway"
APIGW[API Gateway V2<br/>api.getreggie.io]
end
subgraph "VPC (10.0.0.0/16)"
subgraph "Private Subnets"
API_FN["API Lambda (Node.js)<br/>Hono + Drizzle<br/>arm64, 1024 MB"]
VAL_FN["Valuation Lambda<br/>LightGBM (Python)<br/>arm64, 1536 MB"]
MIG_FN["Migrator Lambda<br/>Alembic (Python)<br/>x86_64, 512 MB"]
RDS["Aurora Serverless v2<br/>PostgreSQL 17<br/>Encrypted at rest"]
end
NAT["EC2 NAT Instance<br/>~$4/mo per AZ"]
end
S3_WEB[S3 Web Assets]
S3_ADMIN[S3 Admin Assets]
end
subgraph "Cloudflare R2"
R2[R2 Storage<br/>Claim Documents]
end
CLERK -->|JWKS| API_FN
CF_DNS --> WEB_CF
CF_DNS --> ADMIN_CF
CF_DNS --> APIGW
WEB_CF --> S3_WEB
ADMIN_CF --> S3_ADMIN
APIGW --> API_FN
API_FN --> RDS
API_FN --> VAL_FN
API_FN --> R2
API_FN -->|Clerk, Stripe, DVLA| NAT
VAL_FN --> RDS
MIG_FN --> RDS
Service Architecture¶
Reggie uses a microservices architecture deployed as AWS Lambda functions, managed by SST v4.
graph LR
subgraph "services/"
API["api-ts/<br/>Node.js 22 (Hono)<br/>ZIP Lambda, arm64"]
VAL["valuation/<br/>Python 3.11 (LightGBM)<br/>Container Lambda, arm64"]
MIG["migrator/<br/>Python 3.11 (Alembic)<br/>Container Lambda, x86_64"]
SCRAPER["scraper/<br/>Python 3.11<br/>Scheduled tasks"]
end
subgraph "packages/"
SHARED["shared-python/<br/>Models, schemas, config"]
APICLIENT["api-client/<br/>TypeScript types + client"]
UI["ui/<br/>Shared React components"]
end
subgraph "apps/"
WEB["web/<br/>Next.js 15 (public)"]
ADMIN["admin/<br/>Next.js 15 (admin)"]
end
API --> SHARED
VAL --> SHARED
MIG --> SHARED
SCRAPER --> SHARED
WEB --> APICLIENT
WEB --> UI
ADMIN --> APICLIENT
ADMIN --> UI
Components¶
| Component | Technology | Runtime | Purpose |
|---|---|---|---|
| API | Hono (Node.js 22) | Lambda ZIP, arm64 | REST API, auth, CRUD, webhooks, presigned URLs |
| Valuation | LightGBM (Python 3.11) | Lambda Container, arm64 | ML inference + rules engine |
| Migrator | Alembic (Python 3.11) | Lambda Container, x86_64 | Database schema migrations |
| Scraper | Python 3.11 | Scheduled | DVLA auctions, dealer listings |
| Web | Next.js 15 | CloudFront + Lambda | Public plate search, valuations, offers |
| Admin | Next.js 15 | CloudFront + Lambda | Claims management, admin dashboard |
| Database | Aurora Serverless v2 | PostgreSQL 17 | Encrypted at rest, 0.5-4 ACU |
| Auth | Clerk | External SaaS | JWT issuance, user management |
| Storage | Cloudflare R2 | EU region | Claim documents (V5C uploads) |
| DNS | Cloudflare | Proxied | DNS + CDN proxy |
Request Flow¶
sequenceDiagram
participant U as User/Agent
participant CF as Cloudflare
participant APIGW as API Gateway
participant FN as API Lambda
participant DB as Aurora PostgreSQL
participant VAL as Valuation Lambda
participant CLERK as Clerk JWKS
U->>CF: GET /api/v1/plates/AB12CDE
CF->>APIGW: Forward (proxied)
APIGW->>FN: Invoke Lambda
FN->>DB: Query plate data
DB-->>FN: Plate record
FN->>VAL: Invoke valuation
VAL->>DB: Query market comparables
DB-->>VAL: Market data
VAL-->>FN: Valuation result
FN-->>APIGW: JSON response
APIGW-->>CF: Response
CF-->>U: Plate data + valuation
Auth Model¶
Clerk issues JWTs to authenticated users. The API validates them using RS256 via Clerk's JWKS endpoint (cached for 1 hour).
sequenceDiagram
participant U as User
participant APP as Next.js App
participant CLERK as Clerk
participant API as API Lambda
U->>APP: Sign in
APP->>CLERK: Authenticate
CLERK-->>APP: JWT (RS256)
APP->>API: Request + Bearer token
API->>CLERK: Fetch JWKS (cached 1hr)
CLERK-->>API: Public keys
API->>API: Verify JWT signature
API-->>APP: Authenticated response
Auth dependencies:
- get_current_user() -- require authenticated user
- require_admin() -- require admin role
- See ADR-001
Database Migration Flow¶
Migrations run automatically as part of CI/CD deployment:
sequenceDiagram
participant CI as GitHub Actions
participant SST as SST Deploy
participant ECR as ECR Registry
participant MIG as Migrator Lambda
participant DB as Aurora PostgreSQL
CI->>SST: sst deploy --stage production
SST->>SST: Build + deploy all resources
SST-->>CI: Deploy complete
CI->>CI: docker build (migrator)
CI->>ECR: Push image
CI->>MIG: Update function code
CI->>MIG: Invoke (empty payload)
MIG->>MIG: alembic.command.upgrade("head")
MIG->>DB: Apply migrations
DB-->>MIG: Success
MIG-->>CI: {"status": "success"}
CI->>CI: Smoke test
Important: Code deploys before migrations run. Use expand-contract pattern for breaking schema changes. See Create a Migration.
Valuation System¶
70% ML (LightGBM) + 30% rules engine with adaptive weighting.
- ML Model: Trained on 26,226 DVLA auction sales, 100+ engineered features
- Rules Engine: Base price x length x pattern x word multipliers
- Ensemble: Adaptive weighting based on training data availability per plate type
- Current MAPE: 42.6% (Phase 3.6)
See Valuation deep-dive and ADR-002.
Agent-Native Design¶
API responses include structured data + natural language explanations so AI agents can interact as easily as humans. GET /api/v1/dev/info returns credentials programmatically in local dev.
Monorepo Structure¶
reggie/
apps/
web/ # Next.js public app (port 3000)
admin/ # Next.js admin app (port 3001)
services/
api-ts/ # Hono API (Node.js Lambda ZIP)
valuation/ # ML inference (Python Lambda container)
migrator/ # Alembic migrations (Python Lambda container)
scraper/ # Web scraping (scheduled)
packages/
shared-python/ # Shared models, schemas, config, database
api-client/ # TypeScript API client + generated types
ui/ # Shared UI components
backend/
alembic/ # Database migration files
tests/ # Pytest test suite
scripts/ # Analysis, training, import scripts
docs/ # Documentation (you are here)
.github/ # CI/CD workflows
.claude/ # AI agent configuration
sst.config.ts # Infrastructure definition
Key Files¶
| Purpose | Location |
|---|---|
| API Routes | services/api-ts/src/routes/ |
| API DB Connection | services/api-ts/src/db/index.ts |
| Lambda Handler (API) | services/api-ts/src/index.ts |
| Valuation Engine | services/valuation/app/engine.py |
| Valuation Handler | services/valuation/app/handler.py |
| Migrator Handler | services/migrator/app/handler.py |
| Rules Engine | packages/shared-python/shared/valuation_rules.py |
| Models | packages/shared-python/shared/models/ |
| Schemas | packages/shared-python/shared/schemas/ |
| Database Config | packages/shared-python/shared/database.py |
| App Config | packages/shared-python/shared/config.py |
| SST Config | sst.config.ts |