"""为投顾角色初始化 NL2SQL 最小只读权限。""" from __future__ import annotations import asyncio import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from sqlalchemy import text from config import database from config.database.mysql import get_session_factory ROLE = { "role_code": "advisor", "role_name": "投顾", "employee_role": "投顾", "can_query": 1, "max_rows": 1000, "daily_quota": 100, "status": "active", } TABLE_PERMISSIONS = [ ("fin_holdings", "customer_ids", "customer_id"), ("fin_transaction", "customer_ids", "customer_id"), ("fin_customer_profile", "customer_ids", "customer_id"), ("customer_relation", "customer_ids", "customer_id"), ("sys_user", "customer_ids", "id"), ("fin_product", "none", None), ("fund_performance", "none", None), ] COLUMNS = { "fin_holdings": ( "customer_id", "product_id", "shares", "cost_amount", "current_value", "profit_loss", "profit_ratio", "status", "update_time", ), "fin_transaction": ( "customer_id", "product_id", "transaction_type", "amount", "shares", "nav", "fee", "status", "create_time", ), "fin_customer_profile": ( "customer_id", "risk_level", "risk_score", "investment_experience", "annual_income_range", "total_assets", "customer_level", "update_time", ), "customer_relation": ( "customer_id", "advisor_id", "assign_time", "signed_time", "status", ), "sys_user": ( "id", "real_name", "phone", "customer_level", "status", ), "fin_product": ( "id", "product_code", "product_name", "product_type", "risk_level", "expected_return", "nav", "nav_date", "fee_rate", "term_days", "fund_manager", "status", ), "fund_performance": ( "product_id", "period", "return_rate", "annual_volatility", "max_drawdown", "sharpe", "calc_date", ), } async def main() -> None: async with get_session_factory()() as db: await db.execute( text( """ INSERT INTO nl2sql_query_role (role_code, role_name, employee_role, can_query, max_rows, daily_quota, status) VALUES (:role_code, :role_name, :employee_role, :can_query, :max_rows, :daily_quota, :status) ON DUPLICATE KEY UPDATE role_name = VALUES(role_name), can_query = VALUES(can_query), max_rows = VALUES(max_rows), daily_quota = VALUES(daily_quota), status = VALUES(status) """ ), ROLE, ) role_id = int( await db.scalar( text("SELECT id FROM nl2sql_query_role WHERE employee_role = :employee_role"), {"employee_role": ROLE["employee_role"]}, ) ) await db.execute( text("DELETE FROM nl2sql_role_table_permission WHERE role_id = :role_id"), {"role_id": role_id}, ) await db.execute( text("DELETE FROM nl2sql_role_column_permission WHERE role_id = :role_id"), {"role_id": role_id}, ) for table_name, scope_type, scope_column in TABLE_PERMISSIONS: await db.execute( text( """ INSERT INTO nl2sql_role_table_permission (role_id, table_name, permission, row_scope_type, row_scope_column, status) VALUES (:role_id, :table_name, 'SELECT', :row_scope_type, :row_scope_column, 'active') """ ), { "role_id": role_id, "table_name": table_name, "row_scope_type": scope_type, "row_scope_column": scope_column, }, ) for table_name, columns in COLUMNS.items(): for column_name in columns: access_mode = "mask" if table_name == "sys_user" and column_name == "phone" else "allow" await db.execute( text( """ INSERT INTO nl2sql_role_column_permission (role_id, table_name, column_name, access_mode, mask_type, status) VALUES (:role_id, :table_name, :column_name, :access_mode, :mask_type, 'active') """ ), { "role_id": role_id, "table_name": table_name, "column_name": column_name, "access_mode": access_mode, "mask_type": "partial" if access_mode == "mask" else None, }, ) await db.commit() print({"role_id": role_id, "tables": len(TABLE_PERMISSIONS), "columns": sum(map(len, COLUMNS.values()))}) await database.mysql.dispose() if __name__ == "__main__": asyncio.run(main())