Commit 2f8c962a by luoqi

fix: closed chain 永不 ★ — 修陈化冰 K04 显示矛盾

陈化冰 case(v1 plan 显示):
  K04 chain.status=closed(alt-closed by 种植 16;17;26;46)
  K04 chain.target=true(老 plan reason 还含 K04)
  → 前端 TargetTimelineRow 强制按 discovered 渲染 ★潜在新链 + stage=1 hint
  → 但底部 HistoryStrip / ChainSidebarRow 看 status=closed 渲染 ✓已闭环
  → 同一条 chain 两个组件给出矛盾展示

修(双侧防御):
  1. plan-aggregate.assemble 加约束:
     if (c.status === 'closed') { c.target = false; continue; }
     closed = 临床已结束(拔了/被替代/全治完);即使 SQL 老 reason 仍命中也不 ★
     (SQL 召回老 closed chain 是 data race / 老 plan 残留,不该误导客服)
  2. chain-viz.findFocused:
     chains.find((c) => c.target && c.status !== 'closed')
     双层防御,即使后端漏改也不显示 closed 在 focused

验证(陈化冰 v1 plan superseded,5 reasons 仍含 K04):
  改前:K04 closed chain target=true → focused 错位
  改后:K04 chain target=false → focused = K00 先天/萌出处置·46(下一个 target=true)
        底部历史 ✓已闭环 正常显示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
parent 5967b684
...@@ -85,6 +85,9 @@ export class PlanAggregateService { ...@@ -85,6 +85,9 @@ export class PlanAggregateService {
}; };
for (const c of chains) { for (const c of chains) {
if (!c.code) { c.target = false; continue; } if (!c.code) { c.target = false; continue; }
// closed chain 永不 ★(临床已结束;即使 SQL 召回也是老 plan/data race 异常)
// K04 46 拔了/被替代关闭 → 即使老 plan reason 还含 K04 也不该 focused
if (c.status === 'closed') { c.target = false; continue; }
let hit = false; let hit = false;
for (const key of reasonKeys) { for (const key of reasonKeys) {
const [code, tooth] = key.split('|'); const [code, tooth] = key.split('|');
......
...@@ -186,8 +186,9 @@ function themeOfStatus(status: Chain['status']): 'rose' | 'emerald' | 'sky' | 'a ...@@ -186,8 +186,9 @@ function themeOfStatus(status: Chain['status']): 'rose' | 'emerald' | 'sky' | 'a
// ChainTimeline — 默认形态(详情抽屉用) // ChainTimeline — 默认形态(详情抽屉用)
// ────────────────────────────────────────── // ──────────────────────────────────────────
export function ChainTimeline({ chains }: { chains: Chain[] }) { export function ChainTimeline({ chains }: { chains: Chain[] }) {
const target = chains.find((c) => c.target); // focused chain:必须 target=true 且未闭环(closed chain 渲染成 ★潜在新链会自相矛盾)
const history = chains.filter((c) => !c.target); const target = chains.find((c) => c.target && c.status !== 'closed');
const history = chains.filter((c) => c !== target);
return ( return (
<div className="space-y-2"> <div className="space-y-2">
{target && <TargetTimelineRow chain={target} />} {target && <TargetTimelineRow chain={target} />}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment