You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

239 lines
16 KiB

"""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 ###