"""sqlite 测试 DDL 单一事实源(B8 · B4 评审 P3-12 收敛 / B5 评审 P3-4 时区)。 以 VARCHAR/TEXT/INTEGER/REAL 近似 MySQL 的 ENUM/SMALLINT/JSON/DECIMAL, 枚举防线不在测试 DB 层(由 service 白名单保证,见 test_profile_l3 口径注释)。 时间默认值统一 `(datetime('now','localtime'))`:sqlite CURRENT_TIMESTAMP 为 UTC, 本地 23:00~24:00 跑测试时与 MySQL localtime 口径错位一个日界(B5 评审 P3-4)。 列集为各测试所需列的并集;新表/新列只改此处,禁止再回测试文件手写。 """ from sqlalchemy import create_engine, text from sqlalchemy.pool import StaticPool _TS = "TIMESTAMP DEFAULT (datetime('now','localtime'))" SQLITE_TABLES: dict[str, str] = { # ---- Core 模拟库(只读侧) ---- "core_customer": """ CREATE TABLE core_customer ( customer_id VARCHAR(64) PRIMARY KEY, display_name VARCHAR(128), age INTEGER, occupation VARCHAR(64), open_date DATE, is_active TINYINT DEFAULT 1) """, "core_customer_risk": """ CREATE TABLE core_customer_risk ( customer_id VARCHAR(64), risk_code VARCHAR(8), evaluated_at TIMESTAMP) """, "core_customer_advisor": """ CREATE TABLE core_customer_advisor ( advisor_id VARCHAR(64), customer_id VARCHAR(64), rel_status VARCHAR(16)) """, "core_product": """ CREATE TABLE core_product ( product_id VARCHAR(64) PRIMARY KEY, product_name VARCHAR(128), min_risk_code VARCHAR(8), product_type VARCHAR(32)) """, "core_holding": """ CREATE TABLE core_holding ( customer_id VARCHAR(64), product_id VARCHAR(64), market_value DECIMAL, quantity DECIMAL) """, "core_trade": """ CREATE TABLE core_trade ( trade_id VARCHAR(64) PRIMARY KEY, customer_id VARCHAR(64), product_id VARCHAR(64), trade_type VARCHAR(16), amount DECIMAL, trade_status VARCHAR(16), traded_at TIMESTAMP) """, # ---- agent 库 ---- "audit_log": f""" CREATE TABLE audit_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, trace_id VARCHAR(64), event_type VARCHAR(64), agent_type VARCHAR(16), actor_id VARCHAR(64), customer_id VARCHAR(64), rule_id VARCHAR(64), input_summary TEXT, decision VARCHAR(64), risk_score INTEGER, handler_id VARCHAR(64), handler_result VARCHAR(64), handler_comment VARCHAR(512), created_at {_TS}) """, "input_guard_log": f""" CREATE TABLE input_guard_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, trace_id VARCHAR(64), session_id VARCHAR(64), agent_type VARCHAR(16), actor_id VARCHAR(64), guard_type VARCHAR(24), raw_excerpt VARCHAR(1024), action VARCHAR(16), created_at {_TS}) """, "agent_session": f""" CREATE TABLE agent_session ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id VARCHAR(64) UNIQUE, trace_id VARCHAR(64), agent_type VARCHAR(16), actor_id VARCHAR(64), actor_role VARCHAR(32), customer_id VARCHAR(64), advisor_id VARCHAR(64), title VARCHAR(256), status VARCHAR(16) DEFAULT 'active', created_at {_TS}, closed_at TIMESTAMP) """, "agent_message": f""" CREATE TABLE agent_message ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id VARCHAR(64), trace_id VARCHAR(64), seq_no INTEGER, role VARCHAR(16), content TEXT, has_disclaimer TINYINT DEFAULT 0, token_est INTEGER, created_at {_TS}) """, "agent_tool_call": f""" CREATE TABLE agent_tool_call ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id VARCHAR(64), trace_id VARCHAR(64), message_id INTEGER, tool_name VARCHAR(128), tool_input TEXT, tool_output TEXT, status VARCHAR(16), error_code VARCHAR(64), latency_ms INTEGER, created_at {_TS}) """, "risk_alert": f""" CREATE TABLE risk_alert ( alert_id VARCHAR(64) PRIMARY KEY, trace_id VARCHAR(64), customer_id VARCHAR(64), trade_id VARCHAR(64), alert_type VARCHAR(16), triggered_rules TEXT, risk_score INTEGER, status VARCHAR(24) DEFAULT 'pending_review', payload TEXT, handler_id VARCHAR(64), handler_result VARCHAR(64), handler_comment VARCHAR(512), created_at {_TS}, handled_at TIMESTAMP) """, "risk_suitability_log": f""" CREATE TABLE risk_suitability_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, trace_id VARCHAR(64), customer_id VARCHAR(64), product_id VARCHAR(64), customer_risk_level VARCHAR(8), product_risk_level VARCHAR(8), is_matched TINYINT, is_blocked TINYINT, block_reason VARCHAR(512), request_ref VARCHAR(64), profile_l1_version VARCHAR(32), created_at {_TS}) """, "customer_profile_l3": f""" CREATE TABLE customer_profile_l3 ( customer_id VARCHAR(64) PRIMARY KEY, monitor_tier VARCHAR(16) NOT NULL, risk_score INTEGER, score_dimensions TEXT, monitor_tags TEXT, last_alert_id VARCHAR(64), computed_at TIMESTAMP NOT NULL, updated_at {_TS}) """, "risk_aml_list": f""" CREATE TABLE risk_aml_list ( id INTEGER PRIMARY KEY AUTOINCREMENT, list_id VARCHAR(64), list_type VARCHAR(16), full_name VARCHAR(128), id_no VARCHAR(32), bank_card_no VARCHAR(32), match_threshold REAL, source VARCHAR(64), list_version VARCHAR(16), effective_date DATE, is_active TINYINT DEFAULT 1, created_at {_TS}) """, } def create_sqlite_engine(): """内存 sqlite + 全部表(StaticPool 单连接共享,同现有测试模式)。""" engine = create_engine( "sqlite://", poolclass=StaticPool, connect_args={"check_same_thread": False} ) with engine.begin() as conn: for ddl in SQLITE_TABLES.values(): conn.execute(text(ddl)) return engine