Skip to main content

Overview

AI Studio organizes your work around four core concepts: workspaces, projects, style templates, and team collaboration. Understanding how these pieces fit together will help you use the platform effectively.

Workspaces

A workspace is the top-level container for all your work. Think of it as your company or agency account.

Workspace structure

// Workspace schema from lib/db/schema.ts
{
  id: string,
  name: string,               // "Acme Real Estate"
  slug: string,               // "acme-real-estate"
  
  // Company details (collected during onboarding)
  organizationNumber: string, // Norwegian org number
  contactEmail: string,
  contactPerson: string,
  
  // White-label branding
  logo: string | null,
  primaryColor: string | null,
  secondaryColor: string | null,
  
  // Status and billing
  status: "active" | "suspended" | "trial",
  plan: "free" | "pro" | "enterprise",
  onboardingCompleted: boolean
}

What workspaces contain

Each workspace includes:

Team members

All users belong to one workspace with specific roles (owner, admin, member)

Projects

Photo editing and video projects created by any team member

Billing

Invoice line items, pricing, and payment history

Settings

Workspace name, branding, and team invitations

Workspace roles

Three permission levels control what team members can do:
Full access to everything:
  • Create and delete projects
  • Manage team members and invitations
  • Update workspace settings and branding
  • Access billing and invoices
  • Delete the workspace
The workspace creator automatically becomes the owner. Only one owner per workspace.
System admins (platform administrators) have isSystemAdmin: true and can access all workspaces for support and moderation purposes.

White-label branding

Customize your workspace appearance:
// Branding options:
{
  logo: "https://storage.example.com/workspace-123/logo.png",
  primaryColor: "#FF6B6B",   // Header, buttons, accents
  secondaryColor: "#4ECDC4"  // Secondary UI elements
}
When you set custom branding:
  • Your logo appears in the dashboard header
  • Primary color replaces default blue in buttons and links
  • Secondary color styles badges and secondary actions
  • Team members see your branded interface

Projects

A project groups related images or videos together. Projects are the core unit of work in AI Studio.

Project types

Photo editing projects transform property images with AI:
// Photo project schema:
{
  id: string,
  workspaceId: string,
  userId: string,
  name: string,                    // "123 Main Street - Living Room"
  styleTemplateId: string,         // "scandinavian"
  roomType: string | null,         // "living-room"
  thumbnailUrl: string | null,     // First image preview
  status: "pending" | "processing" | "completed" | "failed",
  imageCount: number,              // Total images uploaded
  completedCount: number,          // Successfully processed
  createdAt: Date,
  updatedAt: Date
}
Each photo project contains multiple imageGeneration records (one per uploaded image).

Project lifecycle

1

Creation

User creates a project via the dashboard:
// Server action: lib/actions/projects.ts
createProjectAction(formData) {
  // 1. Validate user session
  // 2. Get workspace ID
  // 3. Create project record with status: "pending"
  // 4. Return project data
}
2

Upload and queue

Images are uploaded to Supabase storage, and AI jobs are queued:
// Storage path pattern:
"workspaces/{workspaceId}/projects/{projectId}/images/"

// Trigger.dev queues background jobs:
{
  jobType: "image-generation",
  projectId: string,
  imageUrls: string[],
  styleTemplateId: string,
  roomType: string | null
}
3

AI processing

Trigger.dev workers process images via Fal.ai:
// For each image:
1. Generate prompt from template + room type
2. Send to Fal.ai with original image URL
3. Poll for completion (30-60 seconds)
4. Save result URL to database
5. Update project.completedCount
6. Update project.status when all complete
Status transitions:
  • pendingprocessing (first image starts)
  • processingcompleted (all images done)
  • processingfailed (any image fails)
4

Completion

When all images are processed:
  • Project status becomes completed
  • Thumbnail URL is set to first enhanced image
  • User receives notification (if enabled)
  • Project appears in dashboard with results

Project metadata

Projects track useful metadata:
// Image generation metadata example:
{
  metadata: {
    falRunId: "fal-run-12345",
    processingTime: 45.2,        // seconds
    modelVersion: "flux-pro/v1.1",
    originalSize: { width: 2048, height: 1536 },
    enhancedSize: { width: 2048, height: 1536 },
    costUSD: 0.055               // AI API cost
  }
}
This helps with:
  • Debugging failed generations
  • Cost tracking and optimization
  • Performance monitoring
  • Audit trails

Style templates

Style templates define how the AI transforms your images. Each template includes a carefully crafted prompt that guides the AI.

Template structure

// Style template definition (lib/style-templates.ts):
{
  id: "scandinavian",
  name: "Scandinavian",
  description: "Light, airy spaces with natural wood and minimal decor",
  category: "staging",
  thumbnail: "https://images.unsplash.com/.../",
  prompt: `Transform into a Scandinavian-style interior. Add light wooden 
           furniture, white and neutral tones, natural textures like linen 
           and wool, minimalist decor with clean lines. Include plants for 
           freshness. The space should feel bright, calm, and inviting with 
           excellent natural lighting.`,
  comingSoon: false
}

How prompts work

When you create a project, the platform generates a complete prompt:
// Prompt generation (lib/style-templates.ts):
function generatePrompt(template: StyleTemplate, roomType: string | null) {
  const preserveStructure = 
    "Do not move, remove, or modify windows, walls, doors, or any " +
    "architectural elements. Keep the room layout exactly as shown.";
  
  let prompt = template.prompt;
  
  if (roomType) {
    const roomLabel = roomType.replace(/-/g, " ");
    prompt = `This is a ${roomLabel}. ${prompt}`;
  }
  
  return `${prompt} ${preserveStructure}`;
}

// Example output:
"This is a living room. Transform into a Scandinavian-style interior. 
Add light wooden furniture, white and neutral tones... Do not move, 
remove, or modify windows, walls, doors..."

Template categories

Templates are organized into categories:
Interior design and furniture styles:
  • Scandinavian: Light wood, minimal decor, natural tones
  • Modern Minimalist: Clean lines, neutral palette (coming soon)
  • Luxury Estate: High-end, sophisticated (coming soon)
  • Cozy Family Home: Warm, inviting atmosphere (coming soon)
Currently, only the Scandinavian template is available. More templates are being added based on user feedback and quality testing.

Custom prompts (future)

In a future release, you’ll be able to create custom style templates:
// Planned feature:
{
  id: "custom-coastal",
  name: "Coastal Retreat",
  description: "Beach house vibes with blues and whites",
  category: "staging",
  prompt: "Your custom prompt here...",
  workspaceId: "workspace-123",  // Only visible to your workspace
  isPublic: false
}

Image generation

Each uploaded image creates an imageGeneration record that tracks AI processing.

Image generation schema

{
  id: string,
  workspaceId: string,
  userId: string,
  projectId: string,
  
  // Image URLs
  originalImageUrl: string,      // Uploaded to Supabase
  resultImageUrl: string | null, // AI-enhanced result
  prompt: string,                // Full generated prompt
  
  // Version tracking
  version: number,               // 1, 2, 3...
  parentId: string | null,       // Links to previous version
  
  // Status
  status: "pending" | "processing" | "completed" | "failed",
  errorMessage: string | null,
  
  // Metadata
  metadata: jsonb,               // Fal.ai response, timings, costs
  
  createdAt: Date,
  updatedAt: Date
}

Version tracking

If you re-edit an image with a different style, a new version is created:
// Original enhancement:
{
  id: "img-v1",
  version: 1,
  parentId: null,
  styleTemplateId: "scandinavian",
  resultImageUrl: "https://.../scandinavian-result.jpg"
}

// Re-edited with different style:
{
  id: "img-v2",
  version: 2,
  parentId: "img-v1",
  styleTemplateId: "modern-minimalist",
  resultImageUrl: "https://.../modern-result.jpg"
}
This creates an edit history, allowing you to compare different styles applied to the same original image.

Video clips

Video projects generate individual 5-second clips from your images, then compile them into a final video.

Video clip schema

{
  id: string,
  videoProjectId: string,
  
  // Source images
  sourceImageUrl: string,              // Start frame
  imageGenerationId: string | null,
  endImageUrl: string | null,          // End frame (optional)
  endImageGenerationId: string | null,
  
  // Room context
  roomType: string,                    // "living-room", "kitchen", etc.
  roomLabel: string | null,            // "Master Bedroom", "Front Yard"
  sequenceOrder: number,               // 1, 2, 3... (playback order)
  
  // AI generation
  motionPrompt: string | null,         // "Slow pan left to right"
  clipUrl: string | null,              // Kling AI output
  durationSeconds: number,             // Default: 5
  
  // Transitions
  transitionType: "cut" | "seamless",
  transitionClipUrl: string | null,    // Generated transition
  
  status: "pending" | "processing" | "completed" | "failed",
  metadata: jsonb
}

Clip sequencing

Clips play in order based on sequenceOrder:
// Example video with 4 clips:
[
  { sequenceOrder: 1, roomType: "exterior",    roomLabel: "Front Facade" },
  { sequenceOrder: 2, roomType: "living-room", roomLabel: "Living Room" },
  { sequenceOrder: 3, roomType: "kitchen",     roomLabel: "Kitchen" },
  { sequenceOrder: 4, roomType: "bedroom",     roomLabel: "Master Suite" }
]

// User can drag-drop to reorder in the video editor

Motion prompts

Kling AI generates camera motion based on prompts:
// Motion prompt examples:
"Slow pan from left to right, showcasing the entire space"
"Gentle zoom in towards the center, emphasizing the focal point"
"Steady dolly forward, moving deeper into the room"
"Static shot with subtle ambient movement"
The platform auto-generates appropriate motion prompts based on room type, or you can customize them.

Room types

Room types provide context for both photo enhancement and video sequencing.

Available room types

// From lib/db/schema.ts:
type RoomType =
  // Interior
  | "living-room" | "kitchen" | "bedroom" | "bathroom" | "toilet"
  | "hallway" | "office" | "laundry-room" | "storage-room"
  | "walk-in-closet" | "sauna" | "gym" | "childrens-room"
  | "pool-area" | "dining-room" | "tv-room" | "library"
  | "hobby-room" | "utility-room" | "pantry" | "conservatory"
  // Exterior
  | "garage" | "terrace" | "garden" | "landscape" | "exterior"
  | "other";

Room type UI mapping

// User-facing labels (lib/style-templates.ts):
const ROOM_TYPES = [
  {
    id: "living-room",
    label: "Living Room",
    icon: "IconSofa",
    description: "Living spaces, family rooms, lounges"
  },
  {
    id: "bedroom",
    label: "Bedroom",
    icon: "IconBed",
    description: "Bedrooms, master suites, guest rooms"
  },
  // ... etc
];
Icons use Tabler Icons for consistent visual representation across the UI.

Payment and billing

AI Studio supports multiple payment methods based on customer type.

Payment methods

For international customers and immediate payment:
{
  paymentMethod: "stripe",
  stripeCheckoutSessionId: "cs_test_...",
  stripePaymentIntentId: "pi_...",
  amountCents: 9900,           // $99.00 USD
  currency: "usd",
  status: "completed"
}
Payment happens before AI processing begins.

Invoice line items

Each project creates a billable line item:
{
  id: string,
  workspaceId: string,
  projectId: string | null,
  videoProjectId: string | null,
  description: "AI Photo Enhancement - 5 images",
  amountOre: 100000,              // 1000 NOK (stored in ore, smallest unit)
  quantity: 1,
  status: "pending" | "invoiced" | "cancelled",
  invoiceId: string | null        // Linked when invoice is generated
}
Line items remain pending until an admin generates an invoice, at which point they’re marked invoiced.

Next steps

Photo editing guide

Deep dive into image enhancement workflows and best practices.

Video creation guide

Learn how to create property tour videos from your enhanced images.

Team collaboration

Set up your workspace, invite team members, and manage permissions.

API reference

Integrate AI Studio into your existing tools and workflows.

Build docs developers (and LLMs) love