-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmissing_migrations.sql
More file actions
429 lines (395 loc) · 15.1 KB
/
missing_migrations.sql
File metadata and controls
429 lines (395 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
-- missing_migrations.sql
-- Generated: 2026-05-19T01:42:25.036Z
-- Target: https://ktrtheitjtwpdvdvnlzj.supabase.co
-- Apply via: npm run db:migrate (DATABASE_URL) or Supabase SQL editor
-- =============================================================================
-- SECTION A: Existing repo migrations not yet applied on remote
-- =============================================================================
-- >>> from 20260507_create_expression_assets.sql
-- Create expression_assets table for caching Seedance emotion videos
CREATE TABLE IF NOT EXISTS expression_assets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT,
project_id TEXT,
expression TEXT NOT NULL,
source_photo_url TEXT NOT NULL,
video_url TEXT NOT NULL,
model TEXT NOT NULL,
status TEXT DEFAULT 'completed',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Add index for faster lookups by photo URL and expression
CREATE INDEX IF NOT EXISTS idx_expression_assets_photo_expression
ON expression_assets(source_photo_url, expression);
-- Add index for user_id lookups
CREATE INDEX IF NOT EXISTS idx_expression_assets_user_id
ON expression_assets(user_id);
-- Add index for project_id lookups
CREATE INDEX IF NOT EXISTS idx_expression_assets_project_id
ON expression_assets(project_id);
-- Add comment
COMMENT ON TABLE expression_assets IS 'Caches Seedance emotion videos to avoid regenerating the same expression for the same photo';
-- >>> from 20260509_create_payments_table.sql
-- Create payments table for tracking Stripe payments
CREATE TABLE IF NOT EXISTS payments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
movie_id UUID REFERENCES movies(id),
user_id TEXT,
amount INTEGER,
currency TEXT DEFAULT 'usd',
stripe_payment_intent_id TEXT,
stripe_session_id TEXT,
status TEXT DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Add index for faster lookups
CREATE INDEX IF NOT EXISTS idx_payments_movie_id ON payments(movie_id);
CREATE INDEX IF NOT EXISTS idx_payments_user_id ON payments(user_id);
CREATE INDEX IF NOT EXISTS idx_payments_stripe_payment_intent_id ON payments(stripe_payment_intent_id);
CREATE INDEX IF NOT EXISTS idx_payments_stripe_session_id ON payments(stripe_session_id);
-- =============================================================================
-- SECTION B: Tables referenced in code but missing CREATE in supabase/migrations/
-- =============================================================================
-- Snapshot from remote OpenAPI (dialogue_blocks)
CREATE TABLE IF NOT EXISTS public.dialogue_blocks (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
shot_id UUID,
project_id UUID,
character TEXT,
text TEXT,
emotion TEXT DEFAULT 'neutral',
voice_id TEXT,
start_sec NUMERIC,
end_sec NUMERIC,
audio_url TEXT,
timestamps_json JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- dialogue_lines: TTS pipeline per shot line
CREATE TABLE IF NOT EXISTS public.dialogue_lines (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES public.projects(id) ON DELETE CASCADE,
shot_index INTEGER NOT NULL,
line_index INTEGER NOT NULL,
character TEXT NOT NULL,
text TEXT NOT NULL,
emotion TEXT,
voice_id TEXT NOT NULL DEFAULT '',
audio_url TEXT,
tts_status TEXT NOT NULL DEFAULT 'pending',
start_sec NUMERIC,
duration_sec NUMERIC,
timestamps_json JSONB,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (project_id, shot_index, line_index)
);
CREATE INDEX IF NOT EXISTS idx_dialogue_lines_project_id ON public.dialogue_lines(project_id);
-- Snapshot from remote OpenAPI (digital_twins)
CREATE TABLE IF NOT EXISTS public.digital_twins (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
session_id TEXT,
user_id TEXT,
frame_url_front TEXT,
frame_url_mid TEXT,
frame_url_side TEXT,
source_video_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
is_active BOOLEAN DEFAULT true,
voice_id TEXT,
cached_videos JSONB
);
-- Snapshot from remote OpenAPI (director_rules)
CREATE TABLE IF NOT EXISTS public.director_rules (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
rule_id TEXT,
rule TEXT,
reason TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (emotion_details)
CREATE TABLE IF NOT EXISTS public.emotion_details (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
text TEXT,
emotion_tags TEXT[],
visual_symbol TEXT,
human_truth TEXT,
cinematic_potential INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (emotion_lines)
CREATE TABLE IF NOT EXISTS public.emotion_lines (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
text TEXT,
emotion_tags TEXT[],
why_it_hurts TEXT,
human_detail TEXT,
silence_score INTEGER DEFAULT 0,
universality_score INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (emotional_memory)
CREATE TABLE IF NOT EXISTS public.emotional_memory (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
project_id TEXT,
movie_id UUID,
characters JSONB,
visual_symbols JSONB,
unspoken_things JSONB,
emotional_debt JSONB,
pending_callbacks JSONB,
format_type TEXT DEFAULT 'hook_15s',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- generation_runs: tracks video/tts/merge job state per project
CREATE TABLE IF NOT EXISTS public.generation_runs (
project_id UUID PRIMARY KEY REFERENCES public.projects(id) ON DELETE CASCADE,
video_status TEXT NOT NULL DEFAULT 'pending',
tts_status TEXT NOT NULL DEFAULT 'pending',
merge_status TEXT NOT NULL DEFAULT 'pending',
started_at TIMESTAMPTZ,
merge_started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (hook_experiments)
CREATE TABLE IF NOT EXISTS public.hook_experiments (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
template_id TEXT,
user_input TEXT,
hook_blueprint JSONB,
score JSONB,
status TEXT DEFAULT 'draft',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- kling_jobs: table exists on remote; see SECTION C for column ALTERs only
-- Snapshot from remote OpenAPI (market_assets)
CREATE TABLE IF NOT EXISTS public.market_assets (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
seller_id UUID,
project_id UUID,
type TEXT,
title TEXT,
description TEXT,
price_cents INTEGER DEFAULT 999,
status TEXT DEFAULT 'active',
asset_data JSONB,
preview_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (market_feedback)
CREATE TABLE IF NOT EXISTS public.market_feedback (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
hook_experiment_id UUID,
watch_time NUMERIC,
rewatch_rate NUMERIC,
comments JSONB,
conversion_rate NUMERIC,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- movie_shots: only ALTER migrations exist in repo; CREATE from remote OpenAPI snapshot
CREATE TABLE IF NOT EXISTS public.movie_shots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
movie_id UUID,
shot_index INTEGER,
omni_task_id TEXT,
kling_task_id TEXT,
omni_video_url TEXT,
kling_scene_url TEXT,
final_shot_url TEXT,
audio_url TEXT,
status TEXT DEFAULT 'pending',
shotstack_render_id TEXT,
narrative JSONB,
shot_type TEXT DEFAULT 'face',
duration NUMERIC,
retry_count INTEGER DEFAULT 0,
submitted_at TIMESTAMPTZ,
error TEXT,
user_id UUID,
twin_frame_url TEXT,
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_movie_shots_status_updated_at ON public.movie_shots(status, updated_at);
CREATE INDEX IF NOT EXISTS idx_movie_shots_movie_id ON public.movie_shots(movie_id);
-- Snapshot from remote OpenAPI (music_assets)
CREATE TABLE IF NOT EXISTS public.music_assets (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT,
url TEXT,
preview_url TEXT,
cover_url TEXT,
emotion_tags TEXT[],
mood TEXT,
genre TEXT,
language TEXT DEFAULT 'instrumental',
source TEXT DEFAULT 'pixabay',
external_id TEXT,
creator_id UUID,
creator_name TEXT,
status TEXT DEFAULT 'free',
price_credits INTEGER DEFAULT 0,
revenue_share NUMERIC DEFAULT 0.8,
plays INTEGER DEFAULT 0,
purchases INTEGER DEFAULT 0,
uses_in_movies INTEGER DEFAULT 0,
rating NUMERIC DEFAULT 0,
duration INTEGER,
bpm INTEGER,
key TEXT,
format TEXT DEFAULT 'mp3',
approved BOOLEAN DEFAULT true,
reviewed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
valence NUMERIC DEFAULT 0.5,
arousal NUMERIC DEFAULT 0.5,
warmth NUMERIC DEFAULT 0.5,
playfulness NUMERIC DEFAULT 0.3,
darkness NUMERIC DEFAULT 0.1,
tension NUMERIC DEFAULT 0.2,
pacing TEXT DEFAULT 'medium',
suitable_for_characters TEXT[],
suitable_for_settings TEXT[],
unsuitable_for TEXT[],
editorial_quality_score INTEGER DEFAULT 70
);
-- profiles: extends auth.users (required by Stripe webhook + credits)
CREATE TABLE IF NOT EXISTS public.profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
credits INTEGER DEFAULT 0,
subscription_tier TEXT,
subscription_status TEXT,
stripe_customer_id TEXT,
stripe_subscription_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_profiles_credits ON public.profiles(credits);
CREATE INDEX IF NOT EXISTS idx_profiles_stripe_customer_id ON public.profiles(stripe_customer_id);
-- Snapshot from remote OpenAPI (push_subscriptions)
CREATE TABLE IF NOT EXISTS public.push_subscriptions (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
job_id TEXT,
endpoint TEXT,
keys JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Snapshot from remote OpenAPI (script_edits)
CREATE TABLE IF NOT EXISTS public.script_edits (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
project_id UUID,
episode_index INTEGER,
line_index INTEGER,
original_line JSONB,
edited_line JSONB,
status TEXT DEFAULT 'edited',
user_id UUID,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- shots: episode pipeline (lib/orchestrators/episode-orchestrator.ts)
CREATE TABLE IF NOT EXISTS public.shots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES public.projects(id) ON DELETE CASCADE,
shot_index INTEGER NOT NULL,
kling_prompt TEXT NOT NULL DEFAULT '',
kling_task_id TEXT,
video_url TEXT,
video_status TEXT NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (project_id, shot_index)
);
CREATE INDEX IF NOT EXISTS idx_shots_project_id ON public.shots(project_id);
-- =============================================================================
-- SECTION C: ALTER-only tables / column alignment
-- =============================================================================
-- movie_shots: only ALTER migrations exist in repo; CREATE from remote OpenAPI snapshot
CREATE TABLE IF NOT EXISTS public.movie_shots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
movie_id UUID,
shot_index INTEGER,
omni_task_id TEXT,
kling_task_id TEXT,
omni_video_url TEXT,
kling_scene_url TEXT,
final_shot_url TEXT,
audio_url TEXT,
status TEXT DEFAULT 'pending',
shotstack_render_id TEXT,
narrative JSONB,
shot_type TEXT DEFAULT 'face',
duration NUMERIC,
retry_count INTEGER DEFAULT 0,
submitted_at TIMESTAMPTZ,
error TEXT,
user_id UUID,
twin_frame_url TEXT,
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_movie_shots_status_updated_at ON public.movie_shots(status, updated_at);
CREATE INDEX IF NOT EXISTS idx_movie_shots_movie_id ON public.movie_shots(movie_id);
-- kling_jobs: code expects columns beyond remote schema (process-kling route)
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS scene_video_url TEXT;
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS result_video_url TEXT;
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS shotstack_render_id TEXT;
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS task_id TEXT;
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
ALTER TABLE public.kling_jobs ADD COLUMN IF NOT EXISTS prompt TEXT;
-- omnihuman_jobs: align migration file with production columns
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS kling_task_id TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS keyframe_url TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS image_url TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS audio_url TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS scene_task_id TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS scene_video_url TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS shotstack_render_id TEXT;
ALTER TABLE public.omnihuman_jobs ADD COLUMN IF NOT EXISTS user_id UUID;
-- movies: columns used in app but not in 20260416 migration
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS story_input TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS twin_photo_url TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS twin_video_url TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS tier TEXT DEFAULT 'standard';
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS paid BOOLEAN DEFAULT false;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS archetype TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS primary_emotion TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS error_message TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS kling_task_id TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS hook_video_url TEXT;
ALTER TABLE public.movies ADD COLUMN IF NOT EXISTS template_id TEXT;
-- =============================================================================
-- SECTION D: Functions from migrations (depend on emotion_lines, profiles)
-- =============================================================================
-- Create function to boost emotion lines based on market feedback
CREATE OR REPLACE FUNCTION boost_emotion_lines(archetype TEXT, boost_amount INT)
RETURNS void AS $$
BEGIN
UPDATE emotion_lines
SET universality_score = LEAST(10, universality_score + boost_amount)
WHERE emotion_tags && ARRAY[archetype]::text[];
END;
$$ LANGUAGE plpgsql;
-- Add comment explaining the function
COMMENT ON FUNCTION boost_emotion_lines IS 'Boosts universality_score for emotion lines matching the given archetype based on positive market feedback. Score is capped at 10.';
-- Add credits column to profiles table
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS credits INTEGER DEFAULT 0;
-- Create function to increment user credits atomically
CREATE OR REPLACE FUNCTION increment_user_credits(user_id UUID, credit_amount INTEGER)
RETURNS VOID AS $$
BEGIN
-- Insert or update profile with credits
INSERT INTO profiles (id, credits)
VALUES (user_id, credit_amount)
ON CONFLICT (id)
DO UPDATE SET credits = profiles.credits + credit_amount;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Add index for faster lookups
CREATE INDEX IF NOT EXISTS idx_profiles_credits ON profiles(credits);
-- Add comment
COMMENT ON COLUMN profiles.credits IS 'Number of movie credits available to the user';