"""公共常量定义(单一事实来源,与《投顾工作台开发文档/common_const.md》v1.2 对齐)。 用途:投顾工作台(B 端)与投顾Agent(AI 组件)统一引用,避免枚举/字符串硬编码不一致。 规范:业务代码禁止写死字符串字面量,一律 `from common_const import ...`。 说明:本文件只存放「常量字符串 / 枚举 / 模板文本」;业务规则(如适当性匹配逻辑) 写在业务代码中(见 service/advisor/suitability.py),不在此处写业务逻辑。 """ from __future__ import annotations # --------------------------------------------------------------------------- # §1 客户-投顾关系状态(customer_relation.status) # --------------------------------------------------------------------------- CUSTOMER_REL_STATUS_UNSIGNED = "已分配" # 未签约,仅分配,未开通投顾正式服务 CUSTOMER_REL_STATUS_SIGNED = "已签约" # 已签约,可下发推荐/调仓方案给客户 CUSTOMER_REL_STATUS_CLOSED = "已结束" # 服务已终止 # --------------------------------------------------------------------------- # §2 草稿状态(advisor_draft.status,Agent 侧;不可物理删除,仅状态流转) # --------------------------------------------------------------------------- DRAFT_STATUS_DRAFT = "draft" DRAFT_STATUS_DISCARDED = "discarded" # 建议报告本地状态(advisor_report.send_status,工作台本地;sent 为工作台独有,Agent 不感知) REPORT_SEND_STATUS_DRAFT = "draft" REPORT_SEND_STATUS_SENT = "sent" REPORT_SEND_STATUS_DISCARDED = "discarded" # --------------------------------------------------------------------------- # §3 记忆单元类型(memory_unit.info_type;工作台只读,不直接读写该表) # --------------------------------------------------------------------------- MEMORY_INFO_TYPE_FACT = "FACT" # 客观事实,作为业务硬规则依据 MEMORY_INFO_TYPE_OPINION = "OPINION" # 主观观点,仅做排序参考,不能绕过适当性 # --------------------------------------------------------------------------- # §4 Agent 意图枚举(intent) # --------------------------------------------------------------------------- AGENT_INTENT_RECOMMEND = "recommend" # 基金推荐 AGENT_INTENT_REBALANCE = "rebalance" # 持仓诊断 & 调仓再平衡 AGENT_INTENT_FUND_ANALYSIS = "fund_analysis" # 基金深度分析 AGENT_INTENT_DIALOGUE_SCRIPT = "dialogue-script" # 生成沟通话术 # --------------------------------------------------------------------------- # §5 沟通话术场景(generate-talk-script 入参 scene_type) # --------------------------------------------------------------------------- TALK_SCENE_RISK_BLOCK_ORDER = "risk_block_order" # 订单被风控拦截 TALK_SCENE_MARKET_FLUCTUATION = "market_fluctuation" # 市场波动安抚 TALK_SCENE_PORTFOLIO_DIVERGENCE = "portfolio_divergence" # 组合大幅偏离基准 TALK_SCENE_CUSTOMER_COMPLAINT = "customer_complaint" # 客户投诉 # --------------------------------------------------------------------------- # §6 Agent 业务错误码(Agent 自有码域,成功码=0;工作台 service 层须映射,不得透传) # --------------------------------------------------------------------------- ERR_CODE_OK = 0 ERR_CODE_FORBIDDEN_CUSTOMER = 40001 # customer_id 不属于当前投顾,越权访问 ERR_CODE_SUITABILITY_INVALID = 40020 # 适当性校验不通过 ERR_CODE_NOT_SIGNED_REBALANCE = 40030 # 客户未签约,禁止生成 rebalance 草稿 ERR_CODE_DRAFT_NOT_FOUND = 40401 # draft_id 不存在或已废弃 ERR_CODE_LLM_ERROR = 50001 # Agent 内部 LLM 调用异常 ERR_CODE_GRAPH_ERROR = 50002 # GraphRAG 查询异常,触发降级 # Agent 错误码 → 默认提示文案(业务判断必须用 code,禁止依赖 message 文案) AGENT_ERR_MESSAGE = { ERR_CODE_FORBIDDEN_CUSTOMER: "无权操作该客户数据", ERR_CODE_SUITABILITY_INVALID: "方案适当性校验不通过,包含超出客户风险等级的产品", ERR_CODE_NOT_SIGNED_REBALANCE: "客户尚未签约,禁止生成调仓草稿", ERR_CODE_DRAFT_NOT_FOUND: "草稿不存在或者已废弃", ERR_CODE_LLM_ERROR: "AI服务调用异常,请稍后重试", ERR_CODE_GRAPH_ERROR: "图谱查询异常,已降级返回部分结果", } # --------------------------------------------------------------------------- # §7 风险等级(存储编码统一 C1-C5 / R1-R5;中文仅展示层,不入库) # --------------------------------------------------------------------------- C_RISK_C1, C_RISK_C2, C_RISK_C3, C_RISK_C4, C_RISK_C5 = "C1", "C2", "C3", "C4", "C5" PROD_RISK_R1, PROD_RISK_R2, PROD_RISK_R3, PROD_RISK_R4, PROD_RISK_R5 = "R1", "R2", "R3", "R4", "R5" # --------------------------------------------------------------------------- # §8 系统配置 sys_config key(调仓/客户经营参数,代码不写死 key) # --------------------------------------------------------------------------- SYS_KEY_REBALANCE_DEVIATION_THRESHOLD = "rebalance.deviation.threshold" # 组合再平衡偏离阈值(全局兜底) SYS_KEY_HIGH_NET_ASSET_THRESHOLD = "customer.high_net.asset.threshold" # 高净值客户资产门槛 SYS_KEY_RISK_QUESTIONNAIRE_EXPIRE_DAY = "risk.questionnaire.expire.day" # 风险测评过期天数 SYS_KEY_LARGE_FLOW_THRESHOLD = "customer.large_flow.threshold" # 大额申赎阈值 # --------------------------------------------------------------------------- # §9 事件总线 Pub/Sub 事件名(双写 event_log + Redis Pub/Sub,消费以 event_id 幂等) # --------------------------------------------------------------------------- EVENT_REBALANCE_DRAFT_CREATED = "event:rebalance_draft_created" EVENT_PROFILE_UPDATE = "event:profile_update" # 工作台消费的投顾域事件(仅前两者;work_order_change/risk_alert 属其它域) ADVISOR_EVENTS = (EVENT_REBALANCE_DRAFT_CREATED, EVENT_PROFILE_UPDATE) # 事件消费状态(event_log.status) EVENT_STATUS_PENDING = "pending" EVENT_STATUS_CONSUMED = "consumed" EVENT_STATUS_FAILED = "failed" # --------------------------------------------------------------------------- # §10 固定文本模板 # --------------------------------------------------------------------------- # 10.1 报告强制免责声明(完整性判定:正文必须「逐字包含」完整原文,精确匹配) DISCLAIMER_TEXT = ( "【免责声明】本报告由AI辅助生成,仅供持牌投顾内部参考,不构成任何投资建议。" "基金有风险,投资需谨慎。所有投资决策请结合自身风险承受能力审慎判断。" ) # 10.2 SSE 事件类型(Agent 流式;工作台同步接口不涉及,保留枚举以对齐契约) SSE_EVENT_TYPE_TEXT = "text" SSE_EVENT_TYPE_META = "meta" SSE_EVENT_TYPE_DONE = "done" SSE_EVENT_TYPE_ERROR = "error" # --------------------------------------------------------------------------- # §11 定时任务 cron # --------------------------------------------------------------------------- CRON_MEMORY_MAINTENANCE = "0 2 * * 1" # Agent 侧每周记忆维护(工作台不调度) CRON_PORTFOLIO_REBALANCE = "0 1 * * *" # 工作台每日组合再平衡(遍历 signed 客户) CRON_FUND_NAV_UPDATE = "30 1 * * *" # 基金净值更新 # --------------------------------------------------------------------------- # §12 审计日志 action(audit_log.action) # --------------------------------------------------------------------------- AUDIT_AGENT_CHAT_CALL = "agent_chat_call" # 调用投顾Agent对话 AUDIT_DRAFT_SAVE = "draft_save" # 草稿保存 AUDIT_DRAFT_DISCARD = "draft_discard" # 草稿废弃 AUDIT_CUSTOMER_SIGN = "customer_sign" # 客户签约 AUDIT_VIEW_SENSITIVE = "view_sensitive" # 投顾查看脱敏字段完整值(留痕) # --------------------------------------------------------------------------- # §13 投顾角色(sys_user.employee_role) # --------------------------------------------------------------------------- EMPLOYEE_ROLE_ADVISOR = "投顾" # 工作台唯一业务角色;「理财顾问」为历史表述,不参与鉴权 # --------------------------------------------------------------------------- # §14 站内信消息类型(sys_message.msg_type) # --------------------------------------------------------------------------- MSG_TYPE_RECOMMEND = "推荐" MSG_TYPE_REBALANCE = "调仓" MSG_TYPE_RISK = "风控" MSG_TYPE_SIGN = "签约" MSG_TYPE_SYSTEM = "系统" # 草稿 intent → 站内信 msg_type 映射(recommend→推荐 / rebalance→调仓) INTENT_TO_MSG_TYPE = { AGENT_INTENT_RECOMMEND: MSG_TYPE_RECOMMEND, AGENT_INTENT_REBALANCE: MSG_TYPE_REBALANCE, } # --------------------------------------------------------------------------- # 以下为「工作台本地」常量:DDL COMMENT / PRD 定义,common_const.md 未集中列出。 # 假设:按 sql/schema.sql 与 PRD 语义落地;后续若统一进 common_const.md 再收敛。 # --------------------------------------------------------------------------- # 待办类型(advisor_todo.todo_type,见 schema.sql 表 27) TODO_TYPE_NEW_REBALANCE_DRAFT = "new_rebalance_draft" # 新增调仓建议 TODO_TYPE_VISIT_DUE = "visit_due" # 回访到期 TODO_TYPE_RISK_EXPIRE = "risk_expire" # 风险测评过期 TODO_TYPE_LARGE_FLOW = "large_flow" # 客户大额申赎 TODO_TYPE_DRAWDOWN = "drawdown" # 持仓大幅回撤 # 待办来源(advisor_todo.source) TODO_SOURCE_AGENT_EVENT = "agent_event" # 事件消费生成 TODO_SOURCE_LOCAL_TIMER = "local_timer" # 本地定时任务生成 TODO_SOURCE_LOCAL_CALC = "local_calc" # 本地计算生成 # 待办优先级(advisor_todo.priority) TODO_PRIORITY_HIGH = "高" TODO_PRIORITY_NORMAL = "普通" TODO_PRIORITY_LOW = "低" # 待办状态(advisor_todo.status;单向流转 待处理→处理中→已完成) TODO_STATUS_PENDING = "待处理" TODO_STATUS_PROCESSING = "处理中" TODO_STATUS_DONE = "已完成" # 回访方式(advisor_visit_record.visit_type,见 PRD §4.4.2) VISIT_TYPE_PHONE = "电话" VISIT_TYPE_WECHAT = "企微" VISIT_TYPE_SMS = "短信" VISIT_TYPE_ONSITE = "现场" # 关系流转动作(工作台写入 customer_relation.status 的动作标识) RELATION_ACTION_SIGN = "sign" # 签约 RELATION_ACTION_CLOSE = "close" # 结束服务