Files
certain/backend/migrations/versions/0009_rule_kind.py
T
GuidoandClaude Opus 4.8 d1cab19264 feat: gleiches Schlagwort für Einnahme UND Ausgabe erlaubt (Art je Regel)
- CategorizationRule bekommt `kind` (expense|income|transfer); Unique jetzt
  (owner, match_field, pattern, kind) statt ohne kind
- Konfliktprüfung/Anlage (add/update Keyword, Transfer-Keyword, gelernte Regeln)
  arbeiten kind-bewusst: dasselbe Wort je einmal pro Art möglich
- Migration 0009 mit Backfill (kind aus Kategorie-Art bzw. is_transfer)
- Tests angepasst: quer über Arten erlaubt, gleiche Art weiterhin Konflikt (71 grün)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-20 16:37:35 +02:00

49 lines
1.7 KiB
Python

"""Regeln: Art (kind) je Regel + Unique inkl. kind.
Erlaubt, dasselbe Schlagwort einmal für eine Ausgabe- UND einmal für eine
Einnahme-Kategorie (bzw. als Transfer) zu verwenden. ``kind`` wird aus der
zugehörigen Kategorie bzw. ``is_transfer`` zurückgefüllt.
Revision ID: 0009
Revises: 0008
Create Date: 2026-08-20
"""
from alembic import op
import sqlalchemy as sa
revision = "0009"
down_revision = "0008"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.add_column(
"categorization_rules",
sa.Column("kind", sa.String(length=16), nullable=False, server_default="expense"),
)
# Backfill: Transfer-Regeln -> "transfer", sonst die Art der Kategorie.
op.execute("UPDATE categorization_rules SET kind = 'transfer' WHERE is_transfer = 1")
op.execute(
"UPDATE categorization_rules SET kind = ("
" SELECT c.type FROM categories c WHERE c.id = categorization_rules.category_id"
") WHERE is_transfer = 0 AND category_id IS NOT NULL"
)
# Unique-Constraint um kind erweitern (SQLite: über batch neu aufbauen).
with op.batch_alter_table("categorization_rules") as batch:
batch.drop_constraint("uq_rule_owner_field_pattern", type_="unique")
batch.create_unique_constraint(
"uq_rule_owner_field_pattern_kind",
["owner_id", "match_field", "pattern", "kind"],
)
def downgrade() -> None:
with op.batch_alter_table("categorization_rules") as batch:
batch.drop_constraint("uq_rule_owner_field_pattern_kind", type_="unique")
batch.create_unique_constraint(
"uq_rule_owner_field_pattern",
["owner_id", "match_field", "pattern"],
)
batch.drop_column("kind")