feat(migrations): create apify_scraper_runs digest-batch table (supersedes #41)

Merged
SW
3mo ago
+50-0

Summary

Schema prerequisite for the one-digest-per-scrape design on recoupable/chat#1855 (PR #2 of 6). Supersedes #41, which ALTERed apify_scraper_runs — a table that was never created: #39 (the chat#1840 ownership map that would have created it) was closed unmerged on 2026-07-03 when run polling moved to the capability model, so #41's migration fails on prod with 42P01: relation "public.apify_scraper_runs" does not exist (verified live 2026-07-09).

This PR creates the table instead, matching the consumer contract in recoupable/api#760 (lib/supabase/apify_scraper_runs/types.ts — run_id, account_id, social_id, platform, batch_id, completed_at, new_post_urls, created_at), which #41's three columns alone would not have satisfied even on an existing table.

Why each column (sanity-checked against "reference the source of truth instead")

  • batch_id — Apify cannot group runs by our scrape call (no run tags, and siblings don't exist yet when the first run's webhook is registered); grouping state must be ours.
  • completed_at — Apify's SUCCEEDED says the scrape finished, not that our webhook processed the results and wrote new_post_urls; using it would race and mis-assemble digests.
  • new_post_urls — "new" = absent from posts immediately before the upsert; the upsert destroys that state moments later, so the diff cannot be re-derived at digest time.
  • account_id / social_id / platform — written at scrape start, read by the digest assembler for section labels and recipient resolution (api#760's insertApifyScraperRuns / getScrapeDigestRecipients).

Scope guard

Digest bookkeeping only — this is not an ownership/authorization map; the chat#1840 capability-model decision stands (polling auth unchanged). Loose ids, no FKs, no backfill; additive and safe to apply standalone (columns sit unused until api#760 lands).

Tracking issue: recoupable/chat#1855. Merge order: this PR → api#759 → api#760 → api#761 → api#762.

🤖 Generated with Claude Code


Summary by cubic

Create the apify_scraper_runs table to support one-digest-per-scrape batching. Supersedes #41 by creating the table (the previous ALTER failed on prod) and aligns with api#760’s expected schema.

  • Migration
    • Create public.apify_scraper_runs with: run_id PK, created_at, account_id, social_id, platform, batch_id, completed_at, new_post_urls.
    • Add partial index on batch_id (WHERE batch_id IS NOT NULL).
    • No foreign keys; bookkeeping-only table.
    • Enables api insert/complete/select flows for digest assembly (recoupable/chat#1855, api#760).