fix(onboarding): atomic DB append for step completion (deferred bug L3)
markOnboardingStepDone read space_members.onboarding_progress, appended the step id in JS, and wrote the whole jsonb object back — a lost-update race where two near-simultaneous completions (double-submit, or two steps ticked quickly) both read the same base array and the second write clobbered the first, silently dropping a step. Replace it with mark_onboarding_step_done (migration 055): a single atomic UPDATE that dedup-appends the step id into onboarding_progress.completed_step_ids under the row lock — no update can be lost (READ COMMITTED re-evaluates the jsonb expression against the latest tuple via EvalPlanQual), other keys are preserved, and re-appending an existing id is a no-op. Ownership-guarded by auth.uid() so a caller can only complete steps on their own membership row; the no-JWT service path is trusted and scoped by p_member_id (mirrors class_signup_tx et al.). integration/onboarding-progress.test.ts covers dedup/idempotency, key preservation, the auth.uid ownership gate, and the point of the fix: 12 concurrent completions all survive. Migration 055 folded into schema.sql; types/database.ts regenerated. typecheck 0 · lint 0 errors · 645 unit · 58 integration · build ok
This commit is contained in:
@@ -3462,6 +3462,10 @@ export type Database = {
|
||||
}
|
||||
expire_proposals: { Args: never; Returns: number }
|
||||
get_user_space_ids: { Args: { uid: string }; Returns: string[] }
|
||||
mark_onboarding_step_done: {
|
||||
Args: { p_member_id: string; p_step_id: string }
|
||||
Returns: Json
|
||||
}
|
||||
members_with_permission: {
|
||||
Args: { perm: string; sid: string }
|
||||
Returns: {
|
||||
|
||||
Reference in New Issue
Block a user