"""GROUNDING-V2 §4a — 조사 기록 정본 테이블 (append-only).

★additive 다. 기존 테이블·칸을 하나도 안 건드린다 — 되돌리기가 drop 하나다.

Revision ID: 011_grounding_research_revision
Revises: 010_step_lock_ownership
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "011_grounding_research_revision"
down_revision: Union[str, None] = "010_step_lock_ownership"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    op.create_table(
        "grounding_research_revision",
        sa.Column("id", sa.Text(), primary_key=True),
        sa.Column("project_id", sa.Text(),
                  sa.ForeignKey("project_registry.id"), nullable=False),
        sa.Column("episode_id", sa.Text(), nullable=False),
        sa.Column("research_subject_id", sa.Text(), nullable=False),
        # ★신원 셋 — 뭉치면 같은 입력의 두 결과를 못 남긴다.
        sa.Column("research_input_hash", sa.Text(), nullable=False),
        sa.Column("revision_content_hash", sa.Text(), nullable=False),
        sa.Column("attempt_id", sa.Text(), nullable=False),
        sa.Column("era", sa.Text(), nullable=False, server_default=""),
        sa.Column("region", sa.Text(), nullable=False, server_default=""),
        sa.Column("claims_pack_version", sa.Text(), nullable=False),
        sa.Column("policy_version", sa.Text(), nullable=False),
        # ★★입력 신원 12칸의 **정본 bytes**. 합성 hash 는 역산이 안 되므로,
        #  이게 없으면 이 행이 정말 그 입력이었는지 영원히 확인할 수 없다.
        #  `research_input_hash` 도 **이 문자열에서** 계산된다 — 따로 접으면
        #  저장된 봉투와 hash 가 갈린다.
        #  ★위 era·region·pack·policy 칼럼은 **조회용**이다(admission 이 판별에
        #  쓴다). 정본은 이 칸 하나다.
        sa.Column("research_input_json", sa.Text(), nullable=False),
        sa.Column("delta", sa.Text(), nullable=False),
        sa.Column("delta_reason", sa.Text(), nullable=False, server_default=""),
        sa.Column("status", sa.Text(), nullable=False),
        sa.Column("claims_json", sa.Text(), nullable=False, server_default="[]"),
        sa.Column("gaps_json", sa.Text(), nullable=False, server_default="[]"),
        sa.Column("audit_json", sa.Text(), nullable=False, server_default="{}"),
        # ★필수다 — 빈 provenance 행을 만들지 않는다.
        sa.Column("provenance_json", sa.Text(), nullable=False),
        sa.Column("created_at", sa.Text(), nullable=False),
        sa.UniqueConstraint("project_id", "episode_id", "research_subject_id",
                            "research_input_hash", "attempt_id",
                            name="uq_grounding_research_revision_attempt"),
    )
    # ★admission 이 「이 에피소드에서 뭘 이미 샀나」를 매번 묻는다.
    op.create_index("ix_grounding_research_revision_scope",
                    "grounding_research_revision",
                    ["project_id", "episode_id", "research_subject_id"])


def downgrade() -> None:
    op.drop_index("ix_grounding_research_revision_scope",
                  table_name="grounding_research_revision")
    op.drop_table("grounding_research_revision")
