Use this as your manual side note. Code may be on development; production still needs the steps below.
Where: Supabase Dashboard → SQL Editor → New query
File: supabase/supabase-schema.sql
Run these sections in order if you have not already:
| Block | What it adds |
|---|---|
Core news table |
Base columns (skip if DB already has news) |
news_votes + RPCs |
Upvotes on /news/ |
post_comments |
Blog comments |
News auto-ingest (from -- News auto-ingest) |
news.ingest_source, news_feed_sources, news_ingest_log, seed feeds |
Minimum for auto-ingest (sprint 025): copy from line -- News auto-ingest through the final on conflict (slug) do update seed insert.
Verify:
select slug, enabled, kind from public.news_feed_sources order by slug;
select column_name from information_schema.columns
where table_name = 'news' and column_name = 'ingest_source';Where: Supabase Dashboard → Edge Functions → Secrets (or Project Settings → Edge Functions)
| Secret | Used by | Notes |
|---|---|---|
SERVICE_ROLE_KEY |
news-sync, search-ai, etc. |
Service role key from Project Settings → API |
NEWS_SYNC_SECRET |
news-sync |
Generate a long random string; same value goes in GitHub (step 3) |
Also ensure SUPABASE_URL is available to functions (usually automatic).
Where: Supabase Dashboard → Edge Functions → Deploy, or CLI:
supabase functions deploy news-sync --project-ref <your-project-ref>Source: supabase/functions/news-sync/index.ts
After deploy, note the function URL:
https://<project-ref>.supabase.co/functions/v1/news-sync
curl -X POST "https://<project-ref>.supabase.co/functions/v1/news-sync" \
-H "Content-Type: application/json" \
-H "x-sync-secret: <NEWS_SYNC_SECRET>" \
-d '{"sources":["hn-top"]}'Optional — all enabled feeds:
curl -X POST "https://<project-ref>.supabase.co/functions/v1/news-sync" \
-H "Content-Type: application/json" \
-H "x-sync-secret: <NEWS_SYNC_SECRET>" \
-d '{}'Check:
- Response JSON:
"status":"ok"per feed - Table
news_ingest_loghas new rows - Site:
/Blog/news/?freshshows new links withingest_sourceset (badge in sprint 030)
Where: GitHub repo → Settings → Secrets and variables → Actions
| Secret | Value |
|---|---|
NEWS_SYNC_URL |
Full URL from step 3 |
NEWS_SYNC_SECRET |
Same as Supabase secret |
Workflow: .github/workflows/news-sync.yml — runs every 6 hours and on workflow_dispatch.
Existing Pages deploy secrets (unchanged):
PUBLIC_SUPABASE_URLPUBLIC_SUPABASE_ANON_KEYPUBLIC_PLAUSIBLE_DOMAINPUBLIC_JITSI_BASE_URL
- Merge
development→mainwhen ready for production site - Push triggers
.github/workflows/deploy.yml(no extra secrets for news UX)
Where: Supabase → Table Editor → news_feed_sources
- Set
enabled = trueforhn-new, or any RSS slug - Adjust
fetch_limit(max 100 per schema)
Or SQL:
update public.news_feed_sources set enabled = true where slug = 'hn-new';Where: admin/.env (copy from admin/.env.example, gitignored)
SUPABASE_URL=https://<project-ref>.supabase.co
SUPABASE_ANON_KEY=<anon-key>
SITE_BASE_URL=http://localhost:8000/
NEWS_SYNC_SECRET=<same-as-supabase-edge-secret>Generate admin/config.js (also gitignored, used by the browser):
npm run admin:configFor GitHub Pages builds, set repo Actions secrets (or env in deploy workflow): PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, NEWS_SYNC_SECRET, and optionally ADMIN_SITE_BASE_URL (e.g. https://emadram.github.io/Blog/). postbuild runs admin:config before copying to dist/admin.
Serve locally: cd admin && python3 -m http.server 8000 after npm run admin:config.
Redeploy the site (npm run build + push) so /news/ shows Auto · HN Top (etc.) on synced stories and the From feeds filter tab. No new SQL.
Filter URL example: /Blog/news/?tab=feeds&feed=hn-top
| Problem | Check |
|---|---|
Unauthorized on curl |
NEWS_SYNC_SECRET matches header x-sync-secret |
Missing service role |
SERVICE_ROLE_KEY set on Edge Function |
| No new rows | news_feed_sources.enabled; logs in news_ingest_log |
| Duplicates skipped | Expected — unique index on news.url |
| RSS feed errors | last_error on feed row; feed URL reachable from Supabase |
Last updated: sprints 025–028 (schema, HN sync, RSS sync, cron workflow).