Files
saldo/migrations/versions/71ff8f291d18_initial_schema.py
2026-04-21 21:17:36 +02:00

240 lines
11 KiB
Python

"""initial schema
Revision ID: 71ff8f291d18
Revises:
Create Date: 2026-04-20 16:47:07.607628
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '71ff8f291d18'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('account',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=120), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name'),
sa.UniqueConstraint('slug')
)
op.create_table('month',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('label', sa.String(length=7), nullable=False),
sa.Column('year', sa.Integer(), nullable=False),
sa.Column('month', sa.Integer(), nullable=False),
sa.Column('auto_created', sa.Boolean(), nullable=False),
sa.Column('is_locked', sa.Boolean(), nullable=False),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('label')
)
op.create_table('user',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('username', sa.String(length=80), nullable=False),
sa.Column('email', sa.String(length=255), nullable=False),
sa.Column('password_hash', sa.String(length=255), nullable=False),
sa.Column('role', sa.String(length=20), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('email'),
sa.UniqueConstraint('username')
)
op.create_table('allocation_suggestion',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('month_id', sa.Integer(), nullable=False),
sa.Column('target_account_id', sa.Integer(), nullable=False),
sa.Column('suggested_amount', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('reason', sa.Text(), nullable=True),
sa.Column('strategy_key', sa.String(length=80), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['month_id'], ['month.id'], ),
sa.ForeignKeyConstraint(['target_account_id'], ['account.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('audit_log',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('action', sa.String(length=120), nullable=False),
sa.Column('entity_type', sa.String(length=80), nullable=False),
sa.Column('entity_id', sa.Integer(), nullable=True),
sa.Column('payload_json', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('category',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('account_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=120), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['account_id'], ['account.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('account_id', 'slug')
)
op.create_table('cost_participant',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=120), nullable=False),
sa.Column('is_app_user', sa.Boolean(), nullable=False),
sa.Column('linked_user_id', sa.Integer(), nullable=True),
sa.Column('is_external', sa.Boolean(), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['linked_user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('in_app_notification',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('type', sa.String(length=50), nullable=False),
sa.Column('title', sa.String(length=150), nullable=False),
sa.Column('body', sa.Text(), nullable=False),
sa.Column('action_url', sa.String(length=255), nullable=True),
sa.Column('is_read', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('monthly_allocation',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('month_id', sa.Integer(), nullable=False),
sa.Column('target_account_id', sa.Integer(), nullable=False),
sa.Column('label', sa.String(length=120), nullable=False),
sa.Column('amount', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('source', sa.String(length=30), nullable=False),
sa.Column('is_locked', sa.Boolean(), nullable=False),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['month_id'], ['month.id'], ),
sa.ForeignKeyConstraint(['target_account_id'], ['account.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('month_id', 'target_account_id')
)
op.create_table('monthly_income',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('month_id', sa.Integer(), nullable=False),
sa.Column('label', sa.String(length=120), nullable=False),
sa.Column('amount', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['month_id'], ['month.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('notification_preference',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('notify_month_end', sa.Boolean(), nullable=False),
sa.Column('notify_missing_distribution', sa.Boolean(), nullable=False),
sa.Column('notify_missing_values', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('user_id')
)
op.create_table('push_subscription',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('endpoint', sa.Text(), nullable=False),
sa.Column('p256dh_key', sa.Text(), nullable=False),
sa.Column('auth_key', sa.Text(), nullable=False),
sa.Column('user_agent', sa.String(length=255), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('entry',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('category_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=120), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('default_amount', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('amount_type', sa.String(length=20), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('sort_order', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['category_id'], ['category.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('category_id', 'slug')
)
op.create_table('entry_share_rule',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('entry_id', sa.Integer(), nullable=False),
sa.Column('participant_id', sa.Integer(), nullable=False),
sa.Column('share_type', sa.String(length=20), nullable=False),
sa.Column('share_value', sa.Numeric(precision=12, scale=4), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['entry_id'], ['entry.id'], ),
sa.ForeignKeyConstraint(['participant_id'], ['cost_participant.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('entry_id', 'participant_id')
)
op.create_table('monthly_entry_value',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('month_id', sa.Integer(), nullable=False),
sa.Column('entry_id', sa.Integer(), nullable=False),
sa.Column('planned_amount', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('note', sa.Text(), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=True),
sa.Column('updated_by', sa.Integer(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['user.id'], ),
sa.ForeignKeyConstraint(['entry_id'], ['entry.id'], ),
sa.ForeignKeyConstraint(['month_id'], ['month.id'], ),
sa.ForeignKeyConstraint(['updated_by'], ['user.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('month_id', 'entry_id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('monthly_entry_value')
op.drop_table('entry_share_rule')
op.drop_table('entry')
op.drop_table('push_subscription')
op.drop_table('notification_preference')
op.drop_table('monthly_income')
op.drop_table('monthly_allocation')
op.drop_table('in_app_notification')
op.drop_table('cost_participant')
op.drop_table('category')
op.drop_table('audit_log')
op.drop_table('allocation_suggestion')
op.drop_table('user')
op.drop_table('month')
op.drop_table('account')
# ### end Alembic commands ###