fix(web): 账户弹窗移出 inert;校正快照失败不再静默(BUG-968/969)
账户弹窗与入门付费墙 portal 到 document.body,SidebarInset 的 inert 不再罩住弹窗。 GET 校正快照每个非 200 打 JSON warn;客户端失败显示「这一问还没读到」和重新读取。 下一题是可渲染选择题时,确定性回复正文带题干,挂卡后去重。
This commit is contained in:
+9
-9
@@ -12752,32 +12752,32 @@
|
||||
|
||||
## BUG-968 | 账户弹窗打开后整个弹窗点不动,退出登录做不了
|
||||
|
||||
- 状态:investigating(根因已由代码确认,修复未做)
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-18
|
||||
- 最近更新:2026-09-18
|
||||
- 影响面:`src/app/(app)/layout.tsx` `AppShell`、`src/app/(app)/page.tsx` `AccountDialogOverlay` 渲染位置、`use-home-shell-registration.ts` `insetInert`;staging `877128ce`
|
||||
- 用户现象:点侧栏「个人资料 / 退出登录」等任一账户入口,弹窗出现但关闭按钮、表单、确认退出全部点不动;正文区同时点不动。刷新后依旧。
|
||||
- 触发条件:任何让 `modalOpen` 为真的弹窗(五个账户弹窗、onboarding 付费墙)。
|
||||
- 根因:`e4e73f56` 把 `SidebarInset` 搬进 `(app)/layout.tsx` 后,`inert={modalOpen}` 罩住了整个 `children`,而 `AccountDialogOverlay` 由 `page.tsx` 渲染、没有 portal,落在 inert 子树里。搬家前弹窗是 `SidebarInset` 的兄弟节点。
|
||||
- 修复:待做,见 `docs/tasks/TASK-account-dialog-inert-20260918.md` §3.1。
|
||||
- 验证:待做。临时脱困:按 Esc(`window` 级监听不受 inert 影响)。
|
||||
- 防复发:合同测试断言 `role="dialog"` 不在 inert 祖先内。
|
||||
- 修复:选 (a) `createPortal(..., document.body)`。`AccountDialogOverlay` 与 onboarding 付费墙都挂到 `document.body`;`SidebarInset` 的 `inert={modalOpen}` 和移动端抽屉 `isMobile && openMobile` 分支不动。选 portal 而不是把节点交给 layout,是为了不改 `registerShellControls` 协议、并保住现有 DOM 结构与样式。
|
||||
- 验证:`frontend/tests/account-dialog-inert-20260918.test.ts` 断言 overlay / paywall portal 到 `document.body`、layout 仍 inert `SidebarInset`、`role="dialog"` 渲染不含 inert;现有 overlay / sidebar / a11y 合同见定向测试。真机五弹窗点关闭/提交见 `docs/testing/account-dialog-inert-20260918.md`。
|
||||
- 防复发:合同测试断言弹窗 portal 到 `document.body`,且 `SidebarInset` 仍吃 `inert`。
|
||||
- 关联记录:BUG-744~746(侧栏统一)、BUG-926~929(外壳搬家)、BUG-965(跨部署标签页,另一问题)
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
- 修复版本:`1ace0e64`
|
||||
|
||||
## BUG-969 | 生时校正「换一件事问」之后无下文:快照拿不到,两端都不吭声
|
||||
|
||||
- 状态:investigating
|
||||
- 状态:mitigated(快照失败根因仍未由线上日志证实,不得写 resolved)
|
||||
- 首次发现:2026-09-18
|
||||
- 最近更新:2026-09-18
|
||||
- 影响面:`GET /api/rectification/cases/[caseId]`、`rectification-agentic-chat.tsx` `loadCaseSnapshot`、`rectification-surface-state.ts` `hydrateRectificationCase`、确定性回复的题干投递
|
||||
- 用户现象:口述两轮经历后说「想不到了」,回复「已记录。这题先不计分,换一件事问。」然后没有题卡;右侧盘面停在占位、时间轴无候选点、输入框占位是「再说一件带年月的事」。
|
||||
- 触发条件:真实 Case 上服务端已落库下一道财务探针(active,绑在该回复轮),GET 快照本地用真实数据行重算完整、客户端解析函数全部通过;客户端却仍是开场时的快照状态。
|
||||
- 根因:未定。已确认的是链路两端都静默:GET 路由所有异常 503 不写日志,客户端快照失败一律吞掉,边缘与应用层都无 GET 访问日志,PG 未开函数统计。事后无法证明请求是否到达服务端。
|
||||
- 修复:待做,见 `docs/tasks/TASK-account-dialog-inert-20260918.md` §3.2(服务端非 200 记日志、客户端失败显示状态、确定性回复正文带题干)。
|
||||
- 验证:待做。
|
||||
- 修复:① GET 每一个非 200(401/400/409/404/503,含 supabase 配置失败)`console.warn` 一条 JSON(`event=rectification_case_get_failed`、`case_id`、`status`、`code`、`reason=safeToolErrorCode`,不含用户资料)。② `loadCaseSnapshot` / `hydrateRectificationCase` / `refreshRectificationCase` 把非 2xx 或网络错误带回调用方;校正面显示「这一问还没读到。」+「重新读取」,不再装成采集等待。③ 下一题是可渲染选择题时,`persistApplied` 与 `persistCollectDenialTurn` 用 `composeCollectSpokenAssistantText` 把题干追加进正文并随流发出;卡片仍由 GET 挂上,`attachQuestionsToTurns` 的 `stripQuestionSentences` 去重。
|
||||
- 验证:`frontend/tests/account-dialog-inert-20260918.test.ts` 覆盖 GET warn、503 文案与按钮、ack+stem 流式及挂卡后题干只出现一次;hydrate 失败带 `failure.status`。真机清单见 `docs/testing/account-dialog-inert-20260918.md`。若真机仍复现,凭服务端 JSON warn 把本条转 confirmed 并补根因。
|
||||
- 防复发:确定性回复不得只靠 GET 挂卡投递题干;快照失败不得静默。
|
||||
- 关联记录:BUG-525(题干经 asked_turn_id 挂上)、BUG-930(回答钉顶:只见最后一轮是设计)、BUG-965
|
||||
- 复发自:待确认
|
||||
- 修复版本:待发布
|
||||
- 修复版本:`1ace0e64`
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# PROGRESS · 账户弹窗 inert + 校正快照不再静默(2026-09-18)
|
||||
|
||||
工作树:`.worktrees/account-dialog-inert-20260918`
|
||||
分支:`codex/account-dialog-inert-20260918`
|
||||
基线:`origin/staging` @ `e760b1d6`(任务书写 `1061514f`,开工时 staging 已快进到此)
|
||||
合入提交:`1ace0e64`
|
||||
任务书:`docs/tasks/TASK-account-dialog-inert-20260918.md`
|
||||
|
||||
## 任务状态
|
||||
|
||||
| 任务 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 3.1 BUG-968 弹窗移出 inert | 完成 | 选 (a) `createPortal(..., document.body)`。账户弹窗与 onboarding 付费墙都挂到 `document.body`。`SidebarInset` 的 `inert={modalOpen}` 保留,移动端抽屉分支不动。 |
|
||||
| 3.2.1 GET 非 200 记 warn | 完成 | `warnRectificationCaseGet`:401/400/409/404/503 及 supabase 配置失败都打 JSON(`event` / `case_id` / `status` / `code` / `reason`),不含用户资料。 |
|
||||
| 3.2.2 客户端失败不静默 | 完成 | `loadCaseSnapshot` 非 2xx / 网络错误写入 `snapshotFailure`;校正面「这一问还没读到。」+「重新读取」。hydrate 带 `failure.status`。`refreshRectificationCase` 失败走 composer notice。Abort 不当失败。 |
|
||||
| 3.2.3 确定性回复带题干 | 完成 | 下一题是可渲染选择题时,`persistApplied` 与 `persistCollectDenialTurn` 用 `composeCollectSpokenAssistantText` 追加题干并随流发出。口述采集仍只 stream ack(BUG-525)。`attachQuestionsToTurns` 去重。 |
|
||||
|
||||
## 方案选择(3.1)
|
||||
|
||||
选 **(a) createPortal 到 document.body**,不选 (b) 把节点交给 AppShell。
|
||||
|
||||
原因:现有 overlay 的 DOM、焦点圈禁(`overlayRef` + `keepFocusWithin`)、Esc 关闭都不用改;不必扩展 `registerShellControls`。SSR 走 `typeof document === "undefined"` 的原树,现有 `renderToString` 合同继续看见 dialog。
|
||||
|
||||
## 让步
|
||||
|
||||
无。3.1 与 3.2 的 1→2→3 都做完。BUG-969 快照失败的根因仍未由线上日志证实,状态写 **mitigated**,不得写 resolved。
|
||||
|
||||
## 测试
|
||||
|
||||
| 项 | 结果 |
|
||||
| --- | --- |
|
||||
| `tsc --noEmit` | 0 错 |
|
||||
| `npm run lint` | **0 error** / 120 warning(未顺手修 warning) |
|
||||
| 定向 | `account-dialog-inert-20260918` 4/4;overlay / surface-state / surface-contract / collect-stall / question-in-message / membership / sidebar-contract / a11y / home-shell-growth / answer-choice **全绿** |
|
||||
| 全量 `npm test` | 3480 条,3402 绿,**78 红**。失败清单是 Windows 无 Docker / skill symlink `EPERM` / Unix 部署脚本,与本机近期口径一致;新增 4 条全绿,被改过的 discriminator 断言已按三栏改完。Linux 门禁基线仍是 31 红。 |
|
||||
| `Home()` 冻结 | useState / useRef 未增长 |
|
||||
@@ -143,7 +143,7 @@
|
||||
| `TASK-window-consult-contract-20260918.md` §5 | `PROGRESS-window-consult-precompute-20260918.md` | BUG-957:申报时段计算改为服务端预跑并走同请求缓存。产品确认 BUG-954 已在 staging 验证,本轮单独做。不得 `toolChoice: "required"`,本命不预跑 | 待验收 | `53d78137` |
|
||||
| `TASK-chat-markdown-list-20260918.md` | `PROGRESS-chat-markdown-list-20260918.md` | 真机排版反馈:聊天正文列表**没有项目符号**(Tailwind v4 preflight 清了 `list-style`,`.markdown-list` 没恢复,BUG-962);`promoteDefinitionLists` 把四标题口语体的散文误判成并列项,三段正文被改写成列表(BUG-963,判据太松,收紧而非删除——BUG-356 的场景要留);思考条与正文之间实测 56px=报告 grid gap 24 + 首标题 margin-top 32,后者是被特指度压掉的「首元素清零」规则(BUG-964)。基线 `ea0280c1` | 待验收 | `dccedf37` |
|
||||
| `TASK-secondary-page-entry-20260918.md` | `PROGRESS-secondary-page-entry-20260918.md` | 真机反馈:星盘 / 星历 / 报告进入时抖一下——三页都是「矮的等待文案块 → 高的正文块」一次推挤,且 `use-chart-page` 无缓存所以每次进入都抖(BUG-966)。产品已拍板方案一:统一外壳 + 缓存 + 预取消灭中间态,**不加 spinner**,红线不动。另含 BUG-967:标签页跨过部署后客户端导航静默失效(BUG-965 已复现确认,刷新即恢复),要按 `NEXT_PUBLIC_GIT_COMMIT` 与 `/api/health` 比对自愈。基线 `41902067` | 待验收 | `9ccb65b7` |
|
||||
| `TASK-account-dialog-inert-20260918.md` | — | 真机:账户弹窗打开后整个弹窗点不动、退出登录做不了,刷新依旧——`e4e73f56` 把 `SidebarInset` 搬进 layout 后 `inert={modalOpen}` 罩住了没有 portal 的 `AccountDialogOverlay`(BUG-968,P0,代码级确认)。另含 BUG-969:校正「换一件事问」后无下文,服务端已出下一题且快照重算完整,客户端停在开场状态,GET 路由与客户端两端静默,本单只做可观测 + 不静默 + 题干进正文。基线 `1061514f` | 待领取 | — |
|
||||
| `TASK-account-dialog-inert-20260918.md` | `PROGRESS-account-dialog-inert-20260918.md` | 真机:账户弹窗打开后整个弹窗点不动、退出登录做不了,刷新依旧——`e4e73f56` 把 `SidebarInset` 搬进 layout 后 `inert={modalOpen}` 罩住了没有 portal 的 `AccountDialogOverlay`(BUG-968,P0,代码级确认)。另含 BUG-969:校正「换一件事问」后无下文,服务端已出下一题且快照重算完整,客户端停在开场状态,GET 路由与客户端两端静默,本单只做可观测 + 不静默 + 题干进正文。基线 `1061514f` | 待验收 | `1ace0e64` |
|
||||
| `TASK-first-paint-dead-screen-fallback-20260917.md` | — | 真机:首页永远停在「正在载入账户」,兜底全在没跑起来的 bundle 里(BUG-936 investigating)。根 layout 加与 bundle 无关的内联兜底 + 去掉本仓正则后行断言 | 待领取 | — |
|
||||
| `TASK-consultation-answer-start-anchor-20260917.md` | `PROGRESS-consultation-answer-start-anchor-20260917.md` | 主会话回答落在结尾:`useConversationScrollAnchor` 是贴底跟随,流式期间视口钉在最后一个字,回答开头滚出视口;改为发送后问题钉顶、回答向下长、长出视口显示「跳到最新」、末尾动态留白;产品追加拍板:校正面同一语义(推翻 BUG-041/048 贴底),本轮开头 = 用户行或新助手行。BUG 段 930 起 | 已验收(经修复单) | `worktree/green-harbor-5be3` |
|
||||
| `TASK-consultation-answer-start-anchor-fix-20260917.md` | `PROGRESS-consultation-answer-start-anchor-fix-20260917.md` | 验收修复单:F1 头就是留白行时留白按整视口算(BUG-931);F2 留白只在钉住期间存在(BUG-932);前置:先修 e4e73f56 的两处 TS 错否则门禁不过 | 已验收 | `cc1a8980`(Claude 验收:tsc 0 / lint 0 error / npm test 3457 条 39 红与 11c0028d 逐条一致、新增 2 条绿 / `next build --webpack` 通过、`/` Static、首屏 gzip 591,242(较 09-16 基线 582,800 +1.45%,含会话列表单)/ Chrome 真实布局 S1–S6 全部通过,S6 新助手行距顶 16px 且增高不动,S5 不再写留白);真机六条欠 |
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# 真机清单 · 账户弹窗能点 + 校正快照失败可见(2026-09-18)
|
||||
|
||||
对应 `TASK-account-dialog-inert-20260918.md`、`PROGRESS-account-dialog-inert-20260918.md`、BUG-968 / BUG-969。
|
||||
|
||||
自动化做不到的部分:需要**浏览器 + 已登录账号**。执行环境无 Chrome、无登录态,因此这些是环境缺口,不是「已通过」。
|
||||
|
||||
准备:桌面 Chrome,宽度 ≥ 1024px,已登录。不要用 Esc 作为「弹窗能点」的替代证据。
|
||||
|
||||
## A · 五个账户弹窗都能点(BUG-968)
|
||||
|
||||
对侧栏「个人资料 / 星盘资料 / 通用设置 / 账户与点数 / 退出登录」各做一次:
|
||||
|
||||
1. 点开入口。弹窗出现。
|
||||
2. **期望**:关闭按钮能点,点了弹窗关掉;正文区(聊天或输入框)点不动。
|
||||
3. 再打开。「个人资料」改一个昵称能保存;「退出登录」能点「确认退出」(做到确认即可,不必真退)。
|
||||
4. **不期望**:弹窗出现但里面什么都点不了;只能靠 Esc 关掉。
|
||||
|
||||
开着弹窗时,侧栏本身仍可点(它不在 `SidebarInset` 里)。
|
||||
|
||||
## B · 校正「换一件事问」之后有下一题(BUG-969)
|
||||
|
||||
1. 打开一次生时校正,按开场采集题口述两轮带年月的经历。
|
||||
2. 输入「想不到了」发送。
|
||||
3. **期望**:回复落定后出现下一张选择题卡;右侧盘面不再是开场占位;时间轴出现候选点。正文里可以先看到题干,卡挂上后题干不会写两遍。
|
||||
4. **不期望**:只有「已记录。这题先不计分,换一件事问。」然后空白,输入框占位仍是「再说一件带年月的事」。
|
||||
|
||||
## C · 拔网线后再发一轮,要出现状态文案(BUG-969)
|
||||
|
||||
1. 校正会话进行中,DevTools 打开 Network → Offline,或拔网线。
|
||||
2. 再发一轮经历或点一张卡。
|
||||
3. **期望**:校正面出现「这一问还没读到。」和「重新读取」按钮,不是空白、也不是继续装成采集等待。
|
||||
4. 恢复网络,点「重新读取」。**期望**:快照补上,文案消失。
|
||||
Reference in New Issue
Block a user