"""drop runs / usage_events tables + tasks 加 run_status / run_error。

Revision ID: 0004
Revises: 0003
Create Date: 2026-05-18

按 DESIGN §7.4 / §7.7 简化:
- usage_events 表纯死代码(从未写入 / 读取),为"未来计费"预付的架构成本 — 删
- runs 表实质就是"task 当前 in-flight 状态"的影子表:tokens_p/c 写但从未被读
  (tokens 真正走 tasks.tokens_prompt/_completion 累计版),started_at/finished_at
  /error 也只写不读,run_id 只有 broker pub/sub 和 cancel 参数两个用途 — 现在
  cancel 改 task-level、broker 改 task_id 索引,run_id 完全不需要 — 删
- tasks 加两列承接 run 当前状态:
  `run_status text default 'idle'`(idle / running / cancelling / error)
  `run_error text`(error 状态的错误文本,其他状态为 NULL)

`ok / cancelled` 收尾直接回 `idle`(不留"上次跑挂"的持久标记);只有 `error` 是
持久终态(下次起新 run 时清掉)。
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa

revision: str = "0004"
down_revision: Union[str, None] = "0003"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    op.drop_table("usage_events")
    op.drop_table("runs")

    op.add_column(
        "tasks",
        sa.Column(
            "run_status", sa.Text(), nullable=False, server_default="idle"
        ),
    )
    op.add_column("tasks", sa.Column("run_error", sa.Text(), nullable=True))


def downgrade() -> None:
    op.drop_column("tasks", "run_error")
    op.drop_column("tasks", "run_status")

    op.create_table(
        "runs",
        sa.Column("run_id", sa.dialects.postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "task_id",
            sa.dialects.postgresql.UUID(as_uuid=True),
            sa.ForeignKey("tasks.task_id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("status", sa.Text(), nullable=False, server_default="pending"),
        sa.Column("started_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("finished_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("error", sa.Text(), nullable=True),
        sa.Column("tokens_p", sa.Integer(), nullable=False, server_default="0"),
        sa.Column("tokens_c", sa.Integer(), nullable=False, server_default="0"),
    )
    op.create_table(
        "usage_events",
        sa.Column("id", sa.BigInteger(), primary_key=True, autoincrement=True),
        sa.Column("user_id", sa.dialects.postgresql.UUID(as_uuid=True), nullable=False),
        sa.Column("task_id", sa.dialects.postgresql.UUID(as_uuid=True), nullable=True),
        sa.Column("run_id", sa.dialects.postgresql.UUID(as_uuid=True), nullable=True),
        sa.Column("kind", sa.Text(), nullable=False),
        sa.Column("value", sa.Numeric(20, 8), nullable=False),
        sa.Column(
            "ts",
            sa.DateTime(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
    )
