diff --git a/src/email-subscribers/metadata.ts b/src/email-subscribers/metadata.ts new file mode 100644 index 00000000..e1a75a37 --- /dev/null +++ b/src/email-subscribers/metadata.ts @@ -0,0 +1,23 @@ +// Schema for the `metadata` jsonb column on `publication_email_subscribers`. +// +// The column is nullable — most rows have no metadata at all (organic +// signups). Within each variant, only the `source` discriminator is +// required; every other field is optional because different writers +// populate different subsets. + +export type CsvImportProvenance = { + source: "csv_import"; + imported_at?: string; + // Other CSV columns that the import script didn't consume directly + // (e.g. ip_address, signup_source) — kept verbatim so we don't lose + // information from the source list. The subscription date is not + // stored here; it lives on `created_at`/`confirmed_at`. + csv_columns?: Record; +}; + +// Discriminated union of known subscriber-row metadata shapes. Extend as +// new sources start writing the column. +export type SubscriberMetadata = CsvImportProvenance; + +// Column-level type — most rows are null. +export type SubscriberMetadataColumn = SubscriberMetadata | null; diff --git a/supabase/migrations/20260507205333_add_subscriber_metadata.sql b/supabase/migrations/20260507205333_add_subscriber_metadata.sql new file mode 100644 index 00000000..c5deba00 --- /dev/null +++ b/supabase/migrations/20260507205333_add_subscriber_metadata.sql @@ -0,0 +1,7 @@ +-- Provenance metadata on email subscribers (e.g. csv_import, imported_at, +-- original_subscription_date). The events table already has its own +-- per-event metadata column; this one tags the subscriber row itself so +-- "where did these subscribers come from" is a one-table query. + +alter table "public"."publication_email_subscribers" + add column "metadata" jsonb;