给别人出报告能读到档案,对话和报告标明 AI 生成

BUG-1063:后台按列只读档案,授权前数据库拒绝读表,授权后通过。对话输入框下和报告标题下加上 AI 生成说明。状态板按已部署提交改措辞,不标 resolved。下载文件元数据没有做。

自测:tsc 退出码 0;lint 0 error;定向测试 51 通过;test:db 82 项里 13 项为 Windows 已知失败,无新增;隐私标记退出码 0。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-14 09:30:51 +08:00
co-authored by Grok (agent loop)
parent f4c53e7f9f
commit fca62fda43
16 changed files with 376 additions and 39 deletions
+2 -2
View File
@@ -339,11 +339,11 @@ Radii have two visual steps. Controls use 8px (`--radius-md`; `--radius-xs` and
### Input and composer
- **Structure:** a column, not a row — warm canvas field on top, the composer's own bottom row beneath it. The row carries the model picker on the left and the send/stop control on the right, with the character count inline beside it.
- **No strip below the composer.** `.composer-footer` used to sit under the field at a permanent `min-height: 44px`, holding the model picker and a count that only appears near the cap — so most of the time it was 44px of empty chrome on every screen. The row is inside the box now and only renders what it has.
- **No tool strip below the composer.** `.composer-footer` used to sit under the field at a permanent `min-height: 44px`, holding the model picker and a count that only appears near the cap — so most of the time it was 44px of empty chrome on every screen. The row is inside the box now and only renders what it has. A single line of copy (`.composer-ai-notice`, 2026-10-14) sits under the box: it is not a tool row, has no 44px slot, and on a narrow screen it stays one line and ellipsizes instead of wrapping over the send control.
- **States:** default, hover, focus with deep-brown ring, disabled only for structural reasons (readonly, session loading, onboarding, the other surface open, **a rectification session whose surface is not yet open**), invalid. Generating does not disable the textarea; the send control becomes stop. On a rectification session the ordinary composer is only a disabled field with placeholder「正在打开生时校正…」; if opening failed, a「重新打开生时校正」button sits above it. No spinner.
- **Queue:** one pending card (`.composer-queue`) sits above the field while an answer is in flight. Copy: “已排队,回答结束后发出”, plus the text and a 44px “撤回”. A second Enter appends to the same card with a newline. Successful settlement sends it; stop, failure, or recovery puts the text back in the field. The send button is disabled while a card is waiting. No spinner.
- **Accessibility:** persistent label where practical; composer has an explicit accessible label.
- **One composer:** the rectification surface renders the same `ChatComposer` as the main chat; there is no second composer. A surface that owns its own draft passes it as `value`; the main chat reads the draft store. Both count down from the same 500-character ceiling through `CharacterRemaining`, which the composer renders inline and only once `characterRemainingVisible()` is true — it no longer has a permanent container. Controls that belong to the composer go through the `toolbar` slot; nothing is stacked below it.
- **One composer:** the rectification surface renders the same `ChatComposer` as the main chat; there is no second composer. A surface that owns its own draft passes it as `value`; the main chat reads the draft store. Both count down from the same 500-character ceiling through `CharacterRemaining`, which the composer renders inline and only once `characterRemainingVisible()` is true — it no longer has a permanent container. Controls that belong to the composer go through the `toolbar` slot. The only thing under the box is the one-line AI notice, not another control.
- **Inner field corners:** the textarea inside `.composer` has `border-radius: 0`. Rounding stays on the outer `.composer` only. The field has no horizontal padding, so a radius on the textarea itself clips the first glyph's left edge (BUG-1311).
### Answer start anchor