防复发:把「删数据集带走站点自建数据」做成结构性门禁 + 常驻体检
用户放弃继续救那批旧图,要求的是「别再发生同类事件」。所以不靠记性,靠结构:
1) 归属铁律(写进 schema.sql 抬头 + README 新章节)
判断标准只有一句:**这份记录能不能从备份重新导入?**
能(places/visits/movements/weather/activities/tags/entity_raw)⇒ 可挂
`REFERENCES datasets(id) ON DELETE CASCADE`;
不能(place_images/place_notes/place_votes/topics)⇒ 只留 dataset_id 当出处、**不许挂外键**。
2) 两道门禁(dataset_ownership_test.go),都做了变异验证:
- 运行时:查 pg_constraint,凡挂 datasets 的表必须在白名单里;**反向也查**
(白名单里的表不许被顺手摘掉,否则删数据集会留成片孤儿行)。
- 静态:扫 schema.sql 的 CREATE TABLE。只看运行时有盲点——新建的库走 CREATE TABLE,
开发库可能压根没跑过那次迁移。变异(把 topics 的 CASCADE 补回去)当场红。
- 变异验证顺带发现:扫描必须先跳过 `--` 注释行,规矩的说明文字里就写着
`REFERENCES datasets(id)`,不跳过会把自己写的文档当成违规。
- 还发现运行时那道单独看**不够**:夹具每次跑迁移,迁移自己就把坏外键摘了,
它永远不会在不健康的库上报警 ⇒ 补了「注入事故原样的外键再跑迁移,断言被摘掉」
的自愈用例(并先确认变异真的生效,防假绿)。
3) 常驻体检:后台首页显示「库里 N 张 / 本地盘上 M 个 / 落单 K 个」,落单 >0 直接报警。
事故的本质不是「删数据集」本身,而是**行与对象悄悄对不上、没人发现**,等照片看不见了才追。
自愈用例又抓出一个此前漏掉的缺口:place_notes / place_votes 上的同类外键迁移并不会摘
(原先只写了 place_images 与 topics 两句 DROP)⇒ 补成五张自建数据表全覆盖。
⚠️ 排序坑(本项目第二次踩):摘外键那段最初放在 place_images 建表**之前**,
开发库毫无症状、**全新库起不来**(ALTER 报「关系不存在」),被
TestFreshDatabaseServesAppQueries 抓住。整段已挪到 place_images 之后,并把坑写进注释。
顺带订正「删除数据集」的二次确认文案(专题改完之后它还在说专题会一起删)。
全量验收 PASS=336 FAIL=0 SKIP=0。
This commit is contained in:
@@ -152,6 +152,26 @@ go build -o rond .
|
||||
- 换过的底座记档在 `datasets.baseline_name/baseline_sha256`:底座文件丢了会**按记档重建**,
|
||||
而不是退回最初那份旧包(否则上一次换基线会静默失效)。
|
||||
|
||||
## 数据归属(删掉一份数据集会带走什么)
|
||||
|
||||
一条铁律:**从备份导入的数据随数据集删除;站点自建的数据不随数据集删除。**
|
||||
|
||||
| 会随数据集删掉 | 不随数据集删掉 |
|
||||
|---|---|
|
||||
| 到访、地点、位移、天气、活动、标签、原始行留档<br>(重新上传同一份备份就能再导回来) | 备注、结论、地点图片、专题 |
|
||||
|
||||
判断标准很简单:**这份记录能不能从备份重新导入?** 能 ⇒ 挂 `dataset_id … ON DELETE CASCADE`;
|
||||
不能 ⇒ 只留 `dataset_id` 当出处、**不许挂外键**。图片那次事故就是反过来的:行被级联删了、
|
||||
文件却留在盘上,而读取是按坐标键跨数据集的——两套口径打架,删数据集就等于永久丢失。
|
||||
|
||||
这条规矩有两道门禁守着,改坏当场红(不用靠记性):
|
||||
- 运行时:查 `pg_constraint`,凡是挂 `datasets` 的表必须在白名单里(`TestOnlyBackupDerivedTablesCascadeFromDatasets`)
|
||||
- 静态:直接扫 `schema.sql` 的 `CREATE TABLE`(`TestSchemaDeclaresNoDatasetFKForUserData`)——
|
||||
只看运行时有个盲点:新建的库走的是 CREATE TABLE,开发库可能压根没跑过那次迁移。
|
||||
|
||||
另外**图片挂载体检**常驻后台首页(库里 N 张 / 本地盘上 M 个 / 落单 K 个):
|
||||
行与对象对不上时会直接报警,不必等到照片看不见了才追。
|
||||
|
||||
## 地点图片
|
||||
|
||||
- **字节在浏览器里转成 WebP** 再上传,服务端只做形状校验、不重新编码(1 核机器扛不住解码大图)。
|
||||
|
||||
Reference in New Issue
Block a user