收尾:验收脚本自动清死元组、城市圈首末到访按可见到访算、补使用说明

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(原先只比对同口径时,两种算法在夹具数据上结果一样,是条假绿的断言)。
This commit is contained in:
tamakyi
2026-09-29 23:49:39 +08:00
parent 3d03aae018
commit 881f2933ff
4 changed files with 144 additions and 3 deletions
+27
View File
@@ -33,6 +33,28 @@
| 设置 | 站点标题与头像、主题色、主页模块开关、访客可见页面、访客可见区域、隐家/隐工作、图片存储、默认底图 |
| 账号 | 改密码、两步验证(TOTP) |
### 数据编辑页上的「重复到访」
站点里可能残留**历史副本**:同样一次到访存了两份,差别只在 UUID(站点侧生成的那份,
在手机包里找不到)。合并与差异页都是按 UUID 认人的,于是它们会被当成「备份新增」,
导出到 rond 后就是成对的两条。
判定以**这份数据集的基线(导入时留下的手机包)**为参照:到访的 UUID 在基线里找不到、
而基线里有一条「到达时间 + 地点」完全相同的,判为副本。卡片只在检出时出现在数据编辑页,
默认全选 + 二次确认;清理会连它的位移 / 天气 / 留档一起删,并把指向它的合并标记改指到保留项
(不动就会在导出时留下悬空引用)。基线不可用或与本站一条都对不上时,卡片只给说明、不给按钮。
命令行也有一条等价的工具:`tools/dedup_site_visits.py`(默认只预演,加 `--apply` 才动手)。
### 为什么有些到访在页面上看不到
手机包里有两种「不独立成立」的到访:被别的到访**并入**了的(`ZVISIT.ZMERGEDTO`),
以及某个长驻记录下的**子段**(`ZVISIT.ZPARENT`)。rond 自己既不显示、也不把它们算进次数与停留,
本站因此也不算——时间线、统计、地点计数、地图城市圈都不含它们。
⚠️ 这些行**不删**:导出包必须原样带着它们,rond 要靠它们认这次合并发生过。
数据编辑页会照常列出,并打上「已并入 #562 / 子段 #374」,方便核对。
## 技术栈
| 层 | 选型 |
@@ -304,3 +326,8 @@ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o ron
- 时间、坐标这类「原样回贴」的字段有讲究:表单精度(分钟 / 6 位小数)往往低于库里真值,
保存时若与库里已有值落在同一精度上要沿用库里那份,否则只改个备注也会把时间或坐标悄悄改掉。
- `tools/verify_rondbackup.py` 可以做导入→导出→逐表对账,检查改动有没有破坏备份保真度。
- 全量验收 `scripts/verify.sh`(要 **0 FAIL / 0 SKIP**)。每个夹具都会导入一整包再删掉,
一轮下来测试库能留几百 MB 死元组,级联删除随之变慢(实测 16MB 时约 6 分钟跑完、
几百 MB 时半小时都跑不完,看着像卡死)。脚本会在库超过 `VACUUM_MIN_MB`(默认 200MB)
时先清一次死元组;手动来一次 `VACUUM (FULL, ANALYZE)` 还能把文件也缩回去。
另外要确认库里有生效数据集(`datasets.is_active`),否则 `internal/stats` 的对照用例会假 skip。