Architecture
Tailormade is a single Next.js 15 app — no separate backend service. All studios, APIs, auth, and the pipeline engine live inside next-app/.
System Overview
Directory Layout
next-app/
app/
api/ API route handlers (auth, promotion, animation, pipeline)
auth/ Custom JWT auth endpoints (token, refresh, logout, me)
[country]/ Studio pages (uk, de)
promotion/ Promotion wizard + agentic
animation/ Video wizard + agentic
pipeline/ Image Pipeline node-graph canvas
login/ Login page (password + Entra SSO button)
lib/
auth*.ts JWT creation, verification, token store
auth-entra.ts PKCE flow, Microsoft token exchange, JWKS verification
services/
geminiService.ts Vertex AI REST client (text + image)
animation/ Veo video generation
pipeline/
workflow/ Graph executor, SSE progress, cache, storage
nodes/ Gemini image-gen node, expand node, IO nodes
src/
modules/ React feature modules (auth, promotion-studio, video-studio, pipeline)
prisma/
schema.prisma Database schema (User, Workflow, Run, NodeCache, …)
Authentication
Two parallel auth paths share the same JWT/cookie mechanism:
- Access tokens: HS256 JWT, 30 min TTL.
- Refresh tokens: HS256 JWT, 7 days, stored in httpOnly cookie.
- Token blacklist: invalidated tokens stored in PostgreSQL via
auth-store.ts. - New Entra users are auto-provisioned if
ALLOW_ENTRA_USER_PROVISIONING=trueand their domain is in the allowlist.
Studios
Promotion Studio (/[country]/promotion)
A 7-step wizard backed by Redux Toolkit and a Konva canvas:
- Country / language selection
- Product details
- Background image generation (Gemini image model)
- Layout composition (Konva)
- Text generation (Gemini text model)
- Social copy generation
- Export
Agentic mode (/promotion/agentic) streams NDJSON from /api/promotion-studio/agentic.
Video Studio (/[country]/animation)
A 6-step wizard:
- Campaign brief
- Scene planning (Gemini text)
- Prompt optimisation
- Image descriptions
- Video generation (Veo — Vertex AI
us-central1) - Review + export
Agentic mode (/animation/agentic) uses a client-side task queue over SSE.
Image Pipeline (/[country]/pipeline)
A React Flow node-graph canvas. Users wire together nodes and execute the graph:
- Engine:
lib/pipeline/workflow/— topological sort, per-node input/signature cache, SSE progress. - Persistence:
Workflow(graph definition) +Run(execution record) +NodeCachein PostgreSQL. - SSE: client consumes
/api/pipeline/workflows/[id]/streamviafetchreader (notEventSource) so the Bearer token flows.
AI Model Routing
Two separate SDK paths reach Vertex AI:
| Path | SDK | Used by |
|---|---|---|
lib/services/geminiService.ts | Hand-rolled Vertex REST + google-auth-library | Promotion, Video, Image studios |
lib/pipeline/workflow/genai.ts | @google/genai 1.x | Image Pipeline nodes |
Both respect the same env vars. GOOGLE_GENAI_USE_VERTEXAI=false switches both to API-key mode.
Database Schema
| Table | Purpose |
|---|---|
User | Registered users — email, hashed password, isActive flag |
Workflow | Saved Image Pipeline graphs (JSON nodes + edges, userId owner) |
Run | Execution records — status, outputs, error, graph snapshot |
NodeCache | Input-signature → output cache keyed by node type + inputs hash |