Commit Graph
5 Commits
Author SHA1 Message Date
tamakyi 6ff6f944a1 换基线:把「底座换代」做进后台(站点数据一行不动)
导出是「底座为底 + 只覆盖托管表」,所以底座必须是手机导出的包。底座跟着数据集走,
手机重新导出后想换代,以前只能整包重新导入成新数据集(站点补录的行、主题、备注都得重收拾)。
新动作 /admin/baseline(后台首页加入口)就是给同一份数据的底座换代用的。

三道闸,顺序不能挪:
1. 重合判据:新包里的到访 UUID 与站点侧带 UUID 的到访比。一条都对不上直接拒
   (连 force 也不给过)——干跑只验结构,一份不相干的包照样导得出,但换下去站点
   每行都在新底座里认不出身份,全按新行插到最大编号之后,真机上就是「这些到访
   全变成新的」。重合率不到一半要显式确认;判据没过不当场报错了事:包已经收进
   uploads,页面给一个「我确认,强制替换」按钮,不必重传几十 MB。
2. 干跑导出:底座缺表/缺实体编号在这步挡住,不会出现「换完了才发现导不出、
   原来那份已经不知去哪」。
3. 旧底座留档 + 记档,换错了可一键回滚。

两个坑:
- 留档名不能只用秒级时间戳。「替换后紧接着回滚」落在同一秒时,回滚那次 rename 会把
  刚生成的留档覆盖掉,于是回滚回了个寂寞(TestRollbackBaselineRestoresPrevious 当场红)。
  改用 baselineBackupName():20060102-150405 + 冲突自增。
- ensureBaseline 必须先看记档。只认 datasets.sha256(= 最初那份包)的话,底座一丢就静默
  重建回旧包,上一次换基线白做且毫无提示。抽出 ensureBaselineTo(ctx, dsID, dst) 共用;
  「重建」入口写临时文件再 rename,不做破坏性删除。

回归用例 7 条(internal/web/baseline_swap_test.go):成功路径断言「换底座前后导出包里
ZVISIT 的 UUID 集合逐条一致」——编号会换、身份不该换,谁在底座里没对上立刻亮;
记档优先重建带反证(清掉记档后同一条路必须走不通);部分重合需确认、完全对不上 force
也不给过、非包文件第一步就挡住、回滚还原且当前那份也留档、页面渲染到底。

验收:./scripts/verify.sh 全量 PASS=318 FAIL=0 SKIP=0。
2026-09-30 19:00:18 +08:00
tamakyi 0e670aa1cf 文档:补「重复到访」两类成因(站点侧副本 / 补录行被合并回来) 2026-09-30 16:58:59 +08:00
tamakyi 881f2933ff 收尾:验收脚本自动清死元组、城市圈首末到访按可见到访算、补使用说明
verify.sh:测试库 ≥ VACUUM_MIN_MB(默认 200MB)时先 VACUUM (ANALYZE)——一轮全量会留几百 MB
死元组,级联删除随之变慢(同一夹具用例实测 13.6s → 10.2s)。只用普通 VACUUM:FULL 要
ACCESS EXCLUSIVE 锁,有别的服务连着测试库时会把验收整段卡住。

/api/cities 的首末到访改成按可见到访的到达时间算(内层 min/max(v.arrival)),不再取
places.first/last_visit_at——那两列是全量的,会被已并入 / 子段的到访推早推晚。

README 补两节:「数据编辑页上的重复到访」(判定口径与清理范围)、「为什么有些到访在页面上看不到」
(已并入 / 子段不计入显示与统计,但导出必须原样带着),并在开发提示里记下验收环境的死元组与
is_active 两个坑。

回归:city_agg_test.go 补了一段能区分的断言——把某地点最晚那次到访标成已并入后,城市最近到访
必须从 09-13 退到 09-08(原先只比对同口径时,两种算法在夹具数据上结果一样,是条假绿的断言)。
2026-09-29 23:49:39 +08:00
tamakyi f8e1076296 delete useless readme 2026-09-18 15:49:54 +08:00
tamakyi b327bc1230 first release 2026-09-18 13:05:49 +08:00