WorkBuddy
04b07b5821
fix(privacy): updatePrivacySettings 改 upsert —— 同一用户第二次更新不再撞 user_id 主键
user_privacy_settings 的主键自 V002 起就是 user_id,旧实现无论记录是否存在都无条件 insert,
导致同一用户第二次更新必然 DuplicateKeyException → 500,隐私设置从此再也改不动。
现改为「存在则按 user_id 更新,不存在才插入」。
更新条件刻意用 user_id 而非实体 id:id 是 V037 为「实体↔表对齐」后补的独立列,
不作为寻址依据 —— 否则历史行 id 缺失时更新会静默失效。
已知边界(未擅自处理):findByUserId 带 deleted_at IS NULL,若将来引入软删路径,
已软删的行会让本方法走插入分支并撞主键。当前不存在任何软删隐私设置的路径,故不可达;
若将来新增软删,需同步改为 PG ON CONFLICT (user_id) DO UPDATE。已在代码注释中标注。
test(privacy): PrivacySettingsUpsertGuardTest —— 4 用例,全走真实落库(H2),不用 mock 断言调用次数
① 连续更新两次:第二次不得抛异常 + 库中仍只有 1 行(防退化成重复插入,
那会让 findByUserId 的 Optional 返回值抛 TooManyResultsException)
② 部分更新不得把未提交字段重置回默认值
③ 首次更新未提交字段取默认 true
④ 无记录时读取返回全 true 且不落库(固化既有契约)
负向注入已验证:退回无条件 insert → 恰 2 红,失败原因即 DuplicateKeyException;
另 2 个只更新一次的用例正确未红(走不到该分支)。已还原并复跑全绿。
docs(plan): Task 3.1 拆两层并记录进展;附 B 增第 13 项;基线 681→685
⚠️ 关键发现(附 B-13):隐私设置有两套实现,前端走的是桩那一套 ——
小程序 pages/privacy-settings 调 /account/privacy-settings(AccountLifecycleService 桩,不落库),
管理端对隐私端点零调用。故本次修复位于「前端尚未触达」的路径:必要但当前用户不可感知。
真正的用户可见故障是「改隐私设置根本不保存」(桩),属 Task 3.1 上层,仍待契约裁定。
本次修复是该上层工作的必要前置 —— 桩一旦接到 PrivacyService 立刻会撞上此缺陷。
方法论:评估「某修复的价值」必须先确认前端实际调用哪条路径 ——
本项目同业务存在 /me/* 与 /account/* 多套并存端点,后端有真实实现 ≠ 用户能走到。
2026-09-19 15:49:54 +08:00
..
2026-09-18 16:37:47 +08:00
2026-09-18 20:25:58 +08:00
2026-09-18 21:15:29 +08:00
2026-09-16 14:37:44 +08:00
2026-09-14 11:44:02 +08:00
2026-09-09 22:05:00 +08:00
2026-09-09 22:05:00 +08:00
2026-09-19 15:49:54 +08:00
2026-09-13 22:09:15 +08:00
2026-09-17 23:25:31 +08:00
2026-09-16 14:37:44 +08:00
2026-09-09 22:05:00 +08:00
2026-09-18 16:37:47 +08:00
2026-09-19 11:45:27 +08:00
2026-09-09 22:05:00 +08:00
2026-09-15 22:29:26 +08:00
2026-09-18 21:15:29 +08:00
2026-09-18 21:34:33 +08:00
2026-09-10 10:58:43 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 14:37:44 +08:00
2026-09-14 10:01:41 +08:00
2026-09-14 10:01:41 +08:00
2026-09-16 12:54:39 +08:00
2026-09-16 15:11:38 +08:00
2026-09-16 16:42:48 +08:00
2026-09-16 21:00:52 +08:00
2026-09-16 21:50:56 +08:00
2026-09-16 23:01:13 +08:00
2026-09-17 00:01:53 +08:00
2026-09-18 21:34:33 +08:00
2026-09-17 01:25:12 +08:00
2026-09-17 14:02:00 +08:00
2026-09-17 15:07:52 +08:00
2026-09-17 16:47:10 +08:00
2026-09-17 20:42:09 +08:00
2026-09-17 21:07:25 +08:00
2026-09-17 22:25:10 +08:00
2026-09-17 23:25:31 +08:00
2026-09-18 10:12:34 +08:00
2026-09-18 21:58:58 +08:00
2026-09-18 11:49:18 +08:00
2026-09-18 13:50:19 +08:00
2026-09-18 21:58:58 +08:00
2026-09-19 11:40:38 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 12:54:39 +08:00
2026-09-16 14:37:44 +08:00
2026-09-09 22:05:00 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 14:37:44 +08:00
2026-09-19 11:45:27 +08:00
2026-09-16 14:37:44 +08:00
2026-09-16 14:37:44 +08:00
2026-09-18 16:40:09 +08:00
2026-09-18 21:58:58 +08:00