fix(account): grant service_role ayanamsa for new-user profile saves (BUG-600)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9302,3 +9302,19 @@
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-600 | 新用户保存账户资料返回 `PATCH /api/account` 500
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-09
|
||||
- 最近更新:2026-09-09
|
||||
- 影响面:`PATCH /api/account`、staging 自托管 PostgreSQL、首次称呼/出生资料保存
|
||||
- 用户现象:新账号登录后保存称呼或出生资料,接口返回 `500 {"error":"暂时无法保存账户资料"}`。
|
||||
- 触发条件:self-hosted 新用户已有 trigger 创建的 `profiles` 行,前端 `persistProfile` 提交默认 `ayanamsa`。
|
||||
- 根因:`20260903010000_profile_ayanamsa.sql` 只把 `ayanamsa` 的 `UPDATE` 授给 `authenticated`。账户 PATCH 走 `service_role`;PostgreSQL 对未授权列返回 `42501 permission denied for table profiles`。该错误不含 `column`,现有缺列回退不会去掉 `ayanamsa`,因此首次保存直接 500。无档案 INSERT 不受影响,所以已有 trigger 建档的新用户会踩中。
|
||||
- 修复:新增迁移为 `service_role` 补齐 `ayanamsa` 的列级 `SELECT / INSERT / UPDATE`。
|
||||
- 验证:本地 PostgreSQL 在补授权前,含 `ayanamsa` 的 `service_role` UPDATE 返回 `42501`,去掉该列后 UPDATE 成功;补授权后含 `ayanamsa` 的 UPDATE 返回一行。`frontend/tests/profile-persistence.test.ts` 锁定新旧迁移的授权差。
|
||||
- 防复发:账户 PATCH 新增列必须同时授予 `authenticated` 自助保存和 `service_role` 并发读写;缺列回退不得把 table 级 `42501` 当成可忽略的缺列。
|
||||
- 相关记录:BUG-039、BUG-005
|
||||
- 复发自:BUG-039(全球地点列漏授 service_role 的同类权限缺口)
|
||||
- 修复版本:迁移 `20260909010000`,待发布
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
begin;
|
||||
|
||||
-- BUG-600: account PATCH uses service_role. The ayanamsa column only granted
|
||||
-- UPDATE to authenticated, so the first onboarding save (which always sends
|
||||
-- ayanamsa) failed with "permission denied for table profiles".
|
||||
grant select (ayanamsa) on table public.profiles to service_role;
|
||||
grant insert (ayanamsa) on table public.profiles to service_role;
|
||||
grant update (ayanamsa) on table public.profiles to service_role;
|
||||
|
||||
commit;
|
||||
@@ -141,3 +141,24 @@ test("declared birth windows persist as start and end clocks with service-role g
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("service role can persist ayanamsa during account profile upserts", () => {
|
||||
const original = readFileSync(
|
||||
new URL("../supabase/migrations/20260903010000_profile_ayanamsa.sql", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const repair = readFileSync(
|
||||
new URL(
|
||||
"../supabase/migrations/20260909010000_profile_ayanamsa_service_role_grants.sql",
|
||||
import.meta.url,
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
assert.match(original, /grant update \(ayanamsa\) on table public\.profiles to authenticated/);
|
||||
assert.doesNotMatch(original, /to service_role/);
|
||||
assert.match(repair, /grant select \(\s*ayanamsa\s*\) on table public\.profiles to service_role/i);
|
||||
assert.match(repair, /grant insert \(\s*ayanamsa\s*\) on table public\.profiles to service_role/i);
|
||||
assert.match(repair, /grant update \(\s*ayanamsa\s*\) on table public\.profiles to service_role/i);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user