You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.3 KiB
Python
151 lines
6.3 KiB
Python
"""phase13 connectors: connector_account/sync_state/external_link/oauth_state/log + finance_tx/health_sample/chat_message
|
|
|
|
Revision ID: p13a1b2c3d4e5
|
|
Revises: p12f6a7b8c9d0
|
|
Create Date: 2026-06-15 06:00:00.000000
|
|
|
|
"""
|
|
|
|
from typing import Sequence, Union
|
|
|
|
import sqlalchemy as sa
|
|
import sqlmodel
|
|
from alembic import op
|
|
|
|
revision: str = "p13a1b2c3d4e5"
|
|
down_revision: Union[str, Sequence[str], None] = "p12f6a7b8c9d0"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
S = sqlmodel.sql.sqltypes.AutoString
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.create_table(
|
|
"connector_account",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("user_id", S(), nullable=False),
|
|
sa.Column("domain", S(), nullable=False),
|
|
sa.Column("mode", S(), nullable=False),
|
|
sa.Column("provider", S(), nullable=False),
|
|
sa.Column("external_account_id", S(), nullable=False),
|
|
sa.Column("name", S(), nullable=False),
|
|
sa.Column("kind", S(), nullable=False),
|
|
sa.Column("tone", S(), nullable=False),
|
|
sa.Column("state", S(), nullable=False),
|
|
sa.Column("last_synced_at", sa.DateTime(), nullable=True),
|
|
sa.Column("last_label", S(), nullable=False),
|
|
sa.Column("token_enc", S(), nullable=False),
|
|
sa.Column("scopes", S(), nullable=False),
|
|
sa.Column("error_detail", S(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.Column("updated_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["user_id"], ["person.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"connector_sync_state",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("cursor", S(), nullable=False),
|
|
sa.Column("page_token", S(), nullable=False),
|
|
sa.Column("last_full_sync_at", sa.DateTime(), nullable=True),
|
|
sa.Column("last_delta_sync_at", sa.DateTime(), nullable=True),
|
|
sa.Column("items_seen", sa.Integer(), nullable=False),
|
|
sa.Column("items_upserted", sa.Integer(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"external_link",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("external_id", S(), nullable=False),
|
|
sa.Column("entity_type", S(), nullable=False),
|
|
sa.Column("entity_id", S(), nullable=False),
|
|
sa.Column("etag", S(), nullable=False),
|
|
sa.Column("external_updated_at", sa.DateTime(), nullable=True),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index("ix_external_link_account_id", "external_link", ["account_id"])
|
|
op.create_index("ix_external_link_external_id", "external_link", ["external_id"])
|
|
# 멱등성 핵심: (account_id, external_id) 복합 UNIQUE
|
|
op.create_index(
|
|
"ux_extlink_acct_ext", "external_link", ["account_id", "external_id"], unique=True
|
|
)
|
|
op.create_table(
|
|
"oauth_state",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("domain", S(), nullable=False),
|
|
sa.Column("provider", S(), nullable=False),
|
|
sa.Column("code_verifier", S(), nullable=False),
|
|
sa.Column("redirect_after", S(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"connector_account_log",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("action", S(), nullable=False),
|
|
sa.Column("detail", S(), nullable=False),
|
|
sa.Column("items", sa.Integer(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"finance_tx",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("date", S(), nullable=False),
|
|
sa.Column("merchant", S(), nullable=False),
|
|
sa.Column("amount", sa.Integer(), nullable=False),
|
|
sa.Column("category", S(), nullable=False),
|
|
sa.Column("category_id", S(), nullable=False),
|
|
sa.Column("account_label", S(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"health_sample",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("kind", S(), nullable=False),
|
|
sa.Column("value", sa.Float(), nullable=False),
|
|
sa.Column("unit", S(), nullable=False),
|
|
sa.Column("day", S(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_table(
|
|
"chat_message",
|
|
sa.Column("id", S(), nullable=False),
|
|
sa.Column("account_id", S(), nullable=False),
|
|
sa.Column("sender", S(), nullable=False),
|
|
sa.Column("text", S(), nullable=False),
|
|
sa.Column("channel", S(), nullable=False),
|
|
sa.Column("at", S(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.ForeignKeyConstraint(["account_id"], ["connector_account.id"]),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table("chat_message")
|
|
op.drop_table("health_sample")
|
|
op.drop_table("finance_tx")
|
|
op.drop_table("connector_account_log")
|
|
op.drop_table("oauth_state")
|
|
op.drop_index("ux_extlink_acct_ext", table_name="external_link")
|
|
op.drop_index("ix_external_link_external_id", table_name="external_link")
|
|
op.drop_index("ix_external_link_account_id", table_name="external_link")
|
|
op.drop_table("external_link")
|
|
op.drop_table("connector_sync_state")
|
|
op.drop_table("connector_account")
|