From ecd0627396407daf8087a4b55d0dab08cdd948f6 Mon Sep 17 00:00:00 2001 From: zhangshy <994452054@qq.com> Date: Fri, 11 Sep 2026 10:35:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AD=97=E6=AE=B5=E5=B9=B6=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=E9=A3=8E=E6=8E=A7=E9=85=8D=E7=BD=AE=E6=B8=85=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 15 ++- app/repository/risk_repository.py | 2 - config/risk.env.example | 28 ++++++ .../风控业务演示文档/12-日报通知与邮件规则.md | 3 +- .../风控业务演示文档/19-风控模块配置项清单.md | 93 +++++++++++++++++++ docs/风控业务演示文档/README.md | 2 + tests/unit/repository/test_risk_repository.py | 2 + 7 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 config/risk.env.example create mode 100644 docs/风控业务演示文档/19-风控模块配置项清单.md diff --git a/.env.example b/.env.example index ebc4c09..9760a4e 100644 --- a/.env.example +++ b/.env.example @@ -11,7 +11,6 @@ JWT_PUBLIC_KEY_PATH=config/jwt/jwt-public.pem JWT_CLOCK_SKEW_SECONDS=30 MYSQL_DSN=mysql+asyncmy://jr_app:change-me@127.0.0.1:3306/jr_agent -MYSQL_DSN=mysql+asyncmy://root:123456@127.0.0.1:3306/jr_agent MYSQL_POOL_SIZE=5 MYSQL_MAX_OVERFLOW=10 MYSQL_TX_ISOLATION=READ COMMITTED @@ -36,6 +35,7 @@ NEO4J_PASSWORD= MODEL_ROUTER_CONFIG_REF=local MODEL_DEFAULT_ENDPOINT= MODEL_FALLBACK_ENDPOINT= +DEEPSEEK_API_KEY= SSE_HEARTBEAT_SECONDS=15 SSE_MAX_CONNECTION_SECONDS=300 @@ -50,6 +50,19 @@ RISK_SCAN_RUN_IMMEDIATELY=false RISK_SCAN_RETRY_LIMIT=2 RISK_SCAN_POLL_SECONDS=30 +RISK_EVIDENCE_DIR=storage/risk_evidence +RISK_EVIDENCE_MAX_FILE_SIZE_MB=10 + +RISK_DAILY_REPORT_MAIL_ENABLED=false +RISK_DAILY_REPORT_MAIL_DRY_RUN=true +RISK_SMTP_HOST= +RISK_SMTP_PORT=465 +RISK_SMTP_USERNAME= +RISK_SMTP_PASSWORD= +RISK_SMTP_SENDER= +RISK_SMTP_USE_SSL=true +RISK_SMTP_TIMEOUT_SECONDS=30 + # 限流:按“用户 + 方法 + 路由”在窗口内计数,超限返回 429 RATE_LIMITED + Retry-After。 # 默认 600/60s(10 QPS)是为本机验收与集成测试留足余量的宽松值;生产按真实容量收紧。 # Redis 不可用时自动降级为放行(限流是保护措施,不能因后端故障拒绝正常请求)。 diff --git a/app/repository/risk_repository.py b/app/repository/risk_repository.py index 3dea7b7..7fd91dd 100644 --- a/app/repository/risk_repository.py +++ b/app/repository/risk_repository.py @@ -927,8 +927,6 @@ class RiskRepository: "send_status": notification.send_status, "receiver_email": notification.receiver_email, "send_time": notification.sent_at, - "read_time": notification.read_at, - "ack_time": notification.acknowledged_at, } @staticmethod diff --git a/config/risk.env.example b/config/risk.env.example new file mode 100644 index 0000000..c694ebc --- /dev/null +++ b/config/risk.env.example @@ -0,0 +1,28 @@ +# 风控模块专用环境变量示例 +# 实际值请写入主项目 .env 或部署环境,不要提交真实密钥 + +# 模型 +DEEPSEEK_API_KEY= + +# 定时规则扫描 +RISK_SCAN_SCHEDULE_ENABLED=false +RISK_SCAN_INTERVAL_MINUTES=5 +RISK_SCAN_RUN_IMMEDIATELY=false +RISK_SCAN_RETRY_LIMIT=2 +RISK_SCAN_POLL_SECONDS=30 + +# 证据归档 +RISK_EVIDENCE_DIR=storage/risk_evidence +RISK_EVIDENCE_MAX_FILE_SIZE_MB=10 + +# 日报邮件 +RISK_DAILY_REPORT_MAIL_ENABLED=false +RISK_DAILY_REPORT_MAIL_DRY_RUN=true +RISK_SMTP_HOST= +RISK_SMTP_PORT=465 +RISK_SMTP_USERNAME= +RISK_SMTP_PASSWORD= +RISK_SMTP_SENDER= +RISK_SMTP_USE_SSL=true +RISK_SMTP_TIMEOUT_SECONDS=30 + diff --git a/docs/风控业务演示文档/12-日报通知与邮件规则.md b/docs/风控业务演示文档/12-日报通知与邮件规则.md index 867b36a..b2eec4a 100644 --- a/docs/风控业务演示文档/12-日报通知与邮件规则.md +++ b/docs/风控业务演示文档/12-日报通知与邮件规则.md @@ -41,6 +41,8 @@ - 通知内容包含预警编号,便于定位原始预警。 - 通知发送失败不能回滚已经生成的预警。 - 通知查询按主项目分页和权限规则执行。 +- 数据库保留 `read_at`、`acknowledged_at` 基线字段,但当前未实现写入逻辑。 +- 通知接口和前端不返回或展示阅读时间、确认时间。 ## 邮件开关 @@ -68,4 +70,3 @@ - 收件人去重并校验格式。 - 单次最多 10 个收件人。 - 发送结果不额外建立业务留痕,由业务人员自行检查邮箱。 - diff --git a/docs/风控业务演示文档/19-风控模块配置项清单.md b/docs/风控业务演示文档/19-风控模块配置项清单.md new file mode 100644 index 0000000..4a07738 --- /dev/null +++ b/docs/风控业务演示文档/19-风控模块配置项清单.md @@ -0,0 +1,93 @@ +# 风控模块配置项清单 + +## 文档功能 + +本文档用于单独列出风控模块接入主项目时需要配置的环境变量,区分风控专用配置和主项目公共依赖,供合并部署、联调和故障排查使用。 + +## 风控专用配置 + +### 奶龙风控智能助手 + +| 配置项 | 默认值 | 说明 | +|---|---|---| +| `DEEPSEEK_API_KEY` | 空 | 模型端点 `env:DEEPSEEK_API_KEY` 引用的真实密钥 | + +模型地址、模型名称和超时时间由 `model_endpoint_config` 配置,不直接放 `.env`。 + +### 定时规则扫描 + +| 配置项 | 默认值 | 说明 | +|---|---:|---| +| `RISK_SCAN_SCHEDULE_ENABLED` | `false` | 是否开启定时扫描 | +| `RISK_SCAN_INTERVAL_MINUTES` | `5` | 扫描间隔,单位分钟 | +| `RISK_SCAN_RUN_IMMEDIATELY` | `false` | Worker 启动后是否立即执行 | +| `RISK_SCAN_RETRY_LIMIT` | `2` | 单轮失败后的重试次数 | +| `RISK_SCAN_POLL_SECONDS` | `30` | Worker 轮询配置和到期时间的间隔 | + +### 证据归档 + +| 配置项 | 默认值 | 说明 | +|---|---:|---| +| `RISK_EVIDENCE_DIR` | `storage/risk_evidence` | 证据文件归档根目录 | +| `RISK_EVIDENCE_MAX_FILE_SIZE_MB` | `10` | 单个证据文件最大大小,单位 MB | + +### 日报邮件 + +| 配置项 | 默认值 | 说明 | +|---|---:|---| +| `RISK_DAILY_REPORT_MAIL_ENABLED` | `false` | 是否允许调用真实 SMTP | +| `RISK_DAILY_REPORT_MAIL_DRY_RUN` | `true` | 为真时只返回 dry-run,不发送邮件 | +| `RISK_SMTP_HOST` | 空 | SMTP 主机 | +| `RISK_SMTP_PORT` | `465` | SMTP 端口 | +| `RISK_SMTP_USERNAME` | 空 | SMTP 用户名 | +| `RISK_SMTP_PASSWORD` | 空 | SMTP 密码或授权码 | +| `RISK_SMTP_SENDER` | 空 | 发件人邮箱 | +| `RISK_SMTP_USE_SSL` | `true` | 是否使用 SSL | +| `RISK_SMTP_TIMEOUT_SECONDS` | `30` | SMTP 超时时间 | + +## 主项目公共依赖 + +以下配置通常由主项目统一维护,风控模块只依赖,不重复定义: + +| 配置项 | 用途 | +|---|---| +| `MYSQL_DSN` | 风控业务数据和 Agent Run 持久化 | +| `REDIS_URL` | 限流、缓存和降级 | +| `JWT_ISSUER` | JWT 签发方 | +| `JWT_AUDIENCE` | JWT 受众 | +| `JWT_PRIVATE_KEY_PATH` | 本地测试 JWT 私钥 | +| `JWT_PUBLIC_KEY_PATH` | JWT 公钥 | +| `WORKER_POLL_SECONDS` | Agent Worker 轮询间隔 | +| `WORKER_LEASE_SECONDS` | Agent Run 租约 | +| `WORKER_RETRY_LIMIT` | Agent Run 重试次数 | +| `SSE_HEARTBEAT_SECONDS` | Agent SSE 心跳 | +| `SSE_CHUNK_CHARACTERS` | Agent SSE 分片大小 | + +## 可选依赖 + +| 配置项 | 缺失影响 | +|---|---| +| `MILVUS_URI` | 语义记忆关闭,结构化风控功能继续可用 | +| `MILVUS_TOKEN` | 无法连接需要认证的 Milvus | +| `MILVUS_COLLECTION` | 使用默认集合名称 | +| `NEO4J_URI` | 关系图谱投影关闭 | +| `NEO4J_USERNAME` | 无法连接需要认证的 Neo4j | +| `NEO4J_PASSWORD` | 无法连接需要认证的 Neo4j | +| `MESSAGE_BROKER_URL` | 当前使用数据库 Outbox 轮询,不影响风控主流程 | + +## 配置原则 + +- 启动和部署级开关放 `.env`。 +- Agent 工具白名单、意图和模型端点等运行配置继续使用配置发布表。 +- 真实密钥只能通过环境变量或受控密钥系统注入。 +- `.env` 不得提交到 Git。 +- `private_frontend` 不使用独立配置,继续读取主项目 API 地址和 Token。 + +## 使用建议 + +- 联调初期保持 `RISK_SCAN_SCHEDULE_ENABLED=false`。 +- 确认扫描规则和演示数据后,再按需改为 `true`。 +- 邮件先保持 `RISK_DAILY_REPORT_MAIL_DRY_RUN=true`。 +- 正式发送前配置 SMTP,并将 `RISK_DAILY_REPORT_MAIL_ENABLED=true`。 +- 证据目录应挂载到持久化存储,不能只保存在临时容器目录。 + diff --git a/docs/风控业务演示文档/README.md b/docs/风控业务演示文档/README.md index 57663ae..9bbab4b 100644 --- a/docs/风控业务演示文档/README.md +++ b/docs/风控业务演示文档/README.md @@ -39,6 +39,7 @@ | 16 | 已知限制与待办 | 说明当前限制、暂缓项和外部依赖 | | 17 | 前端合并提示词与验收约束 | 指导后续模型识别风控功能并合并前端 | | 18 | 当前项目完成进度 | 汇总当前完成度、验证结果和剩余任务 | +| 19 | 风控模块配置项清单 | 单独说明风控专用和公共依赖配置 | ## 推荐阅读顺序 @@ -49,3 +50,4 @@ 5. 11 至 16:理解证据、日报、审计、验收和限制。 6. 17:主项目前端合并时直接提供给模型。 7. 18:项目汇报、进度同步和下一阶段安排。 +8. 19:合并部署和联调时核对环境变量。 diff --git a/tests/unit/repository/test_risk_repository.py b/tests/unit/repository/test_risk_repository.py index ecd8023..f18bf79 100644 --- a/tests/unit/repository/test_risk_repository.py +++ b/tests/unit/repository/test_risk_repository.py @@ -432,6 +432,8 @@ async def test_notification_evidence_contains_alert_and_customer_numbers() -> No assert page.items[0]["alert_no"] == "ALERT-001" assert page.items[0]["customer_no"] == "CUST-009" + assert "read_time" not in page.items[0] + assert "ack_time" not in page.items[0] async def test_product_evidence_reuses_fund_query_repository() -> None: