记忆:把 .workbuddy/memory 纳入版本控制
用户要求这份记忆跟着仓库走,而不是只留在本机。 .gitignore 里挡路的是 `.workbuddy/`。改成反忽略六行,并且**只放行 .md**: 别用 `!.workbuddy/memory/**`——它会把 memory 下任何文件都放行,本项目真发生过 `web.test.exe` 混进暂存。复核用 `git check-ignore -q --no-index` 逐条打靶: memory/*.png、memory/sub/x.md、memory/MEMORY.md.bak、plans/a.md 全 IGNORED, 17 个 .md 全 included;`git add -An .workbuddy/` 恰好 16 个文件。 其余 .workbuddy 内容(计划、本地设置、临时产物)继续忽略。记忆里没有真凭据 (唯一命中是 2026-09-14.md 里的 `password=rond-admin`,那是项目默认口令)。 顺带做两件整理: 1. 取证了注入上限。以前按「字节数」判断 MEMORY.md 是否超限是错的: WorkBuddy 的 `getWorkingMemoryContent()` 用 `MAX_MEMORY_CHARS = 1e4` 比 JS `content.length`,即**字符数**(中文 1 字算 1);超了 substring 截断、尾部静默丢失。 本 details 与每日日志都不参与注入,只有 MEMORY.md 受约束。 现已从 6604 字符收到上限的 66%,并把这条上限写进索引抬头。 2. 把「备份合并」「导出/恢复三条铁律」两段长文迁进 MEMORY-details.md 的卅一/卅二节, 索引只留关键词指针。行尾统一为 LF(仓库 .gitattributes 是 `* text=auto eol=lf`)。
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# 2026-09-28
|
||||
|
||||
## rondbackup「差异分析 → 合并执行」实测(真机导出包 20260928_183908)
|
||||
|
||||
环境 `conf/app.ini`(库 `rond_with_you`、`data_dir=storage/data`、:8080),数据集 id=9;
|
||||
把真机新导出的 `data/20260928_183908.rondbackup`(955 到访 / 432 地点)合并进已有 867 到访的数据集。
|
||||
|
||||
**主链路生效**(真跑路由 + 站长登录):`POST /admin/preview` → `GET 差异页` → `POST /admin/preview/{token}/merge`,
|
||||
`add_new=1`、冲突留默认 ⇒ 新增 70 地点 / 1 活动 / 134 到访,随到访带入 24 位移 / 32 天气;
|
||||
到访 867→1001、地点 368→438、位移 791→815、天气 557→589;**孤儿位移 0、无地点到访 0、重复 UUID 0 组**。
|
||||
逐条核对:备份里 953 条带 UUID 的到访全部命中且**到达时间微秒级零误差**;站内 2 条 app 已删的 UUID 到访被正确保留。
|
||||
合并后 12 个关键页全 200。报告:`storage/.mergetest/报告-rondbackup合并实测-20260928.md`
|
||||
|
||||
**三个问题**
|
||||
1. 🟠 同名同坐标的重复地点**不幂等**:`DiffPlaces` 的 `byCoord`/`byName` 是单槽位 map + `used[]`,
|
||||
同一坐标下 N 条备份地点最多只能配 2 条 ⇒ 第 3 条永远判「备份新增」,每次合并多插一条。
|
||||
实测备份里同名同坐标共 10 组、只有「柳州站」count=3 ⇒ **每次合并固定多 1 个重复地点**,差异永不归零
|
||||
(438→439→…)。修法:多值 map 逐条消费 + `mergePlaces` INSERT 前按 `PlaceCoordKey` 去重兜底。
|
||||
2. 🟠 到访冲突被「活动改名」放大:`visitFieldChanges` 比的是**活动名称**不是身份;16 个活动改名
|
||||
(餐厅→吃饭…)⇒ 355 条到访冲突全部同因(库内挂在改名活动下的 378 条 − 站内独有 23 条 = 355,精确吻合),
|
||||
活动类型本身只报 16 条。且对到访选「用实机」**不会**改活动名(`activity_id` 按 UUID 映射回同一个)
|
||||
⇒ 冲突永不收敛。修法:到访层面按活动身份(`ZUID_`/id)比对,改名只在活动层报一次。
|
||||
3. 🟡 21 个**长沙**地点两边坐标差 661~748m,实测 20 条满足「站内坐标 == 反纠偏(备份坐标)」
|
||||
⇒ 坐标系不一致(站内那侧被多做了一次 GCJ→WGS 反向换算);**差异页冲突的默认选项是「用实机」**,
|
||||
直接点合并会把这批坐标覆盖、地图上跳 ~660m。另有 分类 12 处(站内中文标签 vs 备份 `MKPOICategory*` 原始枚举)。
|
||||
|
||||
**备份 / 回滚**:`storage/.mergetest/rond_with_you-before-20260928.sql`(整库 pg_dump);
|
||||
差异页快照 `diff-before-merge.html` / `diff-after-merge.html`。库内最终状态 = 合并一次(我重复跑测试
|
||||
多插的 1 个重复地点已回退)。
|
||||
|
||||
**方法(可复用)**:临时 Go 测试(`package web`,才能拿到非导出的 `srv.captcha`)——
|
||||
`httptest.NewServer(srv.Handler())` + cookie jar + **`CheckRedirect: http.ErrUseLastResponse`**
|
||||
(站点用 303,必须关掉自动跟随才能读到 Location);验证码答案直接读 `captcha.Store.Answer(id)`,
|
||||
绕开图像识别;管理员口令是默认 `rond-admin`(pbkdf2 可离线核对)。跑完删掉测试文件,`git status` 保持干净。
|
||||
|
||||
## 同日晚:修复 + 复测(回档数据库后重跑)
|
||||
|
||||
按上面前两条问题改了代码,**5 个文件 +172/−22**:
|
||||
|
||||
1. `internal/rond/diff.go` `DiffPlaces`:`byCoord`/`byName` 由单槽位 map 改为**多值索引**(`map[string][]StoredPlace`),
|
||||
抽出 `take()` 逐条认领未使用的候选(认领即置 `used`)。`classify` 不再自己置 used。
|
||||
2. `internal/rond/diff.go` `visitFieldChanges`:到访的「活动」改为**按身份**比(新增参数 `actUUID`),
|
||||
两边都缺 UUID 才退回名称;`DiffVisits` 传入 `b.ActivityUUID`。`StoredVisit` 新增 `ActivityUUID`。
|
||||
3. `internal/web/backup_diff.go` `loadStoredVisits`:多 JOIN 一次 `entity_raw`(`entity='ZACTIVITY'`,按 `a.src_pk`)取 `ZUID_`。
|
||||
|
||||
**复测结果**(回档 → 重跑同一份备份,同环境):到访冲突 **253 → 6**(247 条活动改名假冲突消失);
|
||||
地点新增 **70 → 67**,合并后再比对 **地点新增 1 → 0**;再点合并由「再插 1 个重复地点」变成
|
||||
「**按当前的选择没有要写入的改动,数据未变**」,地点 435→435、「柳州站」稳定 3 条。
|
||||
到访 1001 / 位移 815 / 天气 589 与修复前一致;953 条 UUID 到访全命中、到达时间 0 偏差、孤儿位移 0。
|
||||
|
||||
**新增守护**:`TestDiffPlacesAlignsDuplicateNameCoordGroups`(含「站内真少两条仍报新增 2」反向断言)、
|
||||
`TestDiffVisitsIgnoresActivityRename`、`TestDiffVisitsReportsActivityChange`、
|
||||
`TestDiffVisitsActivityWithoutUUIDFallsBackToName`;`TestBackupDiffIdentical` 补地点新增断言、
|
||||
两个 merge 幂等用例补「地点差异归零」。**变异验证**:把两处改回旧逻辑,对应用例确实全挂
|
||||
(⚠️ 变异要忠于旧行为:旧 `byCoord` 是 map「后者覆盖前者」=取最后一条;我第一次写成「取第一条」,
|
||||
误报 8 条,与真实旧行为不符,改用 `byCoord[k] = []StoredPlace{sp}` + `byName` 只留第一条才复现出正确的 1 条)。
|
||||
|
||||
**仍未动**:21~24 个长沙地点坐标系差 ~660m(默认「用实机」会覆盖站内;现连带 25 条到访「地点」冲突)、
|
||||
分类 12 处中文标签 vs `MKPOICategory*` 枚举、16 个活动改名需选「用实机」才同步。
|
||||
报告已更新为「实测 → 修复 → 复测」完整版。
|
||||
|
||||
## 收尾:回滚 + 推送 + 重建(19:35)
|
||||
|
||||
- **回滚**:`DROP/CREATE rond_with_you` + 恢复 `storage/.mergetest/rond_with_you-before-20260928.sql`,
|
||||
核对回到合并前基线 867 到访 / 368 地点 / 31 活动 / 791 位移 / 557 天气 / 2538 留档 / 柳州站 3。
|
||||
- **推送**:提交 `10d23e0`(5 文件 +172/−22),`git push origin master`(远端 `git.shiroko.one`)。
|
||||
本地原本就**领先远端 8 个提交**,一并推上去了(`78865fc..10d23e0`)。
|
||||
⚠️ **推送凭据陷阱**:`~/.git-credentials`(store)与 GCM 里缓存的 token **都已失效**
|
||||
(`remote: Failed to authenticate user`),SSH 22 端口 `Network is unreachable`(只有 HTTP 代理
|
||||
`http.proxy=http://100.104.48.63:11882` 能通)。**别加 `GIT_TERMINAL_PROMPT=0`**——它会让 GCM
|
||||
直接放弃认证;去掉这个变量、让 GCM 自己走一遍交互认证即可成功(13 秒完成)。
|
||||
- **重建**:`go build -o bin/rond.exe .`(`bin/rond.exe` 原本还是 9-20 的旧构建,不含修复;
|
||||
旧文件留了副本 `bin/rond.exe.bak-20260920`)。只读冒烟:`/healthz` `/` `/admin/login` 均 200、
|
||||
`/admin` 303,随后 `taskkill //F //IM rond.exe` 停掉、8080 释放,库内计数不变。
|
||||
- 注意:`go build` 那次 `bin/rond.exe~`(9-20 12:14 的更旧副本)不见了;原因未查明,
|
||||
两个都是修复前的旧产物,无实际损失。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user