170 lines
9.9 KiB
Python
170 lines
9.9 KiB
Python
"""init_sqlite_test
|
|
|
|
Revision ID: be562b8079e3
|
|
Revises:
|
|
Create Date: 2026-03-11 17:33:30.695730
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
from sqlalchemy import Text
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
revision: str = 'be562b8079e3'
|
|
down_revision: Union[str, None] = None
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.create_table('cases',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_no', sa.String(length=64), nullable=False),
|
|
sa.Column('title', sa.String(length=256), nullable=False),
|
|
sa.Column('victim_name', sa.String(length=128), nullable=False),
|
|
sa.Column('handler', sa.String(length=128), nullable=False),
|
|
sa.Column('status', sa.Enum('pending', 'uploading', 'analyzing', 'reviewing', 'completed', name='casestatus'), nullable=False),
|
|
sa.Column('image_count', sa.Integer(), nullable=False),
|
|
sa.Column('total_amount', sa.Numeric(precision=14, scale=2), nullable=False),
|
|
sa.Column('created_by', sa.String(length=128), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_cases_case_no'), 'cases', ['case_no'], unique=True)
|
|
op.create_table('evidence_images',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('file_path', sa.String(length=512), nullable=False),
|
|
sa.Column('thumb_path', sa.String(length=512), nullable=False),
|
|
sa.Column('source_app', sa.Enum('wechat', 'alipay', 'bank', 'digital_wallet', 'other', name='sourceapp'), nullable=False),
|
|
sa.Column('page_type', sa.Enum('bill_list', 'bill_detail', 'transfer_receipt', 'sms_notice', 'balance', 'unknown', name='pagetype'), nullable=False),
|
|
sa.Column('ocr_status', sa.Enum('pending', 'processing', 'done', 'failed', name='ocrstatus'), nullable=False),
|
|
sa.Column('file_hash', sa.String(length=128), nullable=False),
|
|
sa.Column('file_size', sa.Integer(), nullable=False),
|
|
sa.Column('uploaded_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_evidence_images_case_id'), 'evidence_images', ['case_id'], unique=False)
|
|
op.create_index(op.f('ix_evidence_images_file_hash'), 'evidence_images', ['file_hash'], unique=True)
|
|
op.create_table('export_reports',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('report_type', sa.Enum('pdf', 'excel', 'word', name='reporttype'), nullable=False),
|
|
sa.Column('file_path', sa.String(length=512), nullable=False),
|
|
sa.Column('version', sa.Integer(), nullable=False),
|
|
sa.Column('content_snapshot', postgresql.JSONB(astext_type=Text()), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_export_reports_case_id'), 'export_reports', ['case_id'], unique=False)
|
|
op.create_table('fund_flow_edges',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('source_node', sa.String(length=256), nullable=False),
|
|
sa.Column('target_node', sa.String(length=256), nullable=False),
|
|
sa.Column('source_type', sa.String(length=32), nullable=False),
|
|
sa.Column('target_type', sa.String(length=32), nullable=False),
|
|
sa.Column('amount', sa.Numeric(precision=14, scale=2), nullable=False),
|
|
sa.Column('tx_count', sa.Integer(), nullable=False),
|
|
sa.Column('earliest_time', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_fund_flow_edges_case_id'), 'fund_flow_edges', ['case_id'], unique=False)
|
|
op.create_table('transaction_clusters',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('primary_tx_id', sa.UUID(), nullable=True),
|
|
sa.Column('match_reason', sa.String(length=512), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_transaction_clusters_case_id'), 'transaction_clusters', ['case_id'], unique=False)
|
|
op.create_table('ocr_blocks',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('image_id', sa.UUID(), nullable=False),
|
|
sa.Column('content', sa.Text(), nullable=False),
|
|
sa.Column('bbox', postgresql.JSONB(astext_type=Text()), nullable=False),
|
|
sa.Column('seq_order', sa.Integer(), nullable=False),
|
|
sa.Column('confidence', sa.Float(), nullable=False),
|
|
sa.ForeignKeyConstraint(['image_id'], ['evidence_images.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_ocr_blocks_image_id'), 'ocr_blocks', ['image_id'], unique=False)
|
|
op.create_table('transaction_records',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('evidence_image_id', sa.UUID(), nullable=True),
|
|
sa.Column('cluster_id', sa.UUID(), nullable=True),
|
|
sa.Column('source_app', sa.Enum('wechat', 'alipay', 'bank', 'digital_wallet', 'other', name='sourceapp'), nullable=False),
|
|
sa.Column('trade_time', sa.DateTime(timezone=True), nullable=False),
|
|
sa.Column('amount', sa.Numeric(precision=14, scale=2), nullable=False),
|
|
sa.Column('direction', sa.Enum('in_', 'out', name='direction'), nullable=False),
|
|
sa.Column('counterparty_name', sa.String(length=256), nullable=False),
|
|
sa.Column('counterparty_account', sa.String(length=256), nullable=False),
|
|
sa.Column('self_account_tail_no', sa.String(length=32), nullable=False),
|
|
sa.Column('order_no', sa.String(length=128), nullable=False),
|
|
sa.Column('remark', sa.Text(), nullable=False),
|
|
sa.Column('confidence', sa.Float(), nullable=False),
|
|
sa.Column('is_duplicate', sa.Boolean(), nullable=False),
|
|
sa.Column('is_transit', sa.Boolean(), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.ForeignKeyConstraint(['cluster_id'], ['transaction_clusters.id'], ),
|
|
sa.ForeignKeyConstraint(['evidence_image_id'], ['evidence_images.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_transaction_records_case_id'), 'transaction_records', ['case_id'], unique=False)
|
|
op.create_index(op.f('ix_transaction_records_order_no'), 'transaction_records', ['order_no'], unique=False)
|
|
op.create_index(op.f('ix_transaction_records_trade_time'), 'transaction_records', ['trade_time'], unique=False)
|
|
op.create_table('fraud_assessments',
|
|
sa.Column('id', sa.UUID(), nullable=False),
|
|
sa.Column('case_id', sa.UUID(), nullable=False),
|
|
sa.Column('transaction_id', sa.UUID(), nullable=False),
|
|
sa.Column('confidence_level', sa.Enum('high', 'medium', 'low', name='confidencelevel'), nullable=False),
|
|
sa.Column('assessed_amount', sa.Numeric(precision=14, scale=2), nullable=False),
|
|
sa.Column('reason', sa.Text(), nullable=False),
|
|
sa.Column('exclude_reason', sa.Text(), nullable=False),
|
|
sa.Column('review_status', sa.Enum('pending', 'confirmed', 'rejected', 'needs_info', name='reviewstatus'), nullable=False),
|
|
sa.Column('review_note', sa.Text(), nullable=False),
|
|
sa.Column('reviewed_by', sa.String(length=128), nullable=False),
|
|
sa.Column('reviewed_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
|
sa.ForeignKeyConstraint(['case_id'], ['cases.id'], ),
|
|
sa.ForeignKeyConstraint(['transaction_id'], ['transaction_records.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_fraud_assessments_case_id'), 'fraud_assessments', ['case_id'], unique=False)
|
|
# ### end Alembic commands ###
|
|
|
|
|
|
def downgrade() -> None:
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.drop_index(op.f('ix_fraud_assessments_case_id'), table_name='fraud_assessments')
|
|
op.drop_table('fraud_assessments')
|
|
op.drop_index(op.f('ix_transaction_records_trade_time'), table_name='transaction_records')
|
|
op.drop_index(op.f('ix_transaction_records_order_no'), table_name='transaction_records')
|
|
op.drop_index(op.f('ix_transaction_records_case_id'), table_name='transaction_records')
|
|
op.drop_table('transaction_records')
|
|
op.drop_index(op.f('ix_ocr_blocks_image_id'), table_name='ocr_blocks')
|
|
op.drop_table('ocr_blocks')
|
|
op.drop_index(op.f('ix_transaction_clusters_case_id'), table_name='transaction_clusters')
|
|
op.drop_table('transaction_clusters')
|
|
op.drop_index(op.f('ix_fund_flow_edges_case_id'), table_name='fund_flow_edges')
|
|
op.drop_table('fund_flow_edges')
|
|
op.drop_index(op.f('ix_export_reports_case_id'), table_name='export_reports')
|
|
op.drop_table('export_reports')
|
|
op.drop_index(op.f('ix_evidence_images_file_hash'), table_name='evidence_images')
|
|
op.drop_index(op.f('ix_evidence_images_case_id'), table_name='evidence_images')
|
|
op.drop_table('evidence_images')
|
|
op.drop_index(op.f('ix_cases_case_no'), table_name='cases')
|
|
op.drop_table('cases')
|
|
# ### end Alembic commands ###
|