来源:
notes/documents/渠道开关实施记录:ticket_01_重跑与事件线闸门切换.md渠道开关实施记录:ticket 01 重跑与事件线闸门切换
结论:渠道开关这条线正式开工。ticket 01 重跑(收回被 revert 的 schema 与回填),ticket 02 把事件线四处闸门从
sensitivity换成feishu_base_enabled。两个验收项都实测通过:logs/daily_log.md逐字节不变、三目的地 dry-run 全绿。偏离 ticket 文本一处(网页日线是删闸门、不是换开关),已记录待确认。
来源:调研 note_10e5f94acdbd45c5、字段梳理 note_41fb5cfa22d34bed、方案与改造清单 note_908871bab2cc4fb0。
一、为什么先做完渠道开关,再动 SQLite
用户 2026-09-26 的决定是:SQLite 不再出现在代码里,历史数据挪进归档目录(仍在个人助理仓库内)。这等于选定了调研里的方案 B 全搬,而不是只搬台账。
但顺序上先做完 sensitivity 更省:
- 开关集就是要搬过去的目标形状。先搬存储,等于按一个马上要删的字段设计新库,紧接着再改一次 schema、再定一次回填。
- 回填的基线量在现在这层地基上,而且 ticket 01 的实测回填已经落在库里,只有地基不动它才成立。
- 184 个 Python 单测、
calendar_parity_report.py、Base 与日历的行数对照全都读 SQLite。先搬存储,这些对照要全部重造,ticket 08「不许差不多」就落不了地。 - 回滚代价不对称:sensitivity 可 git revert 加重跑迁移;去 SQLite 动的是事实源本身。
二、ticket 01 重跑(commit eafd243)
背景:9c3db02 曾按当时的用户决策把 ticket 01 的代码整体回滚,只保留库里的列与回填,并把库的 schema 标记改回 3——形成「库比代码新」的状态。
做法:
- 收回
58ed7f2的scripts/event_store.py,与那一版逐字节一致。 - 不手工改标记,让真库走它自己的升级路径:
note_registry_schema_version3 → 4,_backfill_channel_switches()重跑一次。 - 重跑的实际效果只有一条:revert 期间新增的 note_908871bab2cc4fb0 的
publish_enabled0 → 1。符合回填口径——博客两条管道都没有闸门,它已经在博客上。 - 其余数字不变:notes 130 条,events 无
publish_enabled=0。
实测:单测全过;跑测试不改真库(前后 md5 一致);sync_daily_log_outputs --dry-run 三目的地 {succeeded: 3, failed: 0}。迁移前备份在 /tmp/dbcompare/pre-migration-20260926-174847.sqlite3。
三、ticket 02:事件线读点换掉(commit 46befea)
- Base 三处闸门(
sync_to_feishu_base.py的行构建、V2 投影、旧版投影)与note_base_projection.py::_event_rows:sensitivity == "private"改成not event.feishu_base_enabled;台账error文案从private event改成feishu_base_enabled=0。 daily_log_view.py删掉[敏感记录已隐藏]分支,本地日视图永远渲染全文。capture_event.py不再从publish_enabled推导 sensitivity,改为接收feishu_base_enabled(默认 1,CLI 加--no-feishu-base)。project-calendar-entries.mjs的kept at home与台账error两处文案不再提 private / sensitivity。
偏离 ticket 文本一处:web/scripts/lib/daily-projection.mjs 的日线没有改成读 feishu_base_enabled,而是把那道闸门删掉(只留 status === 'active')。理由:取合规则只该有一份、写在 calendar_entries 视图里(calendar_entries.py 的注释本身就写着飞书日历与网页是这份定义的兄弟投影),网页日程的开关是 calendar_enabled,视图已经实现;换成 Base 开关会让「关掉飞书 Base」经 planDeletions 静默删掉网页上的日历条目。两种改法今天的结果完全一致(视图 406 条里,active 的 private 日线是 0 条)。已记进 ticket 02 的 Comments 与 Answer,不认可可在那里回滚。
四、code-review 抓到的两件事
- sensitivity 不能落默认值。 原本只删推导,新事件会落到
create_event的默认'private';而migrate_daily_log_to_sqlite.py:67拿existing.sensitivity == "internal"当幂等判据,被打破会让老 Markdown 迁移把已有事件当「变了」重写。现在capture_event写常量internal,并加了断言钉住。 - 文档措辞夸大。 新注释说这个文件不做筛选,但它仍筛
status === 'active'——那是这一行一直有的闸门。已改准。
五、验收实测
- 验收项「
logs/daily_log.md改动前后逐字节一致」:同一份真库分别跑 HEAD 版与改动版的render_daily_log_markdown,两版都是 38647 字符且相等;磁盘文件等于新渲染,且不含[敏感记录已隐藏]。 - Python 187 用例、web 62 用例全绿,eslint 干净。
sync_daily_log_outputs --dry-run:三目的地{succeeded: 3, failed: 0};Base 事件线 299 条全部skipped,网页投影 406 条 up to date、kept at home: 0。
六、遗留与下一步
- 未做:ticket 03 笔记线开关、04 Base 列改造与退出语义、05 博客闸门、06 Web 与 Neon 列切换、07 剥离 sensitivity、08 观测对照。
- ticket 06 的阻塞说明已过时:它写「本机没有
web/.env.local」,实际现在有且DATABASE_URL已配(本地预览用 4199 端口实测成功)。做 06 时直接跑迁移即可。 - 去 SQLite 的四个根问题待答:事件事实源换成什么、断网是否必须能记、禁令是否覆盖测试与一次性脚本、归档目录里只放二进制还是也导出可读格式。(「两台机器要不要继续靠 commit 同步 SQLite」已由用户决策为不要。)
- 一个观察:
/note在 17:51 那条事件只提交了logs/daily_log.md,没带上data/daily_log.sqlite3。这条缺口正是去 SQLite 要解决的问题;本次实施记录提交时把它一并带上。