Files
group_xinghuo_jinrong/docs/course/jinrong-module-platform/modules/01-routes.html
T
zhanghongyu_0626 4b8e11c9bd feat(threshold): Implement customer loss threshold configuration and notification system
- Added `ThresholdRepository` for managing customer loss threshold configurations and notifications.
- Introduced `threshold_service` to handle loss threshold alerts based on customer portfolio performance.
- Enhanced `customer_prompts` to include new intent for querying product net values.
- Updated `customer_service` to integrate new threshold alert functionality into existing workflows.
- Implemented `sanitize_postprocess` for improved compliance handling in customer interactions.
- Enhanced course documentation to reflect updates in advisor training modules and interactive elements.

This update significantly improves the customer experience by providing proactive loss threshold notifications and enhancing the overall service framework.
2026-09-10 10:57:40 +08:00

109 lines
6.7 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-1">
<div class="module-inner">
<p class="eyebrow animate-in">模块 1 · 路由地图</p>
<h1 class="module-title animate-in">v0.1 路由:<br>customers / products / advisors / compliance</h1>
<p class="module-lead animate-in">
代销平台 API 是「读 Core 模拟库」的
<span class="term" data-definition="REST = 用固定 URL + HTTP 方法(GET/POST)读写数据的约定,浏览器和 App 都按这个格式发请求。">REST</span>
门面。路由按<strong>业务域</strong>切分,不用 <code>/api/platform/*</code> 前缀。
和 Agent 对话线(<code>/api/chat</code>)是两条平行轨道——指挥 AI 加「查持仓」时,先确认走哪条。
</p>
<div class="screen animate-in">
<h2>四块 canonical 域(以本文为准)</h2>
<div class="pattern-cards">
<div class="pattern-card">
<h3>/api/customers/*</h3>
<p>客户 L0 档案、持仓、流水。平台客户 REST 薄路由(<code>customers.py</code>) → <code>platform/customer_service</code> → <code>core_ro</code>。</p>
</div>
<div class="pattern-card">
<h3>/api/products/*</h3>
<p>产品列表、净值曲线。理财师/客户看产品详情都走这里,不另开 Agent Tool HTTP。</p>
</div>
<div class="pattern-card">
<h3>/api/advisors/*</h3>
<p>理财师名下客户归属。advisor 只能查本人 roster,风控/分析员可全量只读。</p>
</div>
<div class="pattern-card">
<h3>/api/compliance/*</h3>
<p>适当性判定等合规读接口。<strong>canonical</strong>:Agent 合并期改调同一 Service,不保留第二套路径。</p>
</div>
</div>
<div class="callout callout-accent">
<strong>重复能力以谁为准?</strong> 以本平台 API 为准。Agent 侧已有同能力 Tool 时,合并期改调 <code>app/service/platform/</code>,旧路径仅过渡。
</div>
</div>
<div class="screen animate-in">
<h2>三层分工(别让 AI 在路由里写 SQL)</h2>
<div class="flow-animation" data-steps='[
{"highlight":"flow-actor-1","label":"HTTP 请求进入 平台客户 REST 薄路由(customers.py)"},
{"highlight":"flow-actor-2","label":"get_platform_auth_context:验 JWT + 归属","packet":true,"from":"1","to":"2"},
{"highlight":"flow-actor-3","label":"platform_service:组装、分页、脱敏开关","packet":true,"from":"2","to":"3"},
{"highlight":"flow-actor-4","label":"core_ro:SELECT 只读,不感知 HTTP","packet":true,"from":"3","to":"4"},
{"highlight":"flow-actor-1","label":"ok() 统一外壳返回 JSON","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>api/*.py</span></div>
<div class="flow-actor" id="flow-actor-2"><span class="flow-actor-icon">🔑</span><span>deps 鉴权</span></div>
<div class="flow-actor" id="flow-actor-3"><span class="flow-actor-icon">📦</span><span>platform Service</span></div>
<div class="flow-actor" id="flow-actor-4"><span class="flow-actor-icon">🗄</span><span>core_ro</span></div>
</div>
<p class="flow-step-label">点击「下一步」看一层层往下走</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">
<div class="translation-block">
<div class="translation-code">
<span class="translation-label">平台客户 REST 薄路由(customers.py)</span>
<pre><code><span class="code-line"><span class="code-comment">"""代销平台 · 客户 L0 与资产读 API(canonical · 不要求 X-Agent-Type)。"""</span></span>
<span class="code-line">@router.get(<span class="code-string">"/{customer_id}/holdings"</span>)</span>
<span class="code-line"><span class="code-keyword">def</span> <span class="code-function">list_holdings</span>(</span>
<span class="code-line"> customer_id: str,</span>
<span class="code-line"> auth: AuthContext = Depends(get_platform_auth_context),</span>
<span class="code-line">):</span>
<span class="code-line"> assert_platform_customer_access(auth, customer_id, ...)</span>
<span class="code-line"> <span class="code-keyword">return</span> ok(platform_service.list_holdings(customer_id))</span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">白话</span>
<div class="translation-lines">
<p class="tl">文件头就写明:这是平台 canonical 读接口,不要 X-Agent-Type。</p>
<p class="tl">URL 用复数 customers + 嵌套 holdings,参数名和域 ID 一致。</p>
<p class="tl">鉴权用平台专用函数,不是 chat 那条 get_auth_context。</p>
<p class="tl">先断言「你有没有权看这个 customer_id」,再调 Service,路由里不出现 SQL。</p>
</div>
</div>
</div>
<div class="quiz-container" id="quiz-platform-m1">
<div class="quiz-question-block"
data-correct="option-b"
data-explanation-right="对。v0.1 拍板:重复能力以本平台 API + platform Service 为准,Agent Tool 合并时改调同一层。"
data-explanation-wrong="不要在 Agent 里再抄一套查持仓 HTTP;会两套口径、联调必炸。">
<h3 class="quiz-question">理财师 Agent 也要查客户持仓,应该新建 /api/agent/holdings 吗?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>要,Agent 专用路径更清晰</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>不要,改调 platform Service 或现有 /api/customers 路径</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>直接在 Agent 里写 SQL 更快</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<button class="quiz-check-btn" onclick="checkQuiz('quiz-platform-m1')">检查答案</button>
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-platform-m1')">重做</button>
</div>
</div>
</div>
</section>