- 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.
85 lines
5.7 KiB
HTML
85 lines
5.7 KiB
HTML
<section class="module" id="module-1">
|
||
<div class="module-inner">
|
||
<p class="eyebrow animate-in">模块 1 · 双栈鉴权</p>
|
||
<h1 class="module-title animate-in">JWT 双栈:<br>模块鉴权(deps.py)与宿主网关鉴权(gateway/auth_deps.py)各管一线</h1>
|
||
<p class="module-lead animate-in">
|
||
模块 API 走模块鉴权(<code>app/api/deps.py</code>)(<code>get_auth_context</code> / <code>get_platform_auth_context</code>);
|
||
宿主 Wave 0 网关走宿主网关鉴权(<code>app/gateway/auth_deps.py</code>)。
|
||
<strong>模块禁止 import gateway</strong>——指挥 AI 改鉴权时,先确认改的是哪条栈。
|
||
</p>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>两套鉴权表(背下来少踩坑)</h2>
|
||
<table style="width:100%; border-collapse:collapse; margin: 1.5rem 0; font-size: 0.95rem;">
|
||
<thead><tr><th>通道</th><th>入口函数</th><th>X-Agent-Type</th><th>典型路由</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Agent / 对话</td><td><code>get_auth_context</code></td><td>JWT 通道<strong>必填</strong> + 准入矩阵</td><td>/api/chat, /api/risk/*, simulate</td></tr>
|
||
<tr><td>平台只读</td><td><code>get_platform_auth_context</code></td><td><strong>不要</strong></td><td>/api/customers/*, /api/analyst/*</td></tr>
|
||
<tr><td>宿主网关</td><td>宿主网关鉴权(<code>gateway/auth_deps.py</code>)· <code>get_auth_context</code></td><td>宿主口径</td><td>Wave 0 四件套(模块不 import)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="callout callout-warning">
|
||
<strong>debug 头兜底:</strong> 仅 <code>APP_ENV=development</code> 且无 RS256 公钥时,可用 <code>X-Debug-Role</code> + <code>X-Debug-Actor</code> 冒充身份——pytest 和部分演示 SOP 依赖此通道;生产一律 Bearer JWT。
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<div class="translation-block">
|
||
<div class="translation-code">
|
||
<span class="translation-label">模块鉴权(deps.py)· 对话线</span>
|
||
<pre><code><span class="code-line">agent_type = request.headers.get(<span class="code-string">"X-Agent-Type"</span>)</span>
|
||
<span class="code-line"><span class="code-keyword">if not</span> agent_type:</span>
|
||
<span class="code-line"> raise ApiError(<span class="code-number">401</span>, <span class="code-string">"AUTH_401_MISSING_AGENT_TYPE"</span>)</span>
|
||
<span class="code-line">assert_agent_access(auth, agent_type, ...)</span>
|
||
<span class="code-line"></span>
|
||
<span class="code-line"><span class="code-comment"># 平台线 — 无上述检查</span></span>
|
||
<span class="code-line"><span class="code-keyword">def</span> <span class="code-function">get_platform_auth_context</span>(request):</span>
|
||
<span class="code-line"> <span class="code-string">"""不要求 X-Agent-Type"""</span></span></code></pre>
|
||
</div>
|
||
<div class="translation-english">
|
||
<span class="translation-label">白话</span>
|
||
<div class="translation-lines">
|
||
<p class="tl">对话线:验完 JWT 还要读 Agent 头,并对照 AGENT_ACCESS_MATRIX。</p>
|
||
<p class="tl">例如客户 token 不能带 X-Agent-Type: risk,否则 403。</p>
|
||
<p class="tl">平台线:验 JWT 就放行到归属断言,不问你走哪条 Agent。</p>
|
||
<p class="tl">宿主网关鉴权(gateway/auth_deps.py)栈是宿主合并用,和模块鉴权(deps.py)双栈并存,别在模块里混 import。</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>准入矩阵速览</h2>
|
||
<div class="badge-list">
|
||
<div class="badge-item"><span class="badge-code">customer</span><span class="badge-desc">仅 customer 角色</span></div>
|
||
<div class="badge-item"><span class="badge-code">advisor</span><span class="badge-desc">advisor / compliance / ops</span></div>
|
||
<div class="badge-item"><span class="badge-code">analyst</span><span class="badge-desc">analyst / compliance</span></div>
|
||
<div class="badge-item"><span class="badge-code">risk</span><span class="badge-desc">risk_officer / risk_manager / service_risk</span></div>
|
||
</div>
|
||
|
||
<div class="quiz-container" id="quiz-shared-m1">
|
||
<div class="quiz-question-block"
|
||
data-correct="option-b"
|
||
data-explanation-right="平台读 API 用 get_platform_auth_context,文件在模块鉴权(deps.py),与宿主网关鉴权(gateway/auth_deps.py)无关。"
|
||
data-explanation-wrong="宿主网关鉴权(gateway/auth_deps.py)是宿主 Wave 0;模块平台路由只 Depends 模块鉴权(deps.py)里的函数。">
|
||
<h3 class="quiz-question">customers.py 的 Depends 应该从哪 import?</h3>
|
||
<div class="quiz-options">
|
||
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>app.gateway.auth_deps</span>
|
||
</button>
|
||
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>app.api.deps.get_platform_auth_context</span>
|
||
</button>
|
||
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>对话 HTTP 入口(chat.py)里的解析函数</span>
|
||
</button>
|
||
</div>
|
||
<div class="quiz-feedback"></div>
|
||
</div>
|
||
<button class="quiz-check-btn" onclick="checkQuiz('quiz-shared-m1')">检查答案</button>
|
||
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-shared-m1')">重做</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|