"""Eingang fuer extern erfasste Zahlungen und Geraetemarken. Der Kontoauszug kommt erst am Monatsende; wer eine Zahlung gleich erfasst, weiss noch, wofuer sie war. ``inbox_items`` haelt solche Zahlungen fest und bleibt auch nach dem Buchen bestehen, damit der spaetere CSV-Import sie wiedererkennt und nicht ein zweites Mal verbucht. ``api_tokens`` gibt Geraeten ein Zugangsmerkmal, die sich nicht anmelden koennen (iOS-Kurzbefehle). Der Geltungsbereich ist bewusst eng: nur erfassen, nicht lesen. Revision ID: 0015 Revises: 0014 """ import sqlalchemy as sa from alembic import op revision = "0015" down_revision = "0014" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "api_tokens", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("owner_id", sa.Integer(), nullable=False), sa.Column("name", sa.String(length=80), nullable=False), sa.Column("token_hash", sa.String(length=64), nullable=False), sa.Column("scope", sa.String(length=32), nullable=False, server_default="quick_add"), sa.Column("default_account_id", sa.Integer(), nullable=True), sa.Column("last_used_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint(["owner_id"], ["users.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["default_account_id"], ["accounts.id"], ondelete="SET NULL"), ) op.create_index("ix_api_tokens_owner_id", "api_tokens", ["owner_id"]) op.create_index("ix_api_tokens_token_hash", "api_tokens", ["token_hash"], unique=True) op.create_table( "inbox_items", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("owner_id", sa.Integer(), nullable=False), sa.Column("source", sa.String(length=32), nullable=False), sa.Column("status", sa.String(length=32), nullable=False, server_default="pending"), sa.Column("account_id", sa.Integer(), nullable=True), sa.Column("date", sa.Date(), nullable=False), sa.Column("amount_cents", sa.Integer(), nullable=False), sa.Column("currency", sa.String(length=3), nullable=False, server_default="EUR"), sa.Column("payee", sa.String(length=255), nullable=True), sa.Column("note", sa.Text(), nullable=True), sa.Column("category_id", sa.Integer(), nullable=True), sa.Column("transaction_id", sa.Integer(), nullable=True), sa.Column("external_id", sa.String(length=255), nullable=True), sa.Column("raw_text", sa.Text(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint(["owner_id"], ["users.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["account_id"], ["accounts.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["category_id"], ["categories.id"], ondelete="SET NULL"), # SET NULL, nicht CASCADE: Wird die Buchung geloescht, muss der # Eingangs-Eintrag bleiben – sonst kaeme die Zahlung beim naechsten # Auszug unbemerkt ein zweites Mal herein. sa.ForeignKeyConstraint(["transaction_id"], ["transactions.id"], ondelete="SET NULL"), sa.UniqueConstraint("owner_id", "source", "external_id", name="uq_inbox_owner_source_external"), ) op.create_index("ix_inbox_items_owner_id", "inbox_items", ["owner_id"]) op.create_index("ix_inbox_items_account_id", "inbox_items", ["account_id"]) op.create_index("ix_inbox_items_date", "inbox_items", ["date"]) def downgrade() -> None: op.drop_table("inbox_items") op.drop_table("api_tokens")