148 lines
5.1 KiB
Python
148 lines
5.1 KiB
Python
"""为投顾角色初始化 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())
|