import { pgTable, uuid, text, boolean, integer, jsonb, timestamp, index, unique } from 'drizzle-orm/pg-core'; import { projects } from './projects'; /** * Live Scopes Table (Section 8.4) * * Live scopes organize and control image generation via CDN live URLs. * Each scope represents a logical separation within a project (e.g., "hero-section", "product-gallery"). * * Live URL format: /cdn/:orgSlug/:projectSlug/live/:scope?prompt=...&aspectRatio=... */ export const liveScopes = pgTable( 'live_scopes', { id: uuid('id').primaryKey().defaultRandom(), // Relations projectId: uuid('project_id') .notNull() .references(() => projects.id, { onDelete: 'cascade' }), // Scope identifier used in URLs (alphanumeric + hyphens + underscores) // Must be unique within project slug: text('slug').notNull(), // Controls whether new generations can be triggered in this scope // Already generated images are ALWAYS served publicly regardless of this setting allowNewGenerations: boolean('allow_new_generations').notNull().default(true), // Maximum number of generations allowed in this scope // Only affects NEW generations, does not affect regeneration newGenerationsLimit: integer('new_generations_limit').notNull().default(30), // Flexible metadata storage meta: jsonb('meta').$type>().notNull().default({}), // Timestamps createdAt: timestamp('created_at').notNull().defaultNow(), updatedAt: timestamp('updated_at') .notNull() .defaultNow() .$onUpdate(() => new Date()), }, (table) => ({ // Unique constraint: slug must be unique within project projectSlugUnique: unique('live_scopes_project_slug_unique').on(table.projectId, table.slug), // Index for querying scopes by project projectIdx: index('idx_live_scopes_project').on(table.projectId), // Index for slug lookups within project projectSlugIdx: index('idx_live_scopes_project_slug').on(table.projectId, table.slug), }), ); export type LiveScope = typeof liveScopes.$inferSelect; export type NewLiveScope = typeof liveScopes.$inferInsert;