From 6e5d0e88f6c76e28b687375e480446ac2ad98b7b Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Sat, 20 Jun 2026 16:00:51 +0200 Subject: [PATCH] =?UTF-8?q?feat(ux):=20R3=20=E9=AA=8C=E6=94=B6=E5=89=8D?= =?UTF-8?q?=E6=B8=85=E5=8D=95=20=E2=80=94=20AcceptPanel=E3=80=8C=E6=9C=AC?= =?UTF-8?q?=E6=AC=A1=E5=B0=86=E6=9B=B4=E6=96=B0=E3=80=8D=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新 lib/review/accept-preview.ts (buildAcceptPreview):据现有 client state 列验收前预期项——晋升版次/提炼摘要/写回裁决/伏笔到期扫描/伏笔建议待登记。仅列后端 accept 事务确实做的事(核对 projects.py accept 端点),不声称改人物 latest_state,带「以验收回执为准」免责。 AcceptPanel 加 foreshadowCount prop + 未阻断时渲染清单;ReviewReport 传 foreshadow.length。 TDD: 4 测。前端门禁绿: lint/tsc/vitest 205/build。 --- PROGRESS.md | 1 + apps/web/components/review/AcceptPanel.tsx | 42 +++++++++++++++--- apps/web/components/review/ReviewReport.tsx | 1 + apps/web/lib/review/accept-preview.test.ts | 48 ++++++++++++++++++++ apps/web/lib/review/accept-preview.ts | 49 +++++++++++++++++++++ 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 apps/web/lib/review/accept-preview.test.ts create mode 100644 apps/web/lib/review/accept-preview.ts diff --git a/PROGRESS.md b/PROGRESS.md index a803a16..15718a1 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -177,3 +177,4 @@ T0.1 monorepo 骨架 ✅ @devops · T0.2 16 MVP 表迁移(无漂移,users st - [2026-06-19] @llm — **K1.2 修头**:Kimi Code 适配器 `kimi_code_headers()` 改为**仅** `{"User-Agent": "KimiCLI/1.5"}`,删全部 X-Msh-* 头 + `kimi_device_id`/`KIMI_DEVICE_ID`/确定性 device-id 机制(K1.5 联网实测:有效 token 下 X-Msh-* 疑似触发 `401 Invalid Authentication`;对齐 pi-kimi-coder = UA-only)。改 `adapters/kimi_code.py` + `__init__` 导出 + 两测(adapter 6 测/factory 3 测,断 default_headers 仅 UA、无 X-Msh-*)。更 contracts C1扩(头集 UA-only)+ gotcha。门禁绿:ruff/format/mypy/pytest(56 passed)。 - [2026-06-19] @backend — **bugfix 空写章 prompt**:`assemble`(C5)从不含项目 premise/logline/theme/title 且无写章指令 → 全新项目(仅 premise)产空 `stable_core`+`volatile`,写章触发 LLM `400 message must not be empty`。修复:`MemoryRepos` 加第 8 repo `project:ProjectSpecRepo`(`SqlProjectSpecRepo` 按 project_id 读 `projects`);`assemble` 把「作品蓝本」放入 `stable_core` 首段(书级 spec→缓存前缀,守 #9)+ `volatile` 始终含「请创作第 N 章的正文。」。改 `domain/repositories.py`(+ProjectSpecView/Repo) · `memory/sql_repositories.py`(+SqlProjectSpecRepo, sql_memory_repos 装配) · `memory/assemble.py`(_build_spec_section + 注入);测试 `test_memory.py`(+bare-project/chapter-directive 两测+fake) · `test_projects.py`/`test_generation.py`(补 project= fake)。无 DDL/迁移(只读既有列)。门禁全绿:ruff/format/mypy(154 文件)/alembic check(无漂移)/pytest **438 passed**。更 contracts C5 + gotcha。消费方注意:手搓 `MemoryRepos(...)` 须补 `project=`。 - [2026-06-20] @frontend — **UX R1+R2 完成**(审稿裁决人体学,纯前端无后端改)。R1:冲突卡内联命中段预览——新纯函数 `lib/review/snippet.ts`(从 `where`「第 N 段」解析 1-based 段号 → 取终稿对应段截断预览,无段号/越界/空段→null 回退「跳转」),`ConflictCard` 加 `snippet` prop 渲染朱砂引用块。R2:冲突按 type 分组 + 严重度排序(设定违例>能力不符>时间线倒错>地理矛盾>性格漂移,未知殿后)+ 组计数徽标 + 「跳到下一条未裁决」(按显示顺序环回)+ 主次裁决按钮(采纳改法=朱砂主、忽略/手改=次级)——新纯函数 `lib/review/grouping.ts`(`groupConflicts`/`displayOrder`/`nextUnresolvedInOrder`,**分组只改显示顺序、每条携原始 index,守 conflict_index 覆盖 range 不变量**),`ReviewReport` 改分组渲染。TDD:snippet 8 测 + grouping 10 测。前端门禁绿:lint/tsc/**vitest 201**(+18)/build。分支 `feat/ux-r1-r2-review-ergonomics`。下一步(按 plan):R3 验收前清单 → Tier4。 +- [2026-06-20] @frontend — **UX R3 完成**(验收前清单 HITL gate,UX §7.4,纯前端无后端改,续 `feat/ux-r1-r2-review-ergonomics`)。新纯函数 `lib/review/accept-preview.ts`(`buildAcceptPreview`:据现有 client state 列「本次验收将更新」——晋升版次 + 提炼章节摘要 + 写回裁决(有冲突时) + 验收后伏笔到期扫描(可能置 OVERDUE) + 伏笔建议待登记提醒(有建议时))。**只列后端 accept 事务确实做的事**(核对 `projects.py` accept 端点:promote+digest+decisions+overdue 扫描;**不**声称改人物 latest_state/自动落库伏笔建议);带「以上为预期,最终以验收回执为准」免责。`AcceptPanel` 加 `foreshadowCount` prop + 未阻断时渲染清单,`ReviewReport` 传 `foreshadow.length`。TDD:4 测。前端门禁绿:lint/tsc/**vitest 205**(+4)/build。下一步(按 plan):Tier4(T4-a 顶部 AI 工具条 / T4-b 本章指令框+风格预设)。 diff --git a/apps/web/components/review/AcceptPanel.tsx b/apps/web/components/review/AcceptPanel.tsx index 410540f..d6a75ae 100644 --- a/apps/web/components/review/AcceptPanel.tsx +++ b/apps/web/components/review/AcceptPanel.tsx @@ -1,10 +1,13 @@ "use client"; import type { AcceptResponse } from "@/lib/api/types"; +import { buildAcceptPreview } from "@/lib/review/accept-preview"; interface AcceptPanelProps { conflictCount: number; unresolvedCount: number; + // R3:当前伏笔建议数(验收前清单提醒,只读不自动落库)。 + foreshadowCount: number; accepting: boolean; result: AcceptResponse | null; onAccept: () => void; @@ -14,11 +17,16 @@ interface AcceptPanelProps { export function AcceptPanel({ conflictCount, unresolvedCount, + foreshadowCount, accepting, result, onAccept, }: AcceptPanelProps) { const blocked = unresolvedCount > 0; + const preview = buildAcceptPreview({ + conflictCount, + foreshadowSuggestions: foreshadowCount, + }); if (result) { return ( @@ -56,11 +64,35 @@ export function AcceptPanel({ 尚有 {unresolvedCount} 项冲突未裁决,处理完才能验收。

) : ( -

- {conflictCount === 0 - ? "无冲突,可直接验收。" - : "全部冲突已裁决,可验收本章。"} -

+ <> +

+ {conflictCount === 0 + ? "无冲突,可直接验收。" + : "全部冲突已裁决,可验收本章。"} +

+ {/* R3:验收前「本次将更新」清单(预期,落库口径以验收回执为准)。 */} +
+

+ 本次验收将更新 +

+ +

+ 以上为预期,最终以验收回执为准。 +

+
+ )}