Core Tables
apify_ads_raw
Source table for all ad data. Contains raw ad metadata from Meta Ad Library scrapers.Primary key. Meta Ad Library archive ID (e.g.,
123456789012345).Advertiser page name from Meta.
Structured ad snapshot from Meta Ad Library API. Contains fields like:
title: ad headlinebody.text: ad copylink_url: destination URLcta_text: call-to-action button textimages: array of image objects withoriginal_image_url,resized_image_urlvideos: array of video objects withvideo_hd_url,video_sd_url,video_preview_image_urlcards: carousel cards with media + link data
Normalized media URLs:
imageUrls: array of image URLsvideoUrls: array of video URLspreviewImageUrls: array of video preview/thumbnail URLs
Full raw scraper payload. Fallback source for fields not in
snapshot.Original landing page URL if captured during scraping.
Direct link to the ad in Meta Ad Library (e.g.,
https://www.facebook.com/ads/library/?id=...).When the ad first went live. Used to compute
days_running.Whether the ad is currently running. Mapped to
Active/Inactive status in feed views.Last time the row was updated. Fallback for
days_running when start_date is null.Row creation timestamp.
user_saved_ads
Per-user saved ads. Junction table linking users to ads they’ve bookmarked.References
auth.users(id). Defaults to auth.uid(). Cascade deletes when user is deleted.References
apify_ads_raw(ad_archive_id). Cascade deletes when ad is removed.When the ad was saved.
Auto-updated via trigger
trg_user_saved_ads_updated_at.(user_id, ad_archive_id)
Indexes:
idx_user_saved_ads_useronuser_ididx_user_saved_ads_adonad_archive_id
user_projects
User-created folders for organizing saved ads.Primary key. Auto-generated via
gen_random_uuid().References
auth.users(id). Defaults to auth.uid(). Cascade deletes.Project name. Must be trimmed, 1-100 characters, unique per user (case-insensitive). Cannot be
"Saved".Project creation time.
Auto-updated when project is modified or ads are added/removed via trigger
trg_user_projects_updated_at.unique (user_id, name)— case-insensitive via migration20260224193000unique (id, user_id)— compound uniqueness for foreign key referencecheck (name = btrim(name))check (char_length(name) between 1 and 100)check (name <> 'Saved')
idx_user_projects_user_idonuser_ididx_user_projects_updated_aton(user_id, updated_at desc)
user_saved_ad_projects
Links saved ads to projects. Many-to-many relationship betweenuser_saved_ads and user_projects.
References
auth.users(id). Cascade deletes.Ad archive ID.
References
user_projects(id, user_id). Cascade deletes when project is deleted.When the ad was added to the project.
(user_id, ad_archive_id, project_id)
Foreign Keys:
(user_id, ad_archive_id)referencesuser_saved_adson delete cascade(project_id, user_id)referencesuser_projects(id, user_id)on delete cascade
idx_user_saved_ad_projects_user_projecton(user_id, project_id, ad_archive_id)idx_user_saved_ad_projects_user_adon(user_id, ad_archive_id, project_id)
trg_user_saved_ad_projects_touch_project— updates parent project’supdated_aton insert/update/delete
Fanbasis Integration Tables
fanbasis_enabled_offers
Tracks which Fanbasis products trigger user provisioning on purchase.Primary key. Fanbasis product/service ID.
Product name.
Product price.
Whether purchases of this product should provision AdRecon access.
Row creation time.
Auto-updated via trigger
trg_fanbasis_enabled_offers_updated_at.fanbasis_webhook_log
Immutable audit log of all Fanbasis webhook events.Primary key. Auto-increment.
Fanbasis event type (e.g.,
payment.succeeded, payment.refunded).Associated product/service ID.
Customer email from webhook payload.
Full webhook event payload.
Processing result:
received, provisioned, revoked, skipped, error.Error detail if
result = 'error'.Event receipt time.
idx_fanbasis_webhook_log_created on created_at desc
Utility Tables
page_rip_log
Rate-limit tracking for Page Ripper (/api/download-page).
Primary key. Auto-increment.
References
auth.users(id). Cascade deletes.Captured landing page URL.
Capture timestamp.
idx_page_rip_log_user_created on (user_id, created_at desc)
Service-role only access. No RLS policies for regular users. API enforces 10 captures per user per 15-minute window.
Relationships
- auth.users (Supabase Auth) → user_saved_ads, user_projects, page_rip_log (cascade delete)
- apify_ads_raw → user_saved_ads (cascade delete if ad removed)
- user_saved_ads + user_projects → user_saved_ad_projects (cascade delete if either parent is removed)