"""Initial migration Revision ID: cc52be716e44 Revises: Create Date: 2026-03-24 13:55:23.460098 """ from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision = 'cc52be716e44' down_revision = None branch_labels = None depends_on = None def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('accounts', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('username', sa.String(length=64), nullable=False), sa.Column('password_hash', sa.String(length=255), nullable=False), sa.Column('display_name', sa.String(length=64), nullable=True), sa.Column('role', sa.String(length=32), nullable=False), sa.Column('status', sa.String(length=16), nullable=False), sa.Column('last_login_at', sa.DateTime(), nullable=True), sa.Column('created_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('updated_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['created_by'], ['accounts.id'], name=op.f('fk_accounts_created_by_accounts'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['updated_by'], ['accounts.id'], name=op.f('fk_accounts_updated_by_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_accounts')), sa.UniqueConstraint('username', name='uk_accounts_username') ) with op.batch_alter_table('accounts', schema=None) as batch_op: batch_op.create_index('idx_accounts_last_login_at', ['last_login_at'], unique=False) batch_op.create_index('idx_accounts_role_status', ['role', 'status'], unique=False) op.create_table('audit_logs', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('actor_user_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('actor_username', sa.String(length=64), nullable=False), sa.Column('actor_display_name', sa.String(length=64), nullable=True), sa.Column('action_type', sa.String(length=32), nullable=False), sa.Column('target_type', sa.String(length=32), nullable=False), sa.Column('target_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('target_display_name', sa.String(length=128), nullable=True), sa.Column('before_data_json', sa.JSON(), nullable=True), sa.Column('after_data_json', sa.JSON(), nullable=True), sa.Column('request_path', sa.String(length=255), nullable=True), sa.Column('request_method', sa.String(length=16), nullable=True), sa.Column('ip_address', sa.String(length=45), nullable=True), sa.Column('user_agent', sa.String(length=512), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['actor_user_id'], ['accounts.id'], name=op.f('fk_audit_logs_actor_user_id_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_audit_logs')) ) with op.batch_alter_table('audit_logs', schema=None) as batch_op: batch_op.create_index('idx_audit_logs_action_created_at', ['action_type', 'created_at'], unique=False) batch_op.create_index('idx_audit_logs_actor_created_at', ['actor_user_id', 'created_at'], unique=False) batch_op.create_index('idx_audit_logs_created_at', ['created_at'], unique=False) batch_op.create_index('idx_audit_logs_target', ['target_type', 'target_id', 'created_at'], unique=False) op.create_table('option_items', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('option_group', sa.String(length=32), nullable=False), sa.Column('option_code', sa.String(length=64), nullable=False), sa.Column('option_label', sa.String(length=64), nullable=False), sa.Column('parent_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('sort_order', sa.Integer(), nullable=False), sa.Column('is_enabled', sa.Boolean(), nullable=False), sa.Column('is_system', sa.Boolean(), nullable=False), sa.Column('extra_json', sa.JSON(), nullable=True), sa.Column('created_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('updated_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['created_by'], ['accounts.id'], name=op.f('fk_option_items_created_by_accounts'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['parent_id'], ['option_items.id'], name=op.f('fk_option_items_parent_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['updated_by'], ['accounts.id'], name=op.f('fk_option_items_updated_by_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_option_items')), sa.UniqueConstraint('option_group', 'option_code', name='uk_option_items_group_code'), sa.UniqueConstraint('option_group', 'parent_id', 'option_label', name='uk_option_items_group_parent_label') ) with op.batch_alter_table('option_items', schema=None) as batch_op: batch_op.create_index('idx_option_items_group_enabled_sort', ['option_group', 'is_enabled', 'sort_order'], unique=False) batch_op.create_index('idx_option_items_parent_id', ['parent_id'], unique=False) op.create_table('households', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('household_code', sa.String(length=32), nullable=False), sa.Column('head_name', sa.String(length=64), nullable=False), sa.Column('phone', sa.String(length=32), nullable=True), sa.Column('side', sa.String(length=32), nullable=False), sa.Column('relation_category_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('relation_detail_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('tag_option_ids_json', sa.JSON(), nullable=True), sa.Column('invite_status', sa.String(length=32), nullable=False), sa.Column('attendance_status', sa.String(length=32), nullable=False), sa.Column('expected_attendee_count', sa.Integer(), nullable=False), sa.Column('actual_attendee_count', sa.Integer(), nullable=False), sa.Column('child_count', sa.Integer(), nullable=False), sa.Column('red_packet_child_count', sa.Integer(), nullable=False), sa.Column('total_gift_amount', sa.Numeric(precision=12, scale=2), nullable=False), sa.Column('gift_method_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('gift_scene_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('favor_status', sa.String(length=32), nullable=False), sa.Column('candy_status', sa.String(length=32), nullable=False), sa.Column('child_red_packet_status', sa.String(length=32), nullable=False), sa.Column('note', sa.Text(), nullable=True), sa.Column('created_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('updated_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('deleted_at', sa.DateTime(), nullable=True), sa.Column('version', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['created_by'], ['accounts.id'], name=op.f('fk_households_created_by_accounts'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['gift_method_option_id'], ['option_items.id'], name=op.f('fk_households_gift_method_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['gift_scene_option_id'], ['option_items.id'], name=op.f('fk_households_gift_scene_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['relation_category_option_id'], ['option_items.id'], name=op.f('fk_households_relation_category_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['relation_detail_option_id'], ['option_items.id'], name=op.f('fk_households_relation_detail_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['updated_by'], ['accounts.id'], name=op.f('fk_households_updated_by_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_households')), sa.UniqueConstraint('household_code', name='uk_households_household_code') ) with op.batch_alter_table('households', schema=None) as batch_op: batch_op.create_index('idx_households_attendance_status', ['attendance_status'], unique=False) batch_op.create_index('idx_households_deleted_at', ['deleted_at'], unique=False) batch_op.create_index('idx_households_head_name', ['head_name'], unique=False) batch_op.create_index('idx_households_phone', ['phone'], unique=False) batch_op.create_index('idx_households_side_relation_category', ['side', 'relation_category_option_id'], unique=False) batch_op.create_index('idx_households_updated_at', ['updated_at'], unique=False) op.create_table('gift_records', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('household_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('record_type', sa.String(length=32), nullable=False), sa.Column('amount', sa.Numeric(precision=12, scale=2), nullable=True), sa.Column('gift_name', sa.String(length=128), nullable=True), sa.Column('estimated_value', sa.Numeric(precision=12, scale=2), nullable=True), sa.Column('method_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('scene_option_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('record_time', sa.DateTime(), nullable=False), sa.Column('created_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('updated_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('deleted_at', sa.DateTime(), nullable=True), sa.Column('note', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['created_by'], ['accounts.id'], name=op.f('fk_gift_records_created_by_accounts'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['household_id'], ['households.id'], name=op.f('fk_gift_records_household_id_households'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['method_option_id'], ['option_items.id'], name=op.f('fk_gift_records_method_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['scene_option_id'], ['option_items.id'], name=op.f('fk_gift_records_scene_option_id_option_items'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['updated_by'], ['accounts.id'], name=op.f('fk_gift_records_updated_by_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_gift_records')) ) with op.batch_alter_table('gift_records', schema=None) as batch_op: batch_op.create_index('idx_gift_records_deleted_at', ['deleted_at'], unique=False) batch_op.create_index('idx_gift_records_household_id', ['household_id'], unique=False) batch_op.create_index('idx_gift_records_household_record_time', ['household_id', 'record_time'], unique=False) batch_op.create_index('idx_gift_records_record_time', ['record_time'], unique=False) batch_op.create_index('idx_gift_records_record_type', ['record_type'], unique=False) op.create_table('household_members', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('household_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('name', sa.String(length=64), nullable=False), sa.Column('relation_to_head', sa.String(length=64), nullable=True), sa.Column('gender', sa.String(length=16), nullable=True), sa.Column('age_group', sa.String(length=32), nullable=True), sa.Column('is_child', sa.Boolean(), nullable=False), sa.Column('needs_red_packet', sa.Boolean(), nullable=False), sa.Column('expected_to_attend', sa.Boolean(), nullable=False), sa.Column('actually_attended', sa.Boolean(), nullable=False), sa.Column('sort_order', sa.Integer(), nullable=False), sa.Column('note', sa.Text(), nullable=True), sa.Column('created_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('updated_by', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False), sa.ForeignKeyConstraint(['created_by'], ['accounts.id'], name=op.f('fk_household_members_created_by_accounts'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['household_id'], ['households.id'], name=op.f('fk_household_members_household_id_households'), ondelete='RESTRICT'), sa.ForeignKeyConstraint(['updated_by'], ['accounts.id'], name=op.f('fk_household_members_updated_by_accounts'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_household_members')) ) with op.batch_alter_table('household_members', schema=None) as batch_op: batch_op.create_index('idx_household_members_household_id', ['household_id'], unique=False) batch_op.create_index('idx_household_members_household_name', ['household_id', 'name'], unique=False) batch_op.create_index('idx_household_members_household_sort', ['household_id', 'sort_order'], unique=False) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### with op.batch_alter_table('household_members', schema=None) as batch_op: batch_op.drop_index('idx_household_members_household_sort') batch_op.drop_index('idx_household_members_household_name') batch_op.drop_index('idx_household_members_household_id') op.drop_table('household_members') with op.batch_alter_table('gift_records', schema=None) as batch_op: batch_op.drop_index('idx_gift_records_record_type') batch_op.drop_index('idx_gift_records_record_time') batch_op.drop_index('idx_gift_records_household_record_time') batch_op.drop_index('idx_gift_records_household_id') batch_op.drop_index('idx_gift_records_deleted_at') op.drop_table('gift_records') with op.batch_alter_table('households', schema=None) as batch_op: batch_op.drop_index('idx_households_updated_at') batch_op.drop_index('idx_households_side_relation_category') batch_op.drop_index('idx_households_phone') batch_op.drop_index('idx_households_head_name') batch_op.drop_index('idx_households_deleted_at') batch_op.drop_index('idx_households_attendance_status') op.drop_table('households') with op.batch_alter_table('option_items', schema=None) as batch_op: batch_op.drop_index('idx_option_items_parent_id') batch_op.drop_index('idx_option_items_group_enabled_sort') op.drop_table('option_items') with op.batch_alter_table('audit_logs', schema=None) as batch_op: batch_op.drop_index('idx_audit_logs_target') batch_op.drop_index('idx_audit_logs_created_at') batch_op.drop_index('idx_audit_logs_actor_created_at') batch_op.drop_index('idx_audit_logs_action_created_at') op.drop_table('audit_logs') with op.batch_alter_table('accounts', schema=None) as batch_op: batch_op.drop_index('idx_accounts_role_status') batch_op.drop_index('idx_accounts_last_login_at') op.drop_table('accounts') # ### end Alembic commands ###