Studio API — Backend Documentation
Codebase location: studio-api-dev/studio-api-dev/
Framework: NestJS (TypeScript)
Database: PostgreSQL (via TypeORM)
Queue: Bull (Redis-backed)
Auth: Auth0 (dual tenant — Houston + Studio)
The Studio API is the NestJS backend that powers both the Houston public-facing app (where end users consume published Flows) and the Picasso Editor creator app (where creators build, manage, and publish Flows). It exposes two distinct route prefixes — /houston/* and /picasso/* — each backed by its own NestJS module tree and Auth0 configuration.
Table of Contents
- Module Architecture Diagram
- Houston vs Studio Module Comparison
- Complete API Endpoints
- Entity Relationship Diagram
- Authentication System
- Queue and Job Processing System
- Request/Response Pipeline
- External Integrations Map
- Key Environment Variables
- Key File Paths Reference
1. Module Architecture Diagram
The NestJS module hierarchy starts with AppModule at the root. It imports two top-level feature modules — HoustonModule (public endpoints) and StudioModule (creator/admin endpoints) — plus shared infrastructure modules.
graph TD
AppModule["AppModule<br/>(Root)"]
AppModule --> HoustonModule
AppModule --> StudioModule
AppModule --> CoreModule
AppModule --> QueueModule
AppModule --> HealthCheckModule
AppModule --> MailerModule
AppModule --> CacheModule["CacheModule<br/>(Redis via Keyv)"]
AppModule --> ThrottlerModule
AppModule --> LoggerModule["LoggerModule<br/>(Pino)"]
AppModule --> TypeOrmModule["TypeOrmModule<br/>(PostgreSQL)"]
%% Houston sub-modules
HoustonModule --> H_Auth["AuthModule<br/>(Houston)"]
HoustonModule --> H_Flow["FlowModule"]
HoustonModule --> H_FormSub["FormSubmissionModule"]
HoustonModule --> H_Integration["IntegrationModule"]
HoustonModule --> H_Favourite["FavouriteModule"]
HoustonModule --> H_Media["MediaModule"]
HoustonModule --> H_ObjRecog["ObjectsRecognitionModule"]
HoustonModule --> H_TenantUser["TenantUserModule"]
HoustonModule --> H_Tenant["TenantModule"]
HoustonModule --> H_GoogleWallet["GoogleWalletModule"]
HoustonModule --> H_Stats["StatisticsModule"]
%% Studio sub-modules
StudioModule --> S_Auth["AuthModule<br/>(Studio)"]
StudioModule --> S_Flow["FlowModule"]
StudioModule --> S_TenantUser["TenantUserModule"]
StudioModule --> S_Media["MediaModule"]
StudioModule --> S_Tag["TagModule"]
StudioModule --> S_Integration["IntegrationModule"]
StudioModule --> S_Stats["StatisticsModule"]
StudioModule --> S_Webhook["WebhookModule"]
StudioModule --> S_FormSub["FormSubmissionModule"]
StudioModule --> S_NodeTemplate["NodeTemplateModule"]
StudioModule --> S_Zweistein["ZweisteinModule"]
StudioModule --> S_Tenant["TenantModule"]
StudioModule --> S_Chat["ChatConversationModule"]
StudioModule --> S_Collab["CollaborationModule<br/>(WebSocket)"]
style AppModule fill:#4A90D9,color:#fff
style HoustonModule fill:#7B68EE,color:#fff
style StudioModule fill:#E8833A,color:#fff
style CoreModule fill:#888,color:#fff
style QueueModule fill:#888,color:#fff
style HealthCheckModule fill:#888,color:#fff
style MailerModule fill:#888,color:#fff
style CacheModule fill:#888,color:#fff
style ThrottlerModule fill:#888,color:#fff
style LoggerModule fill:#888,color:#fff
style TypeOrmModule fill:#888,color:#fff
Key points:
AppModule registers three global providers: TimeoutInterceptor (5 min timeout), ResponseFormateInterceptor (standardises all JSON responses), and UserThrottlerGuard (IP-based rate limiting, 200 req/min).
Auth0ApiKeyMiddleware is applied only to POST /picasso/tenant-users/create to verify an x-api-key header during initial user creation.
- The
CollaborationModule runs a WebSocket gateway (Socket.IO) for real-time collaboration features in the editor.
2. Houston vs Studio Module Comparison
Houston is the public consumer side. Studio is the authenticated creator side. Many modules share the same name but expose very different functionality.
| Module |
Houston (Public — /houston/*) |
Studio (Creator — /picasso/*) |
| AuthModule |
JwtHoustonStrategy — uses HOUSTON_AUTH0_ISSUER_URL. Optional guard on some endpoints. |
JwtStudioStrategy — uses AUTH0_ISSUER_URL. Required guard on almost all endpoints. |
| FlowModule |
Read-only: get flow by ID/slug/UUID, get public snapshot, submit results, cockpit conversations, external auth |
Full CRUD: create, update, save, publish, delete, clone, transfer, AI generation, folders, notes, results, protection, webhooks, sessions |
| FormSubmissionModule |
Create bulk submissions, upload attachments |
List, delete, update attachments, download media |
| IntegrationModule |
Read-only: get public integrations, Canvas conversations |
Full CRUD: create, update, delete integrations; Google token exchange |
| FavouriteModule |
Full CRUD for user favourites and collections (Houston auth) |
Not present |
| MediaModule |
Get multiple media, upload (Houston auth), download |
Full CRUD: upload images/files/videos, clone, update, delete, text-to-image, remove background, video clips via Mux |
| ObjectsRecognitionModule |
Image-to-text, image Q&A, filter predictions, extract data, audio/video extraction |
Not present (AI features accessed via Zweistein) |
| TenantUserModule |
Get/update current user info (Houston auth) |
Create user, get info, update, remove account, get orgs, invite users, get org users |
| TenantModule |
Get current tenant by hostname |
Get tenant info, manage org invites, update tenant settings |
| GoogleWalletModule |
Generate Google Wallet pass link |
Not present |
| StatisticsModule |
Save analytics events |
Read all insights, views by day, step views, first interactions, unique visitors, traffic, most active flows, admin insights, export |
| TagModule |
Not present |
Controller registered but currently empty |
| WebhookModule |
Not present |
Mux video callback handler (POST /picasso/media/mux-cb) |
| NodeTemplateModule |
Not present |
List, create, delete reusable node templates |
| ZweisteinModule |
Not present |
Search media, search by context, get folders, talk-to-image, Blinkin Lens, upload text to folder |
| ChatConversationModule |
Not present |
Get/create conversations, create messages |
| CollaborationModule |
Not present |
WebSocket gateway for real-time collaboration (join/leave rooms, broadcast messages) |
3. Complete API Endpoints
3.1 Houston Endpoints (Public — /houston/*)
Flow (/houston/flows)
| Method |
Path |
Description |
Auth? |
GET |
/houston/flows/version/:uuid/:version |
Get a flow by UUID and version number |
No |
GET |
/houston/flows/public-snapshot |
Get the published snapshot of a flow (query: flowId, flowUuid) |
No |
GET |
/houston/flows/:id-:slug |
Get a flow by its numeric ID and slug |
No |
POST |
/houston/flows/v2/submit |
Submit collected flow data (forms, AI results) |
No |
POST |
/houston/flows/cockpit-conversation |
Create a cockpit AI conversation based on results |
No |
POST |
/houston/flows/cockpit-conversation/validate |
Validate readiness for cockpit conversation |
No |
POST |
/houston/flows/cockpit-conversation/with-initial-message |
Create cockpit conversation with an initial message |
No |
GET |
/houston/flows/check-form-submission-limit/:flowUuid |
Check if form submission quota limit is reached |
No |
POST |
/houston/flows/external-auth/login |
Proxy external user login to Zweistein |
No |
POST |
/houston/flows/external-auth/validate |
Proxy external user token validation to Zweistein |
No |
Flow Sessions (/houston/flows-sessions)
| Method |
Path |
Description |
Auth? |
POST |
/houston/flows-sessions/ |
Create a new flow session |
No |
PATCH |
/houston/flows-sessions/:id |
Update a flow session |
No |
POST |
/houston/flows-sessions/:id/complete |
Mark a flow session as complete |
No |
| Method |
Path |
Description |
Auth? |
GET |
/houston/forms/get-by-flow |
Get forms by flow ID |
No |
| Method |
Path |
Description |
Auth? |
POST |
/houston/form-submissions/bulk |
Create bulk form submissions (deprecated) |
No |
POST |
/houston/form-submissions/upload |
Upload a file attachment (up to 500 MB) |
No |
Integrations (/houston/integrations)
| Method |
Path |
Description |
Auth? |
GET |
/houston/integrations/ |
Get all public integrations for a flow |
No |
POST |
/houston/integrations/:integration/canvas/conversation |
Create a Canvas API conversation |
No |
POST |
/houston/integrations/:integration/canvas/message |
Send a message to a Canvas conversation |
No |
Favourites (/houston/favourites)
| Method |
Path |
Description |
Auth? |
GET |
/houston/favourites/ |
Get all user favourites |
Houston |
GET |
/houston/favourites/:flow |
Get favourite status for a specific flow |
Houston |
POST |
/houston/favourites/:flow |
Add a flow to favourites |
Houston |
POST |
/houston/favourites/:id/assign-to-collection/:collection |
Assign a favourite to a collection |
Houston |
POST |
/houston/favourites/:id/unassign-from-collection/:collection |
Unassign a favourite from a collection |
Houston |
DELETE |
/houston/favourites/:flow |
Remove a flow from favourites |
Houston |
GET |
/houston/favourites/:flow/total |
Get total favourite count for a flow |
No |
Flow Collections (/houston/flow-collections)
| Method |
Path |
Description |
Auth? |
GET |
/houston/flow-collections/ |
Get all user collections |
Houston |
GET |
/houston/flow-collections/:id |
Get collection details |
Houston |
POST |
/houston/flow-collections/ |
Create a new collection |
Houston |
POST |
/houston/flow-collections/:collection/assign-flow/:flow |
Assign a flow to a collection |
Houston |
DELETE |
/houston/flow-collections/:id |
Delete a collection |
Houston |
Viewed Flows (/houston/viewed-flows)
| Method |
Path |
Description |
Auth? |
GET |
/houston/viewed-flows/ |
Get user's viewed flows |
Houston |
POST |
/houston/viewed-flows/:flow |
Mark a flow as viewed |
Houston |
| Method |
Path |
Description |
Auth? |
POST |
/houston/media/multiple |
Get multiple media items by IDs |
No |
POST |
/houston/media/upload |
Upload a media file |
Houston |
POST |
/houston/media/:uuid/download |
Download a media file |
No |
Upload (/houston/upload)
| Method |
Path |
Description |
Auth? |
POST |
/houston/upload/ |
General file upload handler |
No |
Objects Recognition (/houston/objects-recognition)
| Method |
Path |
Description |
Auth? |
POST |
/houston/objects-recognition/image-to-text |
Convert an image to text using AI |
No |
POST |
/houston/objects-recognition/image-qna |
Ask questions about an image |
No |
POST |
/houston/objects-recognition/upload-source |
Upload a source file for AI processing |
No |
POST |
/houston/objects-recognition/filter-valid-predictions |
Filter valid AI predictions from image |
No |
POST |
/houston/objects-recognition/extract-data |
Extract structured data from an image |
No |
POST |
/houston/objects-recognition/extract-data-from-audio-video |
Extract data from audio/video files |
No |
Tenant Users (/houston/users)
| Method |
Path |
Description |
Auth? |
GET |
/houston/users/info |
Get current user details |
Houston |
PATCH |
/houston/users/info |
Update current user details |
Houston |
User Interactions (/houston/user-interactions)
| Method |
Path |
Description |
Auth? |
POST |
/houston/user-interactions/ |
Create a user interaction event |
No |
Tenants (/houston/tenants)
| Method |
Path |
Description |
Auth? |
GET |
/houston/tenants/current |
Get current tenant by hostname |
No |
Google Wallet (/houston/wallets)
| Method |
Path |
Description |
Auth? |
POST |
/houston/wallets/google/generate-pass-link |
Generate a Google Wallet pass link |
No |
Statistics (/houston/statistics)
| Method |
Path |
Description |
Auth? |
POST |
/houston/statistics/save |
Save analytics events |
No |
3.2 Studio Endpoints (Creator — /picasso/*)
All Studio endpoints require Studio Auth (JwtAuthGuard) unless otherwise noted.
Flows (/picasso/flows)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/flows/ |
Create a new flow |
Studio |
GET |
/picasso/flows/ |
Get all flows for the user (optional folderId query) |
Studio |
GET |
/picasso/flows/with-folders |
Get flows organized with their folders |
Studio |
GET |
/picasso/flows/demo-projects |
Get demo/template projects |
Studio |
GET |
/picasso/flows/mine |
Get flows created by current user (paginated) |
Studio |
GET |
/picasso/flows/recent |
Get recently updated flows |
Studio |
GET |
/picasso/flows/published |
Get all published flows |
Studio |
GET |
/picasso/flows/available |
Get all available flows |
Studio |
GET |
/picasso/flows/listed |
Get listed flows (companion type) |
Studio |
GET |
/picasso/flows/listed-as-board |
Get listed flows (board type) |
Studio |
GET |
/picasso/flows/by-uuids |
Get multiple flows by UUIDs |
Studio |
GET |
/picasso/flows/ces |
Get CES demo flows |
Studio |
GET |
/picasso/flows/uuid/:uuid |
Get a flow by UUID |
Studio |
GET |
/picasso/flows/metadata/:flowId |
Get flow metadata by ID |
Studio |
GET |
/picasso/flows/:flowId/export/graph |
Export flow as graph |
Studio |
PATCH |
/picasso/flows/:uuid |
Update flow details |
Studio |
POST |
/picasso/flows/:uuid/save |
Save flow data (nodes, components, etc.) |
Studio |
POST |
/picasso/flows/:uuid/publish |
Publish a flow (create a snapshot) |
Studio |
POST |
/picasso/flows/:id/demo-template |
Set a flow as a demo template |
Studio |
POST |
/picasso/flows/demo-project |
Create a flow from a demo project |
Studio |
POST |
/picasso/flows/clone/:id |
Clone an existing flow |
Studio |
POST |
/picasso/flows/transfer-to-org/:id/:tenantId |
Transfer flow to an organization |
Studio |
POST |
/picasso/flows/generate-flow-with-ai |
Generate an entire flow with AI |
Studio |
POST |
/picasso/flows/generate-steps-with-ai |
Generate flow steps with AI |
Studio |
POST |
/picasso/flows/generate-image-with-ai |
Generate images with AI |
Studio |
DELETE |
/picasso/flows/:uuid |
Delete a flow |
Studio |
Flow Protection (/picasso/flows — protection sub-routes)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/flows/:uuid/protection |
Set password protection on a flow |
Studio |
PATCH |
/picasso/flows/:uuid/protection |
Update protection settings |
Studio |
DELETE |
/picasso/flows/:uuid/protection |
Remove protection from a flow |
Studio |
POST |
/picasso/flows/:uuid/verify-protection |
Verify a password against protection |
No |
GET |
/picasso/flows/:uuid/protection-status |
Check if a flow is protected |
No |
GET |
/picasso/flows/:uuid/external-access |
Get external access configuration |
Studio |
PUT |
/picasso/flows/:uuid/external-access |
Update external access configuration |
Studio |
POST |
/picasso/flows/:uuid/verify-external-user |
Verify external user access via token |
No |
Flow Folders (/picasso/flows-folders)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/flows-folders/ |
Get all flow folders |
Studio |
POST |
/picasso/flows-folders/ |
Create a new folder |
Studio |
PATCH |
/picasso/flows-folders/:id |
Update a folder |
Studio |
POST |
/picasso/flows-folders/:id/assign-flows |
Assign flows to a folder |
Studio |
POST |
/picasso/flows-folders/unassign-flows |
Unassign flows from a folder |
Studio |
DELETE |
/picasso/flows-folders/:id |
Delete a folder |
Studio |
Flow Sessions (/picasso/flows-sessions)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/flows-sessions/by-flow/:flow |
Get sessions for a flow (paginated) |
Studio |
PATCH |
/picasso/flows-sessions/:id/results |
Update session results |
Studio |
POST |
/picasso/flows-sessions/bulk-delete |
Bulk delete sessions |
Studio |
POST |
/picasso/flows-sessions/:id/download-media |
Download session attachments as ZIP |
Studio |
POST |
/picasso/flows-sessions/export-csv |
Export sessions to CSV |
Studio |
Flow Results (/picasso/flow-results)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/flow-results/by-flow/:flow |
Get results for a flow (paginated) |
Studio |
POST |
/picasso/flow-results/bulk-delete |
Bulk delete results |
Studio |
PATCH |
/picasso/flow-results/:id/update-results |
Update AI/form results |
Studio |
POST |
/picasso/flow-results/:id/download-attachments |
Download result attachments |
Studio |
POST |
/picasso/flow-results/export-csv |
Export results to CSV |
Studio |
Flow Notes (/picasso/flow-notes)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/flow-notes/:flowId |
Get notes for a flow |
Studio |
POST |
/picasso/flow-notes/:flowId |
Create a note on a flow |
Studio |
DELETE |
/picasso/flow-notes/:noteId |
Delete a flow note |
Studio |
Flow Webhooks (/picasso/flow-webhooks)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/flow-webhooks/requests |
Get webhook request logs |
Studio |
POST |
/picasso/flow-webhooks/send-test-request |
Send a test webhook request |
Studio |
Flow Utils (/picasso/flow-utils)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/flow-utils/og-data |
Scrape OG metadata from a URL |
Studio |
POST |
/picasso/flow-utils/image/upscale |
Upscale an image using AI |
Studio |
POST |
/picasso/flow-utils/image/sketch-to-image |
Convert sketch to realistic image |
Studio |
| Method |
Path |
Description |
Auth? |
GET |
/picasso/forms/by-flow/:flowUuid |
Get forms for a flow by UUID |
Studio |
| Method |
Path |
Description |
Auth? |
POST |
/picasso/media/upload |
Upload an image |
Studio |
POST |
/picasso/media/upload-file |
Upload a generic file |
Studio |
POST |
/picasso/media/upload-video |
Upload a video file |
Studio |
POST |
/picasso/media/upload-video-by-url |
Upload a video from URL |
Studio |
POST |
/picasso/media/create-video-clip/:uuid |
Create a video clip via Mux |
Studio |
POST |
/picasso/media/clone/:uuid |
Clone an existing media item |
Studio |
POST |
/picasso/media/multiple |
Get multiple media by IDs |
Studio |
POST |
/picasso/media/text-to-image |
Generate image from text prompt (rate limited) |
Studio |
POST |
/picasso/media/remove-background |
Remove image background |
Studio |
GET |
/picasso/media/by-uuid/:uuid |
Get media by UUID |
Studio |
PATCH |
/picasso/media/:uuid |
Update media metadata |
Studio |
DELETE |
/picasso/media/:uuid |
Delete a media item |
Studio |
Upload (/picasso/upload)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/upload/ |
General file upload handler |
Studio |
POST |
/picasso/upload/upload-video-by-url |
Upload video from URL |
Studio |
| Method |
Path |
Description |
Auth? |
POST |
/picasso/media/mux-cb |
Mux video processing callback |
No |
| Method |
Path |
Description |
Auth? |
GET |
/picasso/form-submissions/ |
List form submissions (query: flowId, sessionId) |
Studio |
DELETE |
/picasso/form-submissions/:id |
Delete a form submission |
Studio |
PATCH |
/picasso/form-submissions/attachments/:id |
Update a submission attachment |
Studio |
POST |
/picasso/form-submissions/download-media/:id |
Download submission attachments |
Studio |
Chat Conversations (/picasso/chat-conversations)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/chat-conversations/:uuid |
Get a conversation by UUID |
Studio |
POST |
/picasso/chat-conversations/ |
Create a new conversation |
Studio |
POST |
/picasso/chat-conversations/message |
Send a message in a conversation |
Studio |
Tenant Users (/picasso/tenant-users)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/tenant-users/create |
Create a tenant user (requires x-api-key middleware) |
API Key |
GET |
/picasso/tenant-users/info |
Get current user info |
Studio |
PATCH |
/picasso/tenant-users/info |
Update current user info |
Studio |
GET |
/picasso/tenant-users/organisations |
Get user's organizations |
Studio |
POST |
/picasso/tenant-users/remove-account |
Remove current user account |
Studio |
POST |
/picasso/tenant-users/get-by-ids |
Get multiple users by IDs |
Studio |
GET |
/picasso/tenant-users/invites |
Get user invites |
Studio |
POST |
/picasso/tenant-users/invites |
Create a user invite |
Studio |
GET |
/picasso/tenant-users/org-users |
Get all users in the organization |
Studio |
Tenant User Invites (/picasso/tenant-user-invites)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/tenant-user-invites/accept |
Accept a user invite |
No |
Tenants (/picasso/tenants)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/tenants/info |
Get current tenant info |
Studio |
GET |
/picasso/tenants/invites |
Get organization invites |
Studio |
POST |
/picasso/tenants/invites |
Create an organization invite |
Studio |
DELETE |
/picasso/tenants/invites/:invite |
Revoke an organization invite |
Studio |
PATCH |
/picasso/tenants/info |
Update tenant info |
Studio |
Integrations (/picasso/integrations)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/integrations/ |
Create a new integration |
Studio |
PATCH |
/picasso/integrations/:id |
Update an integration |
Studio |
DELETE |
/picasso/integrations/:id |
Delete an integration |
Studio |
GET |
/picasso/integrations/ |
Get all integrations |
Studio |
POST |
/picasso/integrations/google/tokens |
Exchange Google auth code for tokens |
Studio |
Statistics (/picasso/statistics)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/statistics/all-insights |
Get all analytics insights |
Studio |
GET |
/picasso/statistics/total-views |
Get total views by day |
Studio |
GET |
/picasso/statistics/step-views |
Get step-level views by day |
Studio |
GET |
/picasso/statistics/first-interactions |
Get first interactions by day |
Studio |
GET |
/picasso/statistics/unique-visitors |
Get unique visitors by day |
Studio |
GET |
/picasso/statistics/traffic-usage |
Get traffic usage metrics |
Studio |
GET |
/picasso/statistics/most-active-flows |
Get most active flows |
Studio |
GET |
/picasso/statistics/admin-insights |
Get admin-level insights |
Studio |
POST |
/picasso/statistics/export-insights |
Export insights to file |
Studio |
Node Templates (/picasso/node-templates)
| Method |
Path |
Description |
Auth? |
GET |
/picasso/node-templates/ |
Get all node templates (query: isCore) |
Studio |
POST |
/picasso/node-templates/ |
Create a node template |
Studio |
DELETE |
/picasso/node-templates/:uuid |
Delete a node template |
Studio |
Zweistein AI (/picasso/zweistein)
| Method |
Path |
Description |
Auth? |
POST |
/picasso/zweistein/search-media |
Search media using AI |
Studio |
POST |
/picasso/zweistein/search-media-based-on-context |
Search media using contextual AI |
Studio |
GET |
/picasso/zweistein/get-folders |
Get Zweistein media folders |
Studio |
POST |
/picasso/zweistein/talk-to-image |
Ask questions about an image |
Studio |
POST |
/picasso/zweistein/blinkin-lens |
Highlight text/shapes on an image |
Studio |
POST |
/picasso/zweistein/upload-text-to-folder/:folderId |
Upload text content to a folder |
Studio |
WebSocket — Collaboration Gateway
| Event |
Direction |
Description |
Auth? |
ping |
Client -> Server |
Heartbeat ping |
No |
pong |
Server -> Client |
Heartbeat response |
No |
join-room |
Client -> Server |
Join a collaboration room (payload: { room }) |
WS Guard |
leave-room |
Client -> Server |
Leave a collaboration room |
WS Guard |
room-message |
Client -> Server |
Broadcast a message to the room |
WS Guard |
4. Entity Relationship Diagram
The database uses PostgreSQL with TypeORM. Flow is the central entity — almost everything revolves around it.
erDiagram
Tenant {
int id PK
string name
jsonb data
string domain
string auth0Id UK
int avatar_id FK
int banner_id FK
timestamp createdAt
timestamp updatedAt
}
TenantUser {
int id PK
string firstName
string lastName
string displayName
string nickname UK
string email
text bio
string motto
string authOid
string authOrgId
int avatarId FK
int bannerId FK
timestamp createdAt
timestamp updatedAt
timestamp deletedAt
}
TenantUserInvite {
uuid id PK
string email
uuid ticketId
int inviterId FK
date expiredAt
boolean accepted
timestamp createdAt
timestamp updatedAt
}
Flow {
int id PK
uuid uuid UK
string slug
string originalSlug UK
boolean listed
boolean listedInOrg
string listedAs
jsonb metadata
jsonb integrations
string name
enum status
jsonb nodes
jsonb components
jsonb connections
jsonb forms
jsonb webhooks
jsonb notificationsSettings
jsonb notifications
string orgId
text description
timestamp createdAt
timestamp updatedAt
}
FlowProtection {
int id PK
boolean isPasswordProtected
text passwordHash
enum accessMode
uuid_array allowedExternalUserIds
uuid_array allowedExternalGroupIds
text zweisteinTenantId
int flowId FK
timestamp createdAt
timestamp updatedAt
}
FlowHistory {
int id PK
uuid uuid UK
jsonb data
enum status
string url
timestamp createdAt
timestamp updatedAt
}
FlowSession {
int id PK
string trackingId
jsonb results
boolean migrated
timestamp startedAt
timestamp endedAt
timestamp createdAt
timestamp updatedAt
}
FlowResult {
int id PK
jsonb formResults
jsonb aiResults
string checkProcessingStatusToken
timestamp createdAt
timestamp updatedAt
}
FlowResultMetaData {
int id PK
jsonb metaData
timestamp createdAt
timestamp updatedAt
}
FormSubmission {
int id PK
jsonb data
string nodeUuid
string formId
timestamp createdAt
timestamp updatedAt
}
FormAttachment {
int id PK
string name
string path
string fileHash
string mimeType
string ext
int size
jsonb data
timestamp createdAt
timestamp updatedAt
}
FlowFolder {
int id PK
string name
string orgId
jsonb data
int image_id FK
timestamp createdAt
timestamp updatedAt
}
FlowCollection {
int id PK
string name
int image_id FK
timestamp createdAt
timestamp updatedAt
}
FlowNote {
int id PK
string content
timestamp createdAt
timestamp updatedAt
}
FlowComment {
int id PK
string text
timestamp createdAt
timestamp updatedAt
}
FlowViewed {
int id PK
timestamp createdAt
timestamp updatedAt
}
Favourite {
int id PK
timestamp createdAt
}
FlowWebhookRequest {
int id PK
boolean test
uuid uuid
smallint status
string url
text request
text response
timestamp createdAt
timestamp updatedAt
}
Media {
int id PK
uuid uuid UK
string name
string path
string folder
string storage
jsonb optimisedImages
int width
int height
string fileHash
string mimeType
string ext
int size
jsonb data
timestamp createdAt
timestamp updatedAt
}
Integration {
int id PK
string name
enum type
jsonb settings
boolean enabled
string orgId
boolean listedInOrg
timestamp createdAt
timestamp updatedAt
}
Tag {
int id PK
string name
}
NodeTemplate {
int id PK
uuid uuid UK
string name
boolean isCore
boolean isOrg
jsonb data
string orgId
timestamp createdAt
timestamp updatedAt
}
ChatConversation {
int id PK
uuid uuid UK
string orgId
timestamp createdAt
timestamp updatedAt
}
ChatConversationMessage {
int id PK
text text
timestamp createdAt
}
Statistics {
int id PK
string uid
jsonb payload
string action
string category
smallint deviceType
string osName
string browserName
timestamp createdAt
}
UserInteraction {
int id PK
string name
jsonb data
timestamp createdAt
timestamp updatedAt
}
%% Relationships
Tenant ||--o{ TenantUser : "many-to-many"
TenantUser ||--o{ Flow : "creates"
TenantUser ||--o{ TenantUserInvite : "invites"
TenantUser ||--o{ Media : "owns"
TenantUser ||--o{ Integration : "owns"
TenantUser ||--o{ NodeTemplate : "creates"
TenantUser ||--o{ FlowCollection : "creates"
TenantUser ||--o{ Favourite : "has"
TenantUser ||--o{ FlowViewed : "has"
TenantUser ||--o{ ChatConversation : "has"
Tenant ||--o{ Media : "owns"
Flow ||--o{ FormSubmission : "has"
Flow ||--o{ FlowSession : "has"
Flow ||--o{ FlowResult : "has"
Flow ||--o{ FlowHistory : "has versions"
Flow ||--o{ FlowNote : "has"
Flow ||--o{ FlowComment : "has"
Flow ||--o{ FlowCollection : "belongs to"
Flow ||--o{ Favourite : "has"
Flow ||--o{ FlowViewed : "has"
Flow ||--|| FlowProtection : "has"
Flow ||--|| FlowResultMetaData : "has"
Flow }o--|| FlowFolder : "belongs to"
Flow }o--o{ Tag : "many-to-many"
FlowSession ||--o{ FormSubmission : "has"
FlowSession ||--|| FlowResult : "produces"
FormSubmission ||--o{ FormAttachment : "has"
FlowResult ||--o{ FormAttachment : "has"
ChatConversation ||--o{ ChatConversationMessage : "has"
FlowComment }o--o{ TenantUser : "likes (many-to-many)"
Key design patterns:
- JSONB columns are used extensively on
Flow for storing complex nested data: nodes, components, connections, forms, webhooks, notifications, and notificationsSettings. These avoid rigid relational schemas for frequently-changing editor data.
- FlowHistory stores published snapshots (versions) of a Flow — each publish creates a new
FlowHistory record with the complete flow data.
- FlowResult is the new unified submission model (replacing the older
FormSubmission + FlowSession pair). It stores both formResults and aiResults as JSONB.
- FlowProtection supports three access modes:
public, password, and external_users.
- Soft deletes are used on
TenantUser (via deletedAt).
5. Authentication System
The API uses a dual Auth0 setup — separate Auth0 tenants for Houston (public app users) and Studio (creator app users). Both strategies use passport-jwt with JWKS RSA key rotation.
sequenceDiagram
participant Client
participant API as Studio API
participant Auth0H as Auth0<br/>(Houston Tenant)
participant Auth0S as Auth0<br/>(Studio Tenant)
participant DB as PostgreSQL
Note over Client,DB: === Houston Authentication Flow ===
Client->>Auth0H: Login (email/social)
Auth0H-->>Client: JWT (signed with Houston JWKS)
Client->>API: GET /houston/favourites/<br/>Authorization: Bearer {JWT}
API->>API: JwtHoustonAuthGuard triggers<br/>JwtHoustonStrategy
API->>Auth0H: Fetch JWKS from<br/>HOUSTON_AUTH0_ISSUER_URL/.well-known/jwks.json
Auth0H-->>API: Public keys (cached)
API->>API: Verify JWT signature,<br/>issuer, audience
API->>DB: Look up TenantUser by auth_oid
DB-->>API: TenantUser record
API-->>Client: 200 OK + favourites data
Note over Client,DB: === Studio Authentication Flow ===
Client->>Auth0S: Login (email/social)
Auth0S-->>Client: JWT (signed with Studio JWKS)
Client->>API: POST /picasso/flows/<br/>Authorization: Bearer {JWT}
API->>API: JwtAuthGuard triggers<br/>JwtStudioStrategy
API->>Auth0S: Fetch JWKS from<br/>AUTH0_ISSUER_URL/.well-known/jwks.json
Auth0S-->>API: Public keys (cached)
API->>API: Verify JWT signature,<br/>issuer, audience
API->>DB: Look up TenantUser by auth_oid
DB-->>API: TenantUser record
API-->>Client: 201 Created + new flow
Note over Client,DB: === API Key Authentication (User Creation) ===
Client->>API: POST /picasso/tenant-users/create<br/>x-api-key: {AUTH0_REQUESTS_API_KEY}
API->>API: Auth0ApiKeyMiddleware<br/>validates x-api-key header
API->>DB: Create TenantUser
DB-->>API: New TenantUser
API-->>Client: 201 Created
How the strategies differ:
| Strategy |
Guard Class |
Env Vars |
Used By |
JwtHoustonStrategy |
JwtHoustonAuthGuard |
HOUSTON_AUTH0_ISSUER_URL, HOUSTON_AUTH0_AUDIENCE |
Houston endpoints that need user identity (favourites, collections, viewed, media upload, user info) |
JwtStudioStrategy |
JwtAuthGuard |
AUTH0_ISSUER_URL, AUTH0_AUDIENCE |
All /picasso/* endpoints (except user creation and a few public ones) |
Auth0ApiKeyMiddleware |
(middleware, not a guard) |
AUTH0_REQUESTS_API_KEY |
Only POST /picasso/tenant-users/create |
WsRBACGuard |
WsRBACGuard |
Uses Studio JWT strategy |
WebSocket collaboration gateway |
Both strategies share the same PassportConfigurationService.validate() method which looks up the TenantUser in the database by auth_oid from the JWT payload.
6. Queue and Job Processing System
The API uses Bull (Redis-backed) for background job processing. Six named queues handle different types of asynchronous work.
flowchart TD
subgraph API["API Controllers"]
MediaCtrl["Media Upload"]
FlowCtrl["Flow Submit"]
UserCtrl["User Delete"]
NotifCtrl["Notifications"]
MailCtrl["Mail Triggers"]
end
subgraph Redis["Redis (Bull Queues)"]
Q1["image-optimizer-queue"]
Q2["remove-tenant-user-media-queue"]
Q3["send-flow-submission-notifications-queue"]
Q4["mail-sending-queue"]
Q5["flow-submission-queue"]
Q6["send-results-to-zs-queue"]
end
subgraph Processors["Queue Processors"]
P1["ImageOptimizerProcessor<br/>Resizes images to 500/1000/1500px<br/>Converts to WebP (quality 90)"]
P2["RemoveTenantUserMediaProcessor<br/>Cleans up Azure Blob storage<br/>when a user is deleted"]
P3["SendFlowSubmissionNotifications<br/>Sends email/webhook notifications<br/>after form submissions"]
P4["MailSendingProcessor<br/>Sends emails via Mailgun"]
P5["FlowSubmissionQueueProcessor<br/>Processes submitted flow data,<br/>runs AI models, saves results,<br/>triggers webhooks & notifications"]
P6["SendResultsToZsProcessor<br/>Sends results to Zweistein AI<br/>for further processing"]
end
subgraph External["External Services"]
Azure["Azure Blob Storage"]
Mailgun["Mailgun"]
Zweistein["Zweistein AI"]
Webhooks["User Webhooks"]
end
MediaCtrl -->|"addJob()"| Q1
UserCtrl -->|"addJob()"| Q2
FlowCtrl -->|"addJob()"| Q5
NotifCtrl -->|"addJob()"| Q3
MailCtrl -->|"addJob()"| Q4
FlowCtrl -->|"addJob()"| Q6
Q1 --> P1
Q2 --> P2
Q3 --> P3
Q4 --> P4
Q5 --> P5
Q6 --> P6
P1 --> Azure
P2 --> Azure
P3 --> Mailgun
P3 --> Webhooks
P4 --> Mailgun
P5 --> Zweistein
P5 --> Webhooks
P6 --> Zweistein
style Redis fill:#DC382C,color:#fff
style API fill:#4A90D9,color:#fff
style Processors fill:#2ECC71,color:#fff
style External fill:#888,color:#fff
Queue details:
| Queue Name |
Processor |
Purpose |
Default Timeout |
image-optimizer-queue |
ImageOptimizerProcessor |
Resizes uploaded images to 3 sizes (500, 1000, 1500px) and converts to WebP format |
120s |
remove-tenant-user-media-queue |
RemoveTenantUserMediaProcessor |
Deletes all media from Azure Blob when a user account is removed |
120s |
send-flow-submission-notifications-queue |
SendFlowSubmissionNotifications |
Sends email and webhook notifications when flow submissions are received |
120s |
mail-sending-queue |
MailSendingProcessor |
General purpose email sending via Mailgun |
120s |
flow-submission-queue |
FlowSubmissionQueueProcessor |
Processes flow submissions: runs AI analysis, saves results, triggers webhooks and notifications |
120s |
send-results-to-zs-queue |
SendResultsToZsProcessor |
Forwards processed results to the Zweistein AI service for further analysis |
120s |
Configuration: All queues share a default job timeout of 120 seconds and priority of 1. Redis connection uses TLS by default (configurable via REDIS_TLS_ENABLED).
7. Request/Response Pipeline
Every HTTP request flows through multiple layers of middleware, guards, and interceptors before reaching the controller.
flowchart LR
Client(("Client"))
Compress["Compression<br/>Middleware<br/>(gzip)"]
BodyParser["Body Parser<br/>(50MB limit)"]
Session["Express Session<br/>(SESSION_SECRET)"]
Passport["Passport<br/>Initialize"]
Pino["Pino Logger<br/>(log + redact headers)"]
Throttle["UserThrottlerGuard<br/>(200 req/min per IP)"]
AuthGuard{"Auth Guard?<br/>JwtAuthGuard or<br/>JwtHoustonAuthGuard"}
ApiKeyMW["Auth0ApiKeyMiddleware<br/>(x-api-key check)"]
Controller["Controller<br/>Method"]
TimeoutInt["TimeoutInterceptor<br/>(5 min)"]
ResponseInt["ResponseFormateInterceptor<br/>(standardize JSON)"]
Response(("Response"))
Client --> Compress
Compress --> BodyParser
BodyParser --> Session
Session --> Passport
Passport --> Pino
Pino --> Throttle
Throttle --> AuthGuard
AuthGuard -->|"Protected route"| Controller
AuthGuard -->|"/picasso/tenant-users/create"| ApiKeyMW
ApiKeyMW --> Controller
Controller --> TimeoutInt
TimeoutInt --> ResponseInt
ResponseInt --> Response
style Client fill:#333,color:#fff
style Response fill:#333,color:#fff
style AuthGuard fill:#E8833A,color:#fff
style Controller fill:#4A90D9,color:#fff
Pipeline breakdown:
- Compression — gzip compression applied to all responses via the
compression npm package.
- Body Parser — Accepts JSON and URL-encoded payloads up to 50 MB.
- Express Session — Session management using
SESSION_SECRET, though the API is primarily stateless JWT-based.
- Passport — Initialized globally; actual authentication happens per-route via guards.
- Pino Logger — Logs requests with severity mapping. Redacts all request headers from logs. Errors (level >= 40) are also sent to a Microsoft Teams webhook.
- UserThrottlerGuard — Global IP-based rate limiting: 200 requests per 60 seconds. Some routes (like
text-to-image) have stricter limits: 10 requests per 600 seconds.
- Auth Guard — Applied per-controller or per-route.
JwtAuthGuard for Studio, JwtHoustonAuthGuard for Houston. Some routes have no guard.
- Controller — The actual business logic handler.
- TimeoutInterceptor — Kills any request that takes longer than 5 minutes.
- ResponseFormateInterceptor — Wraps all successful responses in a standard format:
{ statusCode, data, message }. Converts service-level error codes into proper HTTP exceptions.
Standard response format:
{
"statusCode": 200,
"data": { ... },
"message": null
}
Server configuration:
- Listening port:
PORT env var (defaults to 3000)
- Server timeout: 600,000 ms (10 minutes) for large file uploads
- CORS: Enabled globally
- WebSocket adapter: Socket.IO via
IoAdapter
x-powered-by header: Disabled for security
8. External Integrations Map
Integration Types (Database enum)
The Integration entity supports these types:
| Integration Type |
Description |
CANVAS |
Canvas LMS API integration |
CLAUDE_AI |
Anthropic Claude AI integration |
MAKE_COM |
Make.com (formerly Integromat) automation |
GOOGLE_SPREADSHEET |
Google Sheets integration |
INTERCOM |
Intercom customer messaging |
Complete External Services Map
flowchart TD
API["Studio API"]
subgraph Auth["Authentication"]
Auth0["Auth0<br/>(2 tenants: Houston + Studio)"]
end
subgraph Storage["Storage & Media"]
Azure["Azure Blob Storage<br/>(images + videos)"]
Mux["Mux<br/>(video processing,<br/>clips, streaming)"]
end
subgraph AI["AI Services"]
OpenAI["OpenAI<br/>(GPT models)"]
Claude["Anthropic Claude AI<br/>(image analysis, Q&A)"]
Replicate["Replicate<br/>(image generation,<br/>upscaling)"]
Clipdrop["Clipdrop<br/>(background removal,<br/>sketch-to-image)"]
Zweistein["Zweistein AI<br/>(internal: media search,<br/>flow generation,<br/>cockpit conversations)"]
end
subgraph Comms["Communication"]
Mailgun["Mailgun<br/>(transactional email)"]
TeamsWH["MS Teams Webhook<br/>(error logging)"]
end
subgraph Integrations["User-Configured Integrations"]
GoogleSheets["Google Sheets<br/>(form data export)"]
GoogleDrive["Google Drive<br/>(file storage)"]
GoogleWallet["Google Wallet<br/>(pass generation)"]
Canvas["Canvas LMS<br/>(LMS integration)"]
MakeCom["Make.com<br/>(automation workflows)"]
Intercom["Intercom<br/>(customer messaging)"]
end
subgraph Cache["Cache & Queue"]
Redis["Redis<br/>(caching + Bull queues)"]
end
API <--> Auth0
API <--> Azure
API <--> Mux
API <--> OpenAI
API <--> Claude
API <--> Replicate
API <--> Clipdrop
API <--> Zweistein
API <--> Mailgun
API --> TeamsWH
API <--> GoogleSheets
API <--> GoogleDrive
API <--> GoogleWallet
API <--> Canvas
API <--> MakeCom
API <--> Intercom
API <--> Redis
style API fill:#4A90D9,color:#fff
style Auth fill:#FFD700,color:#333
style Storage fill:#87CEEB,color:#333
style AI fill:#98FB98,color:#333
style Comms fill:#FFB6C1,color:#333
style Integrations fill:#DDA0DD,color:#333
style Cache fill:#DC382C,color:#fff
Service Details
| Service |
Purpose |
How It's Used |
Key Env Vars |
| Auth0 |
Authentication & authorization |
Dual JWT strategy: Houston (public) + Studio (creator). M2M tokens for user management API. |
AUTH0_ISSUER_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_AUDIENCE, HOUSTON_AUTH0_ISSUER_URL, HOUSTON_AUTH0_AUDIENCE |
| Azure Blob Storage |
File storage |
All images, videos, and file uploads are stored in Azure Blob. Separate containers for images and videos. |
AZURE_STORAGE_CONNECTION_STRING, AZURE_STORAGE_URL, AZURE_STORAGE_CONTAINER_NAME, AZURE_STORAGE_VIDEO_CONTAINER_NAME |
| Mux |
Video processing |
Video uploads, transcoding, clip creation, playback. Callback webhook at /picasso/media/mux-cb. |
MUX_TOKEN_ID, MUX_TOKEN_SECRET, MUX_SIGNING_SECRET |
| OpenAI |
AI text generation |
Flow step generation, content creation. |
OPENAI_API_KEY |
| Anthropic (Claude) |
AI image analysis |
Image-to-text, image Q&A, data extraction via objects-recognition module. |
(configured via integration settings) |
| Replicate |
AI image generation |
Image generation from prompts, image upscaling. |
REPLICATE_API_TOKEN |
| Clipdrop |
Image manipulation |
Background removal, sketch-to-image conversion. |
CLIPDROP_API_KEY |
| Zweistein AI |
Internal AI service |
Media search, flow generation with AI, cockpit conversations, Blinkin Lens, result processing. |
ZWEISTEIN_API_BASE_URL, INTERNAL_API_KEY |
| Mailgun |
Email delivery |
Transactional emails: invites, notifications, submission alerts. |
MAILGUN_KEY, MAILGUN_DOMAIN, MAIL_HOST, MAIL_FROM_ADDRESS |
| MS Teams |
Error logging |
Pino logger hook sends errors (level >= 40) to a Teams channel webhook. |
TEAMS_WEBHOOK_URL |
| Google APIs |
Sheets, Drive, Wallet |
OAuth2 for Google Sheets/Drive integration. Wallet pass generation. |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_API_KEY |
| Canvas LMS |
Learning platform |
Canvas API integration for educational flows. |
CANVAS_API_URL |
| Redis |
Caching + queuing |
NestJS CacheModule (3 min TTL) + Bull queue broker. |
REDIS_HOST, REDIS_PORT, REDIS_PWD, REDIS_TLS_ENABLED |
9. Key Environment Variables
All variables are sourced from .env (loaded via dotenv). The .env.example file provides the template.
Database
| Variable |
Description |
ENV |
Environment name (e.g., development, production) |
PORT |
Server listening port (default: 3000) |
DB_USERNAME |
PostgreSQL username |
DB_PASSWORD |
PostgreSQL password |
DB_NAME |
PostgreSQL database name |
DB_PORT |
PostgreSQL port |
DB_HOST |
PostgreSQL host (localhost for dev) |
Auth0 (Studio)
| Variable |
Description |
AUTH0_ISSUER_URL |
Auth0 domain for Studio (e.g., your-tenant.auth0.com) |
AUTH0_AUDIENCE |
Auth0 API audience for Studio |
AUTH0_CLIENT_ID |
Auth0 application client ID (M2M) |
AUTH0_CLIENT_SECRET |
Auth0 application client secret (M2M) |
AUTH0_REQUESTS_API_KEY |
API key for tenant user creation middleware |
AUTH0_APP_CLIENT_ID |
Auth0 app client ID for org invites |
Auth0 (Houston)
| Variable |
Description |
HOUSTON_AUTH0_ISSUER_URL |
Auth0 domain for Houston public app |
HOUSTON_AUTH0_AUDIENCE |
Auth0 API audience for Houston |
Azure Storage
| Variable |
Description |
AZURE_STORAGE_CONNECTION_STRING |
Azure Blob Storage connection string |
AZURE_STORAGE_URL |
Public URL base for Azure Storage |
AZURE_STORAGE_CONTAINER_NAME |
Container name for images (default: images) |
AZURE_STORAGE_VIDEO_CONTAINER_NAME |
Container name for videos (default: videos/) |
AI Services
| Variable |
Description |
OPENAI_API_KEY |
OpenAI API key |
REPLICATE_API_TOKEN |
Replicate API token |
CLIPDROP_API_KEY |
Clipdrop API key |
ZWEISTEIN_API_BASE_URL |
Base URL for Zweistein AI service |
INTERNAL_API_KEY |
Internal API key for Zweistein communication |
Google
| Variable |
Description |
GOOGLE_CLIENT_ID |
Google OAuth2 client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth2 client secret |
GOOGLE_API_KEY |
Google API key |
Redis
| Variable |
Description |
REDIS_HOST |
Redis server host |
REDIS_PORT |
Redis server port |
REDIS_PWD |
Redis password |
REDIS_TLS_ENABLED |
Enable TLS for Redis (true/false, default: true) |
Mux (Video)
| Variable |
Description |
MUX_TOKEN_ID |
Mux API token ID |
MUX_TOKEN_SECRET |
Mux API token secret |
MUX_SIGNING_SECRET |
Mux webhook signing secret |
Email (Mailgun)
| Variable |
Description |
MAIL_HOST |
SMTP host for Mailgun |
MAIL_FROM_ADDRESS |
Default "from" email address |
MAILGUN_DOMAIN |
Mailgun domain |
MAILGUN_KEY |
Mailgun API key |
Application URLs
| Variable |
Description |
HOUSTON_CLIENT_URL |
Houston frontend URL (used in email links, OG data) |
STUDIO_CLIENT_URL |
Studio/Picasso frontend URL |
CANVAS_API_URL |
Canvas LMS API base URL |
IMAGE_PROCESSING_API_URL |
Image processing microservice URL |
Misc
| Variable |
Description |
SESSION_SECRET |
Express session secret key |
JWT_SECRET_KEY |
JWT secret key (for internal signing) |
TEAMS_WEBHOOK_URL |
Microsoft Teams webhook for error logging |
ALLOWED_ORIGINS |
Comma-separated allowed CORS origins for WebSocket |
PUPPETEER_EXECUTABLE_PATH |
Path to Chromium binary for server-side rendering (default: /usr/bin/chromium) |
10. Key File Paths Reference
| File Path |
Description |
src/main.ts |
Application bootstrap: compression, session, passport, body-parser, WebSocket adapter, server timeout |
src/app.module.ts |
Root module: imports all modules, registers global interceptors/guards, configures TypeORM, Redis cache, Pino logger, throttler |
src/app.controller.ts |
Root controller (minimal) |
src/modules/houston/houston.module.ts |
Houston parent module — imports all Houston sub-modules |
src/modules/studio/studio.module.ts |
Studio parent module — imports all Studio sub-modules |
src/modules/health-check/ |
Health check endpoint for load balancers |
| Houston Controllers |
|
src/modules/houston/modules/flow/controllers/flow.controller.ts |
Public flow access, submission, cockpit conversations |
src/modules/houston/modules/flow/controllers/flow-session.controller.ts |
Create/update/complete flow sessions |
src/modules/houston/modules/flow/controllers/flow-collection.controller.ts |
User flow collections |
src/modules/houston/modules/flow/controllers/flow-viewed.controller.ts |
Track viewed flows |
src/modules/houston/modules/flow/controllers/form.controller.ts |
Get forms by flow |
src/modules/houston/modules/form-submission/controllers/form-submission.controller.ts |
Bulk submissions and file upload |
src/modules/houston/modules/integration/controllers/integration.controller.ts |
Public integrations and Canvas API |
src/modules/houston/modules/favourite/controllers/favourite.controller.ts |
Favourites CRUD |
src/modules/houston/modules/media/controllers/media.controller.ts |
Media retrieval, upload, download |
src/modules/houston/modules/objects-recognition/controllers/objects-recognition.controller.ts |
AI image/audio/video processing |
src/modules/houston/modules/tenant-user/controllers/tenant-user.controller.ts |
User info for Houston users |
src/modules/houston/modules/tenant/controllers/tenant.controller.ts |
Tenant lookup by hostname |
src/modules/houston/modules/google-wallet/controllers/google-wallet.controller.ts |
Google Wallet pass generation |
src/modules/houston/modules/statistics/controllers/statistics.controller.ts |
Save analytics events |
| Studio Controllers |
|
src/modules/studio/modules/flow/controllers/flow.controller.ts |
Full flow CRUD, AI generation, publish, clone |
src/modules/studio/modules/flow/controllers/flow-protection.controller.ts |
Flow password/external-user protection |
src/modules/studio/modules/flow/controllers/flow-folder.controller.ts |
Flow folder management |
src/modules/studio/modules/flow/controllers/flow-session.controller.ts |
Session browsing, export, delete |
src/modules/studio/modules/flow/controllers/flow-result.controller.ts |
Result browsing, update, export, delete |
src/modules/studio/modules/flow/controllers/flow-note.controller.ts |
Flow notes CRUD |
src/modules/studio/modules/flow/controllers/flow-webhook.controller.ts |
Webhook request logs and test |
src/modules/studio/modules/flow/controllers/flow-utils.controller.ts |
OG scraping, image upscale, sketch-to-image |
src/modules/studio/modules/flow/controllers/form.controller.ts |
Get forms by flow UUID |
src/modules/studio/modules/media/controllers/media.controller.ts |
Full media CRUD, video, AI image tools |
src/modules/studio/modules/media/controllers/upload.controller.ts |
General file/video upload |
src/modules/studio/modules/form-submission/controllers/form-submission.controller.ts |
Submission management |
src/modules/studio/modules/chat-conversation/controllers/chat-conversation.controller.ts |
Chat conversations CRUD |
src/modules/studio/modules/tenant-user/controllers/tenant-user.controller.ts |
User management, invites, orgs |
src/modules/studio/modules/tenant-user/controllers/tenant-user-invite.controller.ts |
Accept user invites |
src/modules/studio/modules/tenant/controllers/tenant.controller.ts |
Tenant info and org invites |
src/modules/studio/modules/integration/controllers/integration.controller.ts |
Integration CRUD and Google tokens |
src/modules/studio/modules/statistics/controllers/statistics.controller.ts |
Analytics dashboards and exports |
src/modules/studio/modules/node-template/controllers/node-template.controller.ts |
Reusable node template CRUD |
src/modules/studio/modules/zweistein/controllers/zweistein.controller.ts |
AI media search, talk-to-image, Blinkin Lens |
src/modules/studio/modules/webhook/controllers/webhook.controller.ts |
Mux video callback handler |
src/modules/studio/modules/collaboration/gateways/collaboration.gateway.ts |
WebSocket gateway for real-time collaboration |
| Auth |
|
src/modules/studio/modules/auth/strategies/jwt-studio.strategy.ts |
Studio JWT strategy (AUTH0_ISSUER_URL) |
src/modules/houston/modules/auth/strategies/jwt-houston.strategy.ts |
Houston JWT strategy (HOUSTON_AUTH0_ISSUER_URL) |
src/modules/studio/modules/auth/guards/jwt-auth.guard.ts |
Studio auth guard |
src/modules/houston/modules/auth/guards/jwt-auth.guard.ts |
Houston auth guard |
src/modules/studio/modules/auth/guards/ws.guard.ts |
WebSocket auth guard |
src/core/middleware/validate-auth0-api-key.middleware.ts |
API key middleware for user creation |
src/core/guards/user-throttler.guard.ts |
IP-based rate limiting guard |
| Interceptors |
|
src/core/interceptors/response.interceptor.ts |
Standardizes all API responses |
src/core/interceptors/timeout.interceptor.ts |
5-minute request timeout |
| Queue |
|
src/common/modules/queue/queue.module.ts |
Bull queue module with 6 queues |
src/common/modules/queue/processors/image-optimizer.processor.ts |
Image resize/WebP processor |
src/common/modules/queue/processors/flow-submission.processor.ts |
Flow submission processing |
src/common/modules/queue/processors/mail-sending.processor.ts |
Email sending processor |
src/common/modules/queue/processors/remove-tenant-user-media.processor.ts |
User media cleanup |
src/common/modules/queue/processors/send-flow-submission-notifications.ts |
Submission notification processor |
src/common/modules/queue/processors/send-results-to-zs.processor.ts |
Zweistein result forwarding |
| Database |
|
src/database/entities/ |
All TypeORM entity definitions (26 files) |
src/database/repositories/ |
Custom TypeORM repositories |
src/database/connection/ormconfig.ts |
TypeORM connection configuration |
src/database/migrations/ |
Database migration files |
| Config |
|
.env.example |
Environment variable template |
src/core/constants/configration.constant.ts |
Rate limits, timeouts, port config |
src/core/config/mail.config.ts |
Mailgun/mailer configuration |
src/common/constants/api.constant.ts |
Zweistein API URLs |
src/common/constants/azure-common.constant.ts |
Azure container names |