Files
group_xinghuo_jinrong/docs/course/jinrong-module-platform/modules/01-routes.html
T

109 lines
6.7 KiB
HTML
Raw Normal View History

<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>