"""phase7 autonomy core: approval 확장 + automation/approval 테이블 Revision ID: p7a1b2c3d4e5 Revises: 3e46d0f29340 Create Date: 2026-06-14 00:00:00.000000 """ from typing import Sequence, Union import sqlalchemy as sa import sqlmodel # SQLModel AutoString 등 컬럼 타입 참조 from alembic import op # revision identifiers, used by Alembic. revision: str = "p7a1b2c3d4e5" down_revision: Union[str, Sequence[str], None] = "3e46d0f29340" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # 1) automation_rule 먼저(approval.rule_id 가 참조) op.create_table( "automation_rule", sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("cat", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("trigger", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("cond", sqlmodel.sql.sqltypes.AutoString(), nullable=True), sa.Column("action", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("on", sa.Boolean(), nullable=False), sa.Column("last", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("runs", sa.Integer(), nullable=False), sa.Column("fresh", sa.Boolean(), nullable=False), sa.Column("source", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) # 2) approval 확장(기존 행 보존; 기본값으로 채움) — SQLite batch 모드 with op.batch_alter_table("approval") as b: b.add_column( sa.Column( "status", sqlmodel.sql.sqltypes.AutoString(), nullable=False, server_default="pending", ) ) b.add_column( sa.Column( "source", sqlmodel.sql.sqltypes.AutoString(), nullable=False, server_default="system", ) ) b.add_column(sa.Column("rule_id", sqlmodel.sql.sqltypes.AutoString(), nullable=True)) b.add_column(sa.Column("created_at", sa.DateTime(), nullable=True)) b.add_column(sa.Column("executed_at", sa.DateTime(), nullable=True)) b.add_column(sa.Column("undone_at", sa.DateTime(), nullable=True)) # 3) 나머지 신규 테이블 op.create_table( "autonomy_setting", sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("level", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("updated_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_table( "approval_log", sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("time", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("text", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("approval_id", sqlmodel.sql.sqltypes.AutoString(), nullable=True), sa.Column("sort_order", sa.Integer(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_table( "automation_suggestion", sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("pattern", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("offer_name", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("offer_cat", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("offer_trigger", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("offer_cond", sqlmodel.sql.sqltypes.AutoString(), nullable=True), sa.Column("offer_action", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("status", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_table( "automation_run_log", sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("time", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("rule_id", sqlmodel.sql.sqltypes.AutoString(), nullable=True), sa.Column("rule", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("text", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("undone", sa.Boolean(), nullable=False), sa.Column("sort_order", sa.Integer(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_table( "automation_stats", sa.Column("id", sa.Integer(), nullable=False), sa.Column("active", sa.Integer(), nullable=False), sa.Column("runs_week", sa.Integer(), nullable=False), sa.Column("saved", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.PrimaryKeyConstraint("id"), ) def downgrade() -> None: for t in ( "automation_stats", "automation_run_log", "automation_suggestion", "approval_log", "autonomy_setting", ): op.drop_table(t) with op.batch_alter_table("approval") as b: for c in ("undone_at", "executed_at", "created_at", "rule_id", "source", "status"): b.drop_column(c) op.drop_table("automation_rule")