Skip to content

Commit 775630d

Browse files
Miriadresearch
andcommitted
feat: add pg_cron migration for multi-step pipeline schedules
Adds 002_cron_schedules.sql with idempotent schedules for: - ingest-daily (10:00 UTC) - check-research (every 5 min) - check-renders (every 5 min) - sponsor-outreach (Mon/Thu 09:00 UTC) Uses DO blocks for safe unschedule on re-runs. Co-authored-by: research <research@miriad.systems>
1 parent ad546ee commit 775630d

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
-- ==========================================================================
2+
-- pg_cron schedules for CodingCat.dev automated video pipeline
3+
-- ==========================================================================
4+
--
5+
-- Prerequisites:
6+
-- These Supabase config vars must be set before running this migration:
7+
-- ALTER DATABASE postgres SET app.site_url = 'https://your-vercel-url.vercel.app';
8+
-- ALTER DATABASE postgres SET app.cron_secret = 'your-cron-secret-here';
9+
--
10+
-- You can set them in the Supabase dashboard under Database → Extensions,
11+
-- or via SQL in the SQL Editor.
12+
--
13+
-- Pipeline flow:
14+
-- 1. ingest-daily → discovers trends, creates Sanity doc (status: "researching" or "script_ready")
15+
-- 2. check-research → polls NotebookLM, enriches script, transitions to "script_ready"
16+
-- 3. check-renders → audio gen → Remotion render → upload → publish
17+
-- 4. sponsor-outreach → automated sponsor discovery + outreach emails
18+
-- ==========================================================================
19+
20+
-- Enable required extensions
21+
CREATE EXTENSION IF NOT EXISTS pg_cron;
22+
CREATE EXTENSION IF NOT EXISTS pg_net;
23+
24+
-- ---------------------------------------------------------------------------
25+
-- Remove any existing schedules (idempotent re-runs)
26+
-- ---------------------------------------------------------------------------
27+
-- pg_cron's unschedule() throws if the job doesn't exist, so we use DO blocks
28+
DO $$
29+
BEGIN
30+
PERFORM cron.unschedule('ingest-daily');
31+
EXCEPTION WHEN OTHERS THEN
32+
NULL;
33+
END $$;
34+
35+
DO $$
36+
BEGIN
37+
PERFORM cron.unschedule('check-research');
38+
EXCEPTION WHEN OTHERS THEN
39+
NULL;
40+
END $$;
41+
42+
DO $$
43+
BEGIN
44+
PERFORM cron.unschedule('check-renders');
45+
EXCEPTION WHEN OTHERS THEN
46+
NULL;
47+
END $$;
48+
49+
DO $$
50+
BEGIN
51+
PERFORM cron.unschedule('sponsor-outreach');
52+
EXCEPTION WHEN OTHERS THEN
53+
NULL;
54+
END $$;
55+
56+
-- ---------------------------------------------------------------------------
57+
-- Schedule: Ingest — daily at 10:00 UTC
58+
-- ---------------------------------------------------------------------------
59+
SELECT cron.schedule(
60+
'ingest-daily',
61+
'0 10 * * *',
62+
$$SELECT net.http_get(
63+
url := current_setting('app.site_url') || '/api/cron/ingest',
64+
headers := jsonb_build_object('Authorization', 'Bearer ' || current_setting('app.cron_secret'))
65+
)$$
66+
);
67+
68+
-- ---------------------------------------------------------------------------
69+
-- Schedule: Check Research — every 5 minutes
70+
-- Polls NotebookLM for docs in "researching" status
71+
-- ---------------------------------------------------------------------------
72+
SELECT cron.schedule(
73+
'check-research',
74+
'*/5 * * * *',
75+
$$SELECT net.http_get(
76+
url := current_setting('app.site_url') || '/api/cron/check-research',
77+
headers := jsonb_build_object('Authorization', 'Bearer ' || current_setting('app.cron_secret'))
78+
)$$
79+
);
80+
81+
-- ---------------------------------------------------------------------------
82+
-- Schedule: Check Renders — every 5 minutes
83+
-- Polls Remotion render status, uploads completed videos
84+
-- ---------------------------------------------------------------------------
85+
SELECT cron.schedule(
86+
'check-renders',
87+
'*/5 * * * *',
88+
$$SELECT net.http_get(
89+
url := current_setting('app.site_url') || '/api/cron/check-renders',
90+
headers := jsonb_build_object('Authorization', 'Bearer ' || current_setting('app.cron_secret'))
91+
)$$
92+
);
93+
94+
-- ---------------------------------------------------------------------------
95+
-- Schedule: Sponsor Outreach — Mon/Thu at 09:00 UTC
96+
-- ---------------------------------------------------------------------------
97+
SELECT cron.schedule(
98+
'sponsor-outreach',
99+
'0 9 * * 1,4',
100+
$$SELECT net.http_get(
101+
url := current_setting('app.site_url') || '/api/cron/sponsor-outreach',
102+
headers := jsonb_build_object('Authorization', 'Bearer ' || current_setting('app.cron_secret'))
103+
)$$
104+
);

0 commit comments

Comments
 (0)