"""Уникальность дейли и бонуса уровня (ТЗ 3.13): гонки параллельных запросов.
Revision ID: e7f8a9b0c1d2
Revises: d5e6a7b8c9d0
Create Date: 2026-09-21 13:00:00.000000
"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
revision: str = "e7f8a9b0c1d2"
down_revision: str | Sequence[str] | None = "d5e6a7b8c9d0"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
# Частичные индексы — и в Postgres, и в SQLite: дубликаты не допускаются,
# старые строки (NULL-ключи) не трогаем — NULL в уникальном индексе не сталкиваются
DAILY_WHERE = sa.text("source = 'daily'")
LEVEL_WHERE = sa.text("source = 'level' AND level IS NOT NULL")
def upgrade() -> None:
op.add_column("coin_events", sa.Column("day", sa.Date(), nullable=True))
op.create_index(
"uq_coin_daily",
"coin_events",
["source", "day"],
unique=True,
postgresql_where=DAILY_WHERE,
sqlite_where=DAILY_WHERE,
)
op.create_index(
"uq_coin_level",
"coin_events",
["level"],
unique=True,
postgresql_where=LEVEL_WHERE,
sqlite_where=LEVEL_WHERE,
)
def downgrade() -> None:
op.drop_index("uq_coin_level", table_name="coin_events")
op.drop_index("uq_coin_daily", table_name="coin_events")
op.drop_column("coin_events", "day")