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
前端 componentweb-app/modules/components/dashboard/account/DeleteAccount.js
前端 API methodAPImanager.deleteUserAccount()
APIPOST /users/delete.json
Authvalid API key + valid user session
Body無必要欄位
LegacyUsersController::delete() -> User::deleteUserSafety($user_id, $user_id)
New APIEndpoint/V1/Users::delete()
Success response{"status":"success","error":0}
Invalid session response{"error":1,"status":"Invalid request"}

使用者看到的行為

  1. 使用者進入帳號設定的刪除帳號 tab。
  2. 點「刪除帳號」後出現確認 modal。
  3. 按確認後,前端送 POST /users/delete.json
  4. API 成功回 {"status":"success","error":0}
  5. 前端執行 auth.logout()
  6. 前端導回首頁 /

注意:前端目前在 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_active0
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_connected0
is_phone_confirmed0

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 = 1

legacy 沒有加 active / archived guard,所以 new 也不應自行加。

案件與報價

該 user 未 archived 的 quote_requests 會被 close + archive:

quote_requests.is_closed = 1
quote_requests.is_archived = 1

每個被處理的 request 會寫:

  • CloseRequest
  • ArchiveRequest

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_keypayload 重點
moengage_erase_useruser_id、移除 DEL{timestamp}_ prefix 後的 email
sumsub_deactivate_useruser_id

會寫 event_queue

event_keypayload 重點
Delete_Useruser_idquote_service_id = nullAdmin User Delete email task

若刪除前 users.life_55688_id 非空,會送 Life55688 delete user event。

不會動的東西

刪帳流程不會更新下列資料;不要因為看起來合理就補 side effect:

  • password
  • mobile_app_hash
  • wallet / payment 金額,例如 available_wallet_amount
  • card / debt 相關欄位
  • counters,例如 quote_service_countquote_request_countquote_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 已 archive
  • quote_requests 已 close/archive
  • nshop_items 已 deleted
  • MoEngage / Sumsub / Life55688 queue 可能已被 worker 或外部系統處理

因此正式情境不要把刪帳當成可復原操作。

第一輪排查

  1. 查 API response 是否成功。
  2. 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>;
  1. 查 session 是否清掉:
SELECT id, user_id, device_id, expires
FROM api_sessions
WHERE user_id = <user_id>
ORDER BY id DESC;
  1. 查服務與案件:
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;
  1. 查 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;
  1. 查 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

相關文件