Files
group_xinghuo_jinrong/docs/course/jinrong-module-risk/modules/02-engine.html
T
zhanghongyu_0626 21ced4d38f feat(report): Add battery report generation and update course documentation
- Introduced `battery_report.json` for local data analysis, excluding it from the database.
- Enhanced `AGENTS.md` to reflect updated test baseline with 795 passed tests.
- Added new metrics for trade flow in `dict_service.py`, improving transaction data analysis.
- Updated regex patterns in `guardrail.py` to better handle numeric extraction and prevent misinterpretation of tokens.
- Expanded course modules with new content on FR-8/9/10 capabilities and L3 role management.
- Improved concurrency handling in transaction processing to ensure accurate alert generation.

This update enhances data analysis capabilities and improves the overall structure and clarity of course materials.
2026-09-10 14:32:25 +08:00

110 lines
7.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<section class="module" id="module-2">
<div class="module-inner">
<p class="eyebrow animate-in">模块 2 · 模拟交易链路</p>
<h1 class="module-title animate-in">一笔演示交易<br>怎么长出预警单?</h1>
<p class="module-lead animate-in">
<code>RiskSimulatePage</code> 提交表单 → 模拟交易入口(<code>simulate.py</code>)验权 → 模拟写 Core 网关(<code>trade_gateway.py</code>)写库 →
规则引擎(<code>risk_engine.py</code>)扫规则 → 聚合进 <code>risk_alert</code>。
像演示用的「假收银台」:钱是假的,但风控流程是真的。
</p>
<div class="screen animate-in">
<h2>四段链路(动画)</h2>
<div class="flow-animation" data-steps='[
{"highlight":"flow-actor-1","label":"RiskSimulatePage:submitSimulateTrade(token, \"risk\", body)"},
{"highlight":"flow-actor-2","label":"模拟交易入口(simulate.py):POST /api/simulate/trade → 鉴权 risk_demo 或客户本人","packet":true,"from":"1","to":"2"},
{"highlight":"flow-actor-3","label":"模拟写 Core 网关(trade_gateway.py):R-02 适当性 → INSERT core_trade(唯一写 Core 路径)","packet":true,"from":"2","to":"3"},
{"highlight":"flow-actor-4","label":"规则引擎(risk_engine.py)扫描 → 写 risk_alert(大额/集中度等)","packet":true,"from":"3","to":"4"},
{"highlight":"flow-actor-1","label":"台账 GET /api/risk/alerts 可见 + 固定 disclaimer","packet":true,"from":"4","to":"1"}
]'>
<div class="flow-actors">
<div class="flow-actor" id="flow-actor-1"><span class="flow-actor-icon">🧪</span><span>模拟交易 UI</span></div>
<div class="flow-actor" id="flow-actor-2"><span class="flow-actor-icon">🚪</span><span>模拟交易入口</span></div>
<div class="flow-actor" id="flow-actor-3"><span class="flow-actor-icon">⚙</span><span>模拟写 Core 网关</span></div>
<div class="flow-actor" id="flow-actor-4"><span class="flow-actor-icon">🛡</span><span>规则引擎</span></div>
</div>
<p class="flow-step-label">Preset A-3:CUST-3001 · 50 万 → 大额预警 · Preset A-1:适当性阻断</p>
<div class="flow-controls">
<button class="btn flow-next-btn">下一步</button>
<button class="btn flow-reset-btn">重来</button>
</div>
</div>
</div>
<div class="screen animate-in">
<h2>R-02 阻断 vs R-01 大额待审(同网关、不同结果)</h2>
<p>模拟写 Core 网关(<code>trade_gateway.py</code>)里<strong>先</strong>跑适当性:不过 → 交易写不进去(R-02);过了 → 写入 <code>core_trade</code> → 规则引擎再扫 R-01 大额等 → 出 <code>pending_review</code> 预警。</p>
<div class="pattern-cards">
<div class="pattern-card">
<h3>A-1 · R-02 阻断</h3>
<p>CUST-1001 + PROD-161725 · 风评与产品 R 档不匹配 → 网关拒绝 · 可有 suitability 类预警 · <strong>无成交</strong></p>
</div>
<div class="pattern-card">
<h3>A-3 · R-01 大额待审</h3>
<p>CUST-3001 · 50 万申购 → 成交写入 Core → 引擎出大额类 <code>pending_review</code> · 台账可见</p>
</div>
</div>
<div class="callout callout-warning">
<strong>指挥 AI 时:</strong> 别把「阻断交易」和「出预警待审」混成一个状态——前者在网关,后者在引擎聚合。
</div>
</div>
<div class="screen animate-in">
<h2>代码地图</h2>
<div class="file-tree animate-in">
<div class="tree-item tree-folder">模拟交易入口(app/api/simulate.py)</div>
<div class="tree-item tree-indent">薄路由:鉴权 + 调 submit_trade</div>
<div class="tree-item tree-folder">模拟写 Core 网关(app/gateway/trade_gateway.py)</div>
<div class="tree-item tree-indent">适当性 → 写 core_trade → 调 risk 引擎</div>
<div class="tree-item tree-folder">app/service/risk/</div>
<div class="tree-item tree-indent">规则引擎(risk_engine.py) · alert_service.py · 规则聚合</div>
<div class="tree-item tree-folder">web/src/pages/risk/RiskSimulatePage.tsx</div>
<div class="tree-item tree-indent">预设 A-1 / A-3 一键填表</div>
</div>
</div>
<div class="screen animate-in">
<div class="translation-block">
<div class="translation-code">
<span class="translation-label">CODE · 模拟交易入口(simulate.py)</span>
<pre><code><span class="code-line"><span class="code-keyword">if not</span> (auth.has_role(<span class="code-string">"risk_demo"</span>)</span>
<span class="code-line"> <span class="code-keyword">or</span> (auth.is_customer() <span class="code-keyword">and</span></span>
<span class="code-line"> auth.customer_id == req.customer_id)):</span>
<span class="code-line"> deny(auth, <span class="code-string">"AUTH_403_ROLE"</span>, ...)</span>
<span class="code-line"><span class="code-keyword">return</span> submit_trade(req.model_dump(), ...)</span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">白话</span>
<div class="translation-lines">
<p class="tl">能点「提交模拟交易」的只有两类人:带 risk_demo 的风控演示号,或客户本人买自己的单。</p>
<p class="tl">STAFF-30001 在 jwt_service 里配了 risk_demo,所以能造 A-3 大额演示数据。</p>
</div>
</div>
</div>
<div class="quiz-container" id="quiz-risk-m2">
<div class="quiz-question-block"
data-correct="option-c"
data-explanation-right="模拟写 Core 网关(trade_gateway.py)是唯一允许向 jinrong_core 写 INSERT 的路径(模拟成交);Agent 画像不能直接改 Core 正式字段。"
data-explanation-wrong="问数和其他 Agent 对 Core 是只读;只有网关模拟交易可写 core_trade。">
<h3 class="quiz-question">Demo 里谁可以把新成交写进 core_trade?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>NL→SQL 编排(analyst_agent.py)问数 SQL</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>风控对话 Tool</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>模拟写 Core 网关(trade_gateway.py,经 simulate/trade)</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<button class="quiz-check-btn" onclick="checkQuiz('quiz-risk-m2')">检查答案</button>
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-risk-m2')">重做</button>
</div>
</div>
</div>
</section>