来源:notes/documents/网页版多模块改版需求入口.md

网页版多模块改版:需求入口(给下一个会话)

这份文档是什么

下一个会话的第一个输入。目的不是把需求写完,是让人(或 agent)读完就能开一轮 /grill-with-docs,把下面 D1–D13 那些细节问定,然后走 /to-spec/to-tickets

需求本体不在这里,在设计文档 网页版多模块设计:外壳契约、页边档号与日程模块note_ce68034f2e624b83)。本文只做四件事:把已经定死的不再议的东西列出来、把待定的细节 编号、把新范围(daily_log)的现状摆清楚、把「怎么在本地看到界面」写下来。

2026-09-22 这一轮已走完(grill → spec → tickets → implement → code-review):D1–D13 全部按建议采纳(日程另追加 Q1–Q6),产出在 .scratch/web-multimodule-shell/——spec.md(39 条用户故事)与 issues/0112(01–11 编号即依赖序,12 是补开的笔记图片通道); ADR 0009(外壳契约)/ 0010(查询参数路由)/ 0011(日程走 Neon 投影)。下方 D3 与「不做的事」 里被 ADR-0011 取代的两处已就地改掉,其余条目作为决策记录保留。 实现结果见文末第 4、5 条: 12 张 ticket 全部 resolved 并附验证;06 / 07 的真机部分 2026-09-22 补齐(cd67238)。

前置文档(各管一段,别混)

文档 note_id 管什么
网页版多模块设计:外壳契约、页边档号与日程模块 note_ce68034f2e624b83 需求来源:外壳契约、四个模块、色彩、字体、度量、砍掉的默认款
网页版笔记面体检报告 note_27ad578ece424daa 改造前的证据:108 篇正文泄漏 front matter、亮色 1:1、956px 度量
网页版前端首轮体检与优化实施计划 note_204a244f983d41a3 哪里坏了怎么修。P0 已完成(dac8324),P1–P5 待做
网页版前端装备六个 agent skill note_f1443e6b49b24075 这一轮能用的六个前端 skill 与它们的缺口

已经定死、不要再议的

  • 外壳四层:脊(模块,64px)→ 索引(300px)→ 页(左侧 72px 页边 gutter)→ 档号。 任何新模块只允许替换「索引」和「页」两处,外壳、导航位置不动。
  • 四个模块:笔记 / 日程 / 任务 / 材料与来源。第三、第四是任务与材料,已定。
  • 色彩:五个角色两套值,默认素纸,系统偏好暗色时整组换夜纸。这条已经落地 (P0,提交 dac8324),不要在改造里重新发明颜色。
  • 字体:正文与标题用宋体但只限阅读页;索引、月历、任务行、档号一律黑体; 先不引中文 web font,靠系统栈回落;正文最小 17px。
  • 度量:正文 17px / 1.9、一行 34 个汉字(约 640px);h1 32 / h2 24 / h3 19 / 元数据 13 / 档号 12;数字用 tabular-nums
  • 砍掉的默认款(照单删):卡片套件与统一阴影、每张卡片的 hover 过渡与入场淡入、 path · 大小 · 日期 中缀元数据、「小字号加字距的灰色标签」、大数字加小标签的统计头、 小数据用等宽字体、渐变。
  • 质量底线:正文 ≥12:1、淡墨 ≥5:1、靛青 ≥4.5:1、朱砂只做非文字记号 ≥3:1; 键盘焦点环两种主题下都要保住。
  • 窄屏(<900px):脊变底部固定条,索引变页顶抽屉(默认只显示当前项), 页边 gutter 降级成正文上方一行档号。

现在长什么样

P0 之后的笔记面(本地夹具实拍,亮色):结构还是「左侧一个列表 + 右侧一篇正文」, 颜色已经是定版的那五个角色,字体与度量还没动。

当前的笔记面(P0 之后的亮色)

新范围:把 daily_log 接进 web(日程模块)

设计文档里日程模块只给了形态(月历定位 + 当日流水),没给数据怎么进 web。现状事实先摆清楚:

  • 权威数据是 data/daily_log.sqlite3events 表:285 条、覆盖 87 天, 从 2025-11-18 到 2026-09-20;一天最多 18 条(2025-11-27)。
  • 只有 16 条有结束时间;duration_minuteslocation 全空——所以周视图时间网格是错的。
  • 285 条 sensitivity 全是 internalstatus 全是 active;正文平均 86 字、最长 3045 字。
  • 类型分布:life 206、reflection 30、note 25、investment 16、task 6、meeting 2。
  • note_reference 字段 285 条全空:设计里那条「note 类事件指向当天写下的笔记」的桥, 现在没有任何数据支撑,要单独定义怎么建。
  • web 侧目前只有笔记一条线:web/scripts/generate-notes.mjs 在构建期扫 notes/, 产出 web/generated/notes.json(7.85 MiB / 156 篇),日程没有任何代码。

沿用设计里的硬约束:事件表是权威源,web 是只读派生;不在 web 里编辑。

待定细节(grill 的 frontier,每条都带我的建议)

  • D1 路由形态。 设计说「路由形态不动」,但现在根本没有路由——选中一篇笔记只是 React state,刷新就回列表。多模块要不要真 URL?建议:要,用查询参数(?m=daily&date=2026-09-22), 不引路由库,先保证刷新、收藏、浏览器回退可用。
  • D2 模块与选中态记不记忆。 建议全部进 URL,不落 localStorage(一个人用,分享与回退更有价值)。
  • D3 daily_log 怎么进 web。 建议沿用笔记那条路:构建期从 SQLite 生成 events.json 已改(ADR-0011):日程要走 Neon 数据库投影。理由是日程更新频繁,写进构建产物意味着 每次都要重新构建部署,写数据库只插一行。本地 SQLite 仍是权威源,Neon 是第三投影, 由 scripts/sync_daily_log_outputs.py 分钟级同步(只投 active 且非 private)。 「列表带不带正文」照旧:列表不带、点开当天再取。
  • D4 时间口径。 occurred_at+08:00。月历按哪个时区切天?凌晨 00:29 那条算前一天还是当天? 建议一律按 Asia/Shanghai 的本地日期,并在文档里写明。
  • D5 life 要不要默认出现在流水里。 设计只定了「默认不上色」。建议全量都在(日志删了就不是日志), 只是不给记号。
  • D6 事件到笔记的桥怎么建。 建议第一期不做,明确推迟;要做的话先定「往 SQLite 写回 note_reference」还是「构建脚本按日期匹配」,这两条路的代价完全不同。
  • D7 任务模块怎么读 tasks/ 三个手写 md(todo.md 有 High Priority 小标题、 in_progress.md 1 条、done.md 67 条)。建议同样构建期解析成 tasks.json, 字段就四个加一条状态时间线,已完成默认折叠。
  • D8 材料模块的体量与门。 notes/sources/ 原始文件 120 MB(PDF/EPUB/MOBI), 25 个全文 md、最大的 1.67 MiB,其中 5.5 MB 已经进了构建产物。建议:原始二进制永不进产物; 全文按期拆分、按需加载;索引里把「材料」和「我的解读」用档号区分开。
  • D9 搜索的作用域。 现在只搜笔记的标题/路径/正文。加了日程与材料之后搜什么? 建议第一期仍只搜笔记;材料全文要不要进索引,单独一条决定。
  • D10 淡墨的 4.93 对设计写的 5:1。 实测 #5C6B78 落在素纸上是 4.93:1(AA 的 4.5 已过)。 建议改阈值到 4.5,或把色值压深一档——要你拍。
  • D11 当前项的记号。 设计写「朱砂墨点」,P0 落的是 3px 左规(近似)。 建议按点重做,并把 .note-item 的 hover 过渡删掉(设计明说删)。
  • D12 改造分期。 建议第一期把外壳 + 笔记模块做完(日程/任务/材料都要复用外壳), 再按模块逐个加;一次铺四个模块会没法验收。
  • D13 与实施计划 P1 的关系。 P1 要拆的 #root max-width / 居中 正好是外壳要替换掉的那层。 建议把 P1 合进外壳改造,别单独做一个马上要拆的中间态。

怎么在本地看到界面、怎么截图(已跑通)

笔记面与日程面都在 GitHub OAuth 之后,会话是服务端不透明 token(sessions.token_hash 才对得上), 所以不能用真登录态。(Vercel 上 21 个 Neon 变量全是 Hidden/Secret、vercel env pull 只写回 [SENSITIVE] 占位;连接串改由 Neon CLI 走 API key 拉取,见第 5 条。这只解决写库,不解决登录态。)

用的是本地夹具,四步:

  1. cd web && npm run build —— 会先跑 notes:generate,再 tsc -bvite build, 产物在 web/frontend/dist/web/generated/ 是 gitignore 的,新克隆必须跑这一步)。
  2. 一个约 40 行的 node 脚本,绑 127.0.0.1:4173 起静态服务(服务 frontend/dist), /api/*真实的 backend/src/lib/notes.ts(用 node --experimental-strip-types 直接 import),NOTES_DATA_FILE 指向 web/generated/notes.json 这份真产物;只伪造 /api/me 的身份与鉴权守门 (固定返回 {authenticated:true,user:{displayName:'andy'}}), /api/notes/api/notes/search/api/notes/detail 全是真 handler。
  3. 截图与量测用 Playwright(chromium.launch(),默认无头)。要看 console 就挂 page.on('console')
  4. 生产侧走代理:chromium.launch({ proxy: { server: 'http://127.0.0.1:7890' } }), 或 curl -x http://127.0.0.1:7890。本机直连 *.vercel.app 是 DNS 污染(返回 000)。 生产域名 https://vite-react-tawny-one-14.vercel.app,push main 会自动部署,约 20 秒落地。

用它的结论必须写清偏差:登录态是伪造的,任何关于鉴权、会话、OAuth 回跳的结论都不成立; 渲染、布局、对比度、交互这类结论才有效。

这个夹具是一次性 QA 工具,没进仓库(截图与脚本都在 /tmp)。要让下一个会话直接复用, 最省事的做法是把它固化成 web/scripts/local-preview.mjs 并在 web/docs/operations.md 里写一段—— 这件事本身也可以是一个 ticket。

能用的 skill(新会话要一起考虑)

三个来源,别混:

  • mattpocock 那套(工作区以插件加载,路由是 /ask-matt):负责流程——grill、spec、tickets、 implement、code-review。
  • 六个前端 skillweb/.agents/skills/,详表在 web/docs/frontend-skills.md):负责执行—— frontend-testing-debugging(改完渲染验证的纪律)+ webapp-testing(Playwright 工具)是这一轮 真正会用到的;外壳审美若还要再定方向用 frontend-design;要重新审一遍界面用 audit
  • 仓库自己的personal-assistant-webneonneon-postgres

已知缺口,照做别踩:本机没有 Browser 插件frontend-testing-debuggingfrontend-app-builder 会回退到 Playwright,按规矩要在报告里记录回退原因; frontend-app-builder 需要能出图的概念模型,而本机的 key 是 DeepSeek、出不了 gpt-image-*, 要用它得先解决出图;react-best-practices 出身 Next.js,只取 rerender-client-rendering-js- 四类;装与升级这些 skill 必须带代理。

不做的事

  • 不在 web 里编辑内容、不做多用户、不引 UI 框架 / 路由库 / 组件库。
  • 不把 notes/logs/tasks/ 搬进数据库或函数包:一律构建期产物。例外是 daily_log: 事件表按 ADR-0011 投影进 Neon(理由见 D3)。
  • 不改 Vercel 项目名与 OAuth 回调,不动部署方式。
  • 不改 notes/ 下笔记的写法。

下一个会话的第一步(已执行,留作记录)

  1. 用户会先敲 /ask-matt —— 已做:/grill-with-docs(写了 ADR 0009 / 0010 / 0011)→ /to-spec/to-tickets,每一步都已 commit + push。
  2. 把 D1–D13 当一轮的 frontier 问完 —— 已做:全部采纳推荐答案,日程改数据库后另问 Q1–Q6。
  3. 需要「先看看」才能定的走 /prototype —— 已做:外壳与四张月历变体都出了原型图 (.scratch/web-multimodule-shell/assets/),月历定为 C 变体
  4. /implement/code-review —— 已做(2026-09-22):12 张 ticket 里 01–05、08–12 共 10 张 resolved,每张的 ## Answer 都有提交号与实测证据(c0e3e30ccfd8b9);两轴 code-review (Standards / Spec 各一个只读子代理)的报告与逐条处置在 .scratch/web-multimodule-shell/code-review.md
  5. 把 Neon 连接串放进 web/.env.local,补跑迁移与首次投影 —— 已做(2026-09-22):连接串用 Neon CLI 的 API key 路径拉取(neon env pull --env DATABASE_URL --file web/.env.local), npm run daily:migratenpm run daily:project 真机跑完——285 条事件全部落地, 2026-06 是 78 条 / 19 天、06-04 是 16 条,两个命令各连跑两次都是零变更;首跑暴露的一条畸形 时间戳(历史 bug 写出的 end 时间)已修;随后按文档做「truncate + 全量重灌」又暴露第二条—— --truncate 没清本地投影台账,表空了却一条都不发(日历静默变空),已修(06d0dbf); 两条都与真失败退出码的实测(用 SQLite 副本,权威库不动)一起记在 .scratch/web-multimodule-shell/issues/0607。 剩下只有一件要你定:「搜索是不是每个模块都能用」——本期搜索只搜笔记,搜索框因此只长在笔记索引头里。