-- ============================================================================ -- Fix Missing Fields Script -- Safely adds missing fields without recreating existing structures -- ============================================================================ BEGIN; \echo '=== FIXING USERS TABLE ===' -- Fix TOS field name if needed (tos_accepted -> accepts_tos) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'tos_accepted' ) AND NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'accepts_tos' ) THEN ALTER TABLE users RENAME COLUMN tos_accepted TO accepts_tos; RAISE NOTICE 'Renamed tos_accepted to accepts_tos'; END IF; END $$; -- Add reminder tracking fields if missing DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'email_verification_reminders_sent' ) THEN ALTER TABLE users ADD COLUMN email_verification_reminders_sent INTEGER DEFAULT 0 NOT NULL; ALTER TABLE users ADD COLUMN last_email_verification_reminder_at TIMESTAMP WITH TIME ZONE; ALTER TABLE users ADD COLUMN event_attendance_reminders_sent INTEGER DEFAULT 0 NOT NULL; ALTER TABLE users ADD COLUMN last_event_attendance_reminder_at TIMESTAMP WITH TIME ZONE; ALTER TABLE users ADD COLUMN payment_reminders_sent INTEGER DEFAULT 0 NOT NULL; ALTER TABLE users ADD COLUMN last_payment_reminder_at TIMESTAMP WITH TIME ZONE; ALTER TABLE users ADD COLUMN renewal_reminders_sent INTEGER DEFAULT 0 NOT NULL; ALTER TABLE users ADD COLUMN last_renewal_reminder_at TIMESTAMP WITH TIME ZONE; RAISE NOTICE 'Added reminder tracking fields'; END IF; END $$; -- Add WordPress import fields if missing DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'import_source' ) THEN ALTER TABLE users ADD COLUMN import_source VARCHAR(50); ALTER TABLE users ADD COLUMN import_job_id UUID REFERENCES import_jobs(id); ALTER TABLE users ADD COLUMN wordpress_user_id BIGINT; ALTER TABLE users ADD COLUMN wordpress_registered_date TIMESTAMP WITH TIME ZONE; RAISE NOTICE 'Added WordPress import tracking fields'; END IF; END $$; \echo '=== FIXING IMPORT_JOBS TABLE ===' -- Add WordPress import enhancement fields if missing DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'import_jobs' AND column_name = 'field_mapping' ) THEN ALTER TABLE import_jobs ADD COLUMN field_mapping JSONB DEFAULT '{}'::jsonb; ALTER TABLE import_jobs ADD COLUMN wordpress_metadata JSONB DEFAULT '{}'::jsonb; ALTER TABLE import_jobs ADD COLUMN imported_user_ids JSONB DEFAULT '[]'::jsonb; ALTER TABLE import_jobs ADD COLUMN rollback_at TIMESTAMP WITH TIME ZONE; ALTER TABLE import_jobs ADD COLUMN rollback_by UUID REFERENCES users(id); RAISE NOTICE 'Added WordPress import enhancement fields to import_jobs'; END IF; END $$; -- Add validating, preview_ready, rolled_back to ImportJobStatus enum if missing DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'importjobstatus' AND e.enumlabel = 'validating' ) THEN ALTER TYPE importjobstatus ADD VALUE IF NOT EXISTS 'validating'; RAISE NOTICE 'Added validating to importjobstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'importjobstatus' AND e.enumlabel = 'preview_ready' ) THEN ALTER TYPE importjobstatus ADD VALUE IF NOT EXISTS 'preview_ready'; RAISE NOTICE 'Added preview_ready to importjobstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'importjobstatus' AND e.enumlabel = 'rolled_back' ) THEN ALTER TYPE importjobstatus ADD VALUE IF NOT EXISTS 'rolled_back'; RAISE NOTICE 'Added rolled_back to importjobstatus enum'; END IF; END $$; -- Add pending_validation, pre_validated, canceled, expired, abandoned to UserStatus enum if missing DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus' AND e.enumlabel = 'pending_validation' ) THEN ALTER TYPE userstatus ADD VALUE IF NOT EXISTS 'pending_validation'; RAISE NOTICE 'Added pending_validation to userstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus' AND e.enumlabel = 'pre_validated' ) THEN ALTER TYPE userstatus ADD VALUE IF NOT EXISTS 'pre_validated'; RAISE NOTICE 'Added pre_validated to userstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus' AND e.enumlabel = 'canceled' ) THEN ALTER TYPE userstatus ADD VALUE IF NOT EXISTS 'canceled'; RAISE NOTICE 'Added canceled to userstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus' AND e.enumlabel = 'expired' ) THEN ALTER TYPE userstatus ADD VALUE IF NOT EXISTS 'expired'; RAISE NOTICE 'Added expired to userstatus enum'; END IF; IF NOT EXISTS ( SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus' AND e.enumlabel = 'abandoned' ) THEN ALTER TYPE userstatus ADD VALUE IF NOT EXISTS 'abandoned'; RAISE NOTICE 'Added abandoned to userstatus enum'; END IF; END $$; COMMIT; \echo '' \echo '=== VERIFICATION ===' SELECT (SELECT COUNT(*) FROM information_schema.columns WHERE table_name = 'users') as users_columns, (SELECT COUNT(*) FROM information_schema.columns WHERE table_name = 'import_jobs') as import_jobs_columns, (SELECT COUNT(*) FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'userstatus') as userstatus_values, (SELECT COUNT(*) FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'importjobstatus') as importjobstatus_values; \echo '' \echo '✅ Missing fields have been added!' \echo 'You can now run: alembic stamp head'