投顾推荐空候选池:把"为什么没有产品"讲清楚,而不是一句"没有通过校验的产品"

"当前没有通过适当性与证据校验的产品。" 这句话对运营毫无信息量:既不知道是谁的问题,
也不知道下一步该做什么。现在空态会说明证据门口径(每个产品都要求 ①销售机构的**已验证**
适当性证据 ②基金合同快照,且都要带可核查的来源链接与文档 sha256,缺一即整只排除,
fail closed),并给出本轮候选/入选/排除的数量,以及两条可执行路径:

- 真实方案:先由产品治理线导入适当性证据与合同快照
  (	ools/import_product_governance_reference.py,CSV 需带 source_url 与 document_sha256);
- 呈现效果:切到页面顶部「本地演示数据」,那里的方案会标注"规则模拟、不构成真实推荐"。

同时说明本环境为空的原因:dvisor_product_suitability_reference 与
dvisor_product_contract_snapshot **均为 0 行**(26 个上市产品因此全部被证据门排除,
candidate_count=0,所以连"排除原因"也没有可展示的条目)。
This commit is contained in:
2026-09-14 23:34:36 +08:00
parent 467d2b5169
commit 48b43cfad5
@@ -231,7 +231,30 @@ export function createActionsModule({ output, alert, steps, amountInput, horizon
+ '</div>';
}
if (!products.length) {
html += note('当前没有通过适当性与证据校验的产品。', 'info');
// 空候选池**必须说清为什么**:只写"没有产品",运营既不知道是谁的问题、
// 也不知道下一步做什么。这里把证据门的口径与可执行动作一并给出。
const summary = data.selection_summary || {};
html += note(
'当前没有通过「适当性与证据校验」的产品。投顾推荐对每个产品都要求'
+ '①销售机构的**已验证**适当性证据、②基金合同快照,且两者都要带可核查的'
+ '来源链接与文档 sha256 —— 缺任一项即整只排除(fail closed)。'
+ '本环境这两类证据暂无数据,因此候选为 0。',
'info',
);
if (summary.candidate_count !== undefined) {
html += note(
`本轮候选 ${summary.candidate_count ?? 0} 只:入选 ${summary.selected_count ?? 0} 只、`
+ `排除 ${summary.excluded_count ?? 0} 只。`,
'info',
);
}
html += note(
'要看真实方案:先由产品治理线导入适当性证据与合同快照'
+ '(`tools/import_product_governance_reference.py`,CSV 需带 source_url 与 document_sha256);'
+ '只想先看呈现效果:可切到页面顶部的「本地演示数据」,那里的方案会明确标注'
+ '"规则模拟、不构成真实推荐"。',
'info',
);
} else {
html += table(['产品', '风险级', '评分', '推荐依据'], products.map((product) => {
const evidence = product.recommendation_evidence_card || {};