-- Reconcile the early domain migration with the runtime contract. Existing -- installations keep their data; the compatibility columns are populated by -- the payment adapter and the canonical identifier remains provider/event. ALTER TABLE IF EXISTS payment_events ADD COLUMN IF NOT EXISTS external_event_id TEXT; ALTER TABLE IF EXISTS payment_events ADD COLUMN IF NOT EXISTS provider_event_id TEXT; UPDATE payment_events SET external_event_id = COALESCE(external_event_id, provider_event_id) WHERE external_event_id IS NULL; UPDATE payment_events SET provider_event_id = COALESCE(provider_event_id, external_event_id) WHERE provider_event_id IS NULL; CREATE UNIQUE INDEX IF NOT EXISTS payment_events_provider_external_idx ON payment_events(provider, external_event_id) WHERE external_event_id IS NOT NULL; ALTER TABLE IF EXISTS plan_purchases ALTER COLUMN plan_id TYPE TEXT USING plan_id::text; ALTER TABLE IF EXISTS plan_purchases ALTER COLUMN purchase_amount TYPE BIGINT USING purchase_amount::bigint; ALTER TABLE IF EXISTS plan_purchases ALTER COLUMN included_balance TYPE BIGINT USING included_balance::bigint; CREATE UNIQUE INDEX IF NOT EXISTS plan_purchases_user_idempotency_idx ON plan_purchases(user_id, idempotency_key); ALTER TABLE IF EXISTS sessions ADD COLUMN IF NOT EXISTS absolute_expires_at TIMESTAMPTZ; ALTER TABLE IF EXISTS sessions ADD COLUMN IF NOT EXISTS family_id UUID; ALTER TABLE IF EXISTS sessions ADD COLUMN IF NOT EXISTS device_id TEXT; UPDATE sessions SET absolute_expires_at = COALESCE(absolute_expires_at, expires_at) WHERE absolute_expires_at IS NULL;