- 续审 Agent 声明(AgentSpec) + 结构化输出契约(ContinuityReview/Conflict 五类) - LangGraph 并行审子图(可扩四审) + collect 落 chapter_reviews 留痕 + review SSE(section/conflict) - 验收-side Repository:章节 accepted 版本晋升 + digest append-only + 审稿留痕/裁决 - API:review(SSE) + reviews 历史 + accept(单原子事务:晋升 version + 终稿 digest + 裁决留痕) - 冲突 gate:未决裁决拦截(CONFLICT_UNRESOLVED);digest 从终稿提炼(不变量#4) - 前端:审稿报告页 + 冲突就地标注 + 裁决(采纳/忽略/手改) + 未决禁验收 + 「本次将更新」清单 - M2 E2E:真实 DB + 多档位 mock 网关零 token 走通 写→审→裁决→验收→摘要入库 - 多 agent 协同台账(PROGRESS.md) + 共享记忆(memory/contracts·decisions·gotchas)
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
"use client";
|
||
|
||
import type { AcceptResponse } from "@/lib/api/types";
|
||
|
||
interface AcceptPanelProps {
|
||
conflictCount: number;
|
||
unresolvedCount: number;
|
||
accepting: boolean;
|
||
result: AcceptResponse | null;
|
||
onAccept: () => void;
|
||
}
|
||
|
||
// 验收 gate(UX §9 / §8.4):未决禁验收(置灰 + 文案),验收后呈现「本次将更新」清单。
|
||
export function AcceptPanel({
|
||
conflictCount,
|
||
unresolvedCount,
|
||
accepting,
|
||
result,
|
||
onAccept,
|
||
}: AcceptPanelProps) {
|
||
const blocked = unresolvedCount > 0;
|
||
|
||
if (result) {
|
||
return (
|
||
<div className="rounded border border-pass/50 bg-panel p-4">
|
||
<h3 className="mb-2 text-sm font-semibold text-pass">本章已验收</h3>
|
||
<ul className="space-y-1 text-xs text-ink-soft">
|
||
<li>
|
||
晋升版次:
|
||
<span className="font-mono text-ink">v{result.accepted_version}</span>
|
||
</li>
|
||
<li>
|
||
章节摘要:{result.digest_added ? "已新增一行" : "未变更"}
|
||
</li>
|
||
<li>
|
||
裁决写回:
|
||
<span className="font-mono text-ink">
|
||
{result.decisions_recorded}
|
||
</span>{" "}
|
||
条
|
||
</li>
|
||
{result.review_id ? (
|
||
<li className="truncate">
|
||
留痕:<span className="font-mono">{result.review_id}</span>
|
||
</li>
|
||
) : null}
|
||
</ul>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="rounded border border-line bg-panel p-4">
|
||
{blocked ? (
|
||
<p className="mb-2 text-xs text-conflict" role="status">
|
||
尚有 {unresolvedCount} 项冲突未裁决,处理完才能验收。
|
||
</p>
|
||
) : (
|
||
<p className="mb-2 text-xs text-ink-soft">
|
||
{conflictCount === 0
|
||
? "无冲突,可直接验收。"
|
||
: "全部冲突已裁决,可验收本章。"}
|
||
</p>
|
||
)}
|
||
<button
|
||
type="button"
|
||
onClick={onAccept}
|
||
disabled={blocked || accepting}
|
||
aria-disabled={blocked || accepting}
|
||
className="w-full rounded bg-cinnabar px-4 py-2 text-sm text-panel hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40"
|
||
>
|
||
{accepting ? "验收中…" : "全部处理完 → 验收本章"}
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|