"""add_subscription_plan_fields Revision ID: 007_add_sub_fields Revises: 006_rename_active Create Date: 2026-01-04 Fixes: - Add missing columns to subscription_plans table (custom cycle fields, dynamic pricing fields) """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '007_add_sub_fields' down_revision: Union[str, None] = '006_rename_active' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: """Add missing columns to subscription_plans (skip if already exists)""" from alembic import op import sqlalchemy as sa from sqlalchemy import inspect # Get database connection conn = op.get_bind() inspector = inspect(conn) existing_columns = {col['name'] for col in inspector.get_columns('subscription_plans')} # Custom billing cycle fields if 'custom_cycle_enabled' not in existing_columns: op.add_column('subscription_plans', sa.Column('custom_cycle_enabled', sa.Boolean(), nullable=False, server_default='false')) if 'custom_cycle_start_month' not in existing_columns: op.add_column('subscription_plans', sa.Column('custom_cycle_start_month', sa.Integer(), nullable=True)) if 'custom_cycle_start_day' not in existing_columns: op.add_column('subscription_plans', sa.Column('custom_cycle_start_day', sa.Integer(), nullable=True)) if 'custom_cycle_end_month' not in existing_columns: op.add_column('subscription_plans', sa.Column('custom_cycle_end_month', sa.Integer(), nullable=True)) if 'custom_cycle_end_day' not in existing_columns: op.add_column('subscription_plans', sa.Column('custom_cycle_end_day', sa.Integer(), nullable=True)) # Dynamic pricing fields if 'minimum_price_cents' not in existing_columns: op.add_column('subscription_plans', sa.Column('minimum_price_cents', sa.Integer(), nullable=False, server_default='3000')) if 'suggested_price_cents' not in existing_columns: op.add_column('subscription_plans', sa.Column('suggested_price_cents', sa.Integer(), nullable=True)) if 'allow_donation' not in existing_columns: op.add_column('subscription_plans', sa.Column('allow_donation', sa.Boolean(), nullable=False, server_default='true')) def downgrade() -> None: """Remove added columns (rollback)""" op.drop_column('subscription_plans', 'allow_donation') op.drop_column('subscription_plans', 'suggested_price_cents') op.drop_column('subscription_plans', 'minimum_price_cents') op.drop_column('subscription_plans', 'custom_cycle_end_day') op.drop_column('subscription_plans', 'custom_cycle_end_month') op.drop_column('subscription_plans', 'custom_cycle_start_day') op.drop_column('subscription_plans', 'custom_cycle_start_month') op.drop_column('subscription_plans', 'custom_cycle_enabled')