users_delete
文件狀態:已對 legacy / 已對 new API,staging full diff 待補
最後驗證:2026-07-02
來源:legacy UsersController::delete() / User::deleteUserSafety()、new Endpoint/V1/Users::delete()、web-app DeleteAccount
目的
整理使用者在帳號設定按下「刪除帳號」後,前端、API、DB、activity、queue 與外部同步會發生什麼。
這支流程不是單純登出,也不是物理刪掉所有 DB row。它比較接近:
停用帳號
-> 釋出 email / phone
-> 歸檔使用者相關服務與案件
-> 清除登入 session
-> 發 downstream erase / deactivate event不回答什麼
- 不列
users全欄位定義。 - 不提供正式帳號復原 SOP;刪帳應視為不可逆。
- 不記錄單次測試 user id、session token 或 queue id。
- 不重寫 MoEngage / Sumsub / Life55688 的完整外部規格。
入口
| 項目 | 內容 |
|---|---|
| 前端頁面 | /dashboard/settings/deactivate |
| 前端 component | web-app/modules/components/dashboard/account/DeleteAccount.js |
| 前端 API method | APImanager.deleteUserAccount() |
| API | POST /users/delete.json |
| Auth | valid API key + valid user session |
| Body | 無必要欄位 |
| Legacy | UsersController::delete() -> User::deleteUserSafety($user_id, $user_id) |
| New API | Endpoint/V1/Users::delete() |
| Success response | {"status":"success","error":0} |
| Invalid session response | {"error":1,"status":"Invalid request"} |
使用者看到的行為
- 使用者進入帳號設定的刪除帳號 tab。
- 點「刪除帳號」後出現確認 modal。
- 按確認後,前端送
POST /users/delete.json。 - API 成功回
{"status":"success","error":0}。 - 前端執行
auth.logout()。 - 前端導回首頁
/。
注意:前端目前在 API 回傳 JSON 後會執行 logout 與導回首頁;fetch/http exception 才會停在錯誤 modal。
主流程
POST /users/delete.json
-> 驗 API key 與 user session
-> 取得 session user id
-> users row FOR UPDATE
-> 更新 users 刪帳欄位
-> archive quote_services
-> close/archive quote_requests
-> 寫 request / bid / user activities
-> 刪 api_sessions
-> Life55688 delete event(有 life_55688_id 才送)
-> nshop items delete + ES delete
-> task_event_queue
-> event_queue Delete_User
-> response success成功 Side Effect
users
刪帳會更新 legacy 明確指定的欄位:
| 欄位 | 行為 |
|---|---|
is_active | 設 0 |
email | 若不是 DEL{timestamp}_ 開頭,改成 DEL{time()}_{old_email} |
phone | 改成 DEL{time()}_{old_phone} |
facebook_user_id / facebook_access_token | 清成 NULL |
google_user_id / google_access_token | 清成 NULL |
apple_user_id | 清成 NULL |
life_55688_id | 清成 NULL,但通知 Life55688 時用清除前的舊值 |
is_apple_connected / is_facebook_connected / is_google_connected | 設 0 |
is_phone_confirmed | 設 0 |
email / phone 加 DEL{timestamp}_ 的目的,是讓原本 email / phone 之後可以重新註冊,不會撞唯一值或登入查詢。
Session
刪除該 user 的所有 api_sessions:
DELETE FROM api_sessions WHERE user_id = <user_id>效果是所有裝置的登入 session 都失效。
專家服務
該 user 名下所有 quote_services 都會被歸檔:
quote_services.is_active = 0
quote_services.is_archived = 1legacy 沒有加 active / archived guard,所以 new 也不應自行加。
案件與報價
該 user 未 archived 的 quote_requests 會被 close + archive:
quote_requests.is_closed = 1
quote_requests.is_archived = 1每個被處理的 request 會寫:
CloseRequestArchiveRequest
request 底下 quote_status_id IN (InProgress, Hired) 的 bids 會寫:
QuoteBidClosed
同時會清 provider 的 my work unread,避免刪帳後還殘留待讀狀態。
User Activity
會寫一筆 DeleteUser activity。
本 API 是 self-delete path,legacy DB 實際資料顯示 param1 為 (self),new 也對齊寫 (self)。
Nshop
該 user 所有 nshop_items:
- 非 deleted 的 item 設為 deleted。
- 每筆呼叫 ES delete。
- ES / nshop delete 例外只寫 log,不 rollback 主流程。
Queue / Event
會寫 task_event_queue:
| event_key | payload 重點 |
|---|---|
moengage_erase_user | user_id、移除 DEL{timestamp}_ prefix 後的 email |
sumsub_deactivate_user | user_id |
會寫 event_queue:
| event_key | payload 重點 |
|---|---|
Delete_User | user_id、quote_service_id = null、Admin User Delete email task |
若刪除前 users.life_55688_id 非空,會送 Life55688 delete user event。
不會動的東西
刪帳流程不會更新下列資料;不要因為看起來合理就補 side effect:
passwordmobile_app_hash- wallet / payment 金額,例如
available_wallet_amount - card / debt 相關欄位
- counters,例如
quote_service_count、quote_request_count、quote_bid_sent_count user_profiles的姓名、電話、avatar、identity- notification settings
- subscription / package / auto refill 設定
復原與重新註冊
這支 API 沒有直接復原 API,也不是 reversible toggle。
一般使用者情境應視為重新註冊:
- 舊 user 會停用。
- 原 email / phone 因為被加上
DEL{timestamp}_prefix,理論上可再次註冊。 - 重新註冊會產生新的 user id。
- 舊服務、案件、對話與 activity 不會自動回到新帳號。
工程救援只能算手動 DB rescue,而且需要知道刪除前狀態或有 DB snapshot。不能只把 users.is_active = 1 改回來,還要處理:
- email / phone prefix
- social account 綁定已清掉
api_sessions已刪quote_services已 archivequote_requests已 close/archivenshop_items已 deleted- MoEngage / Sumsub / Life55688 queue 可能已被 worker 或外部系統處理
因此正式情境不要把刪帳當成可復原操作。
第一輪排查
- 查 API response 是否成功。
- 查
users:
SELECT
id,
email,
phone,
is_active,
is_phone_confirmed,
google_user_id,
facebook_user_id,
apple_user_id,
life_55688_id
FROM users
WHERE id = <user_id>;- 查 session 是否清掉:
SELECT id, user_id, device_id, expires
FROM api_sessions
WHERE user_id = <user_id>
ORDER BY id DESC;- 查服務與案件:
SELECT id, is_active, is_archived
FROM quote_services
WHERE user_id = <user_id>
ORDER BY id DESC;
SELECT id, is_closed, is_archived
FROM quote_requests
WHERE user_id = <user_id>
ORDER BY id DESC;- 查 activity:
SELECT id, quote_activity_type_id, user_id, param1, created
FROM quote_activities
WHERE user_id = <user_id>
ORDER BY id DESC
LIMIT 50;- 查 downstream queue 或 queue log:
task_event_queue / task_event_queue_log:
- moengage_erase_user
- sumsub_deactivate_user
event_queue / event_queue_log_1..4:
- Delete_User