QuoteServices Change Status Profile Ready
API:
POST /quote_services/change_status/profile_ready/{quote_service_id}.json功能說明
provider 完成 onboarding 服務資料後呼叫。這支會把 service 設為可接案狀態,並依 start_identity_free_credit_user_id 判斷是否進舊版免費點數流程。
成功 response:
{"error":0,"status":"Success"}快速結論
- 呼叫者:service owner,需有效 REST API key 與 user session token。
- legacy API:
QuoteServicesController::change_status('profile_ready', $quote_service_id)。 - new API:已補
Endpoint/V1/QuoteServices.php::change_status_profile_ready()。 - routing:已補
/quote_services/change_status/profile_ready/{quote_service_id}.json。 - DB 寫入:
quote_services.is_active = 1quote_services.is_archived = 0- 更新
quote_services.modified users.onboard_state = 2- 新增
quote_activities,quote_activity_type_id = 34(ServiceProfileReady)
- 舊版免費點數分支仍保留:
- 可能新增
task_queue.action = newQuoteService - 可能新增
transactions.class = FreeCreditEvent - 可能新增
wallet_balance_logs - 可能新增
user_internal_logs - 可能新增
event_queue.event_key = Pro_Ready
- 可能新增
目前本機 start_identity_free_credit_user_id = 1。常用測試 user 8616 只會啟用 service、設定 onboard;不發免費點數、不排 newQuoteService、不送 Pro_Ready。
前端呼叫鏈:
/dashboard/onboarding/{quote_service_id}
-> OnboardingContainer.nextStep() description step
-> OnboardingContainer.onEndOnboarding()
-> APIManager.markServiceProfileReady()
-> POST /quote_services/change_status/profile_ready/{quote_service_id}.jsonStaging 手動觸發方式
若 provider 已經完成 onboarding,但要在 staging 重新觸發這支 API,最小 DB 準備是把 service owner 的 users.onboard_state 暫時改回未完成狀態,再用該 owner session 操作 onboarding 或直接呼叫 API。
先查 owner:
SELECT qs.id AS quote_service_id, qs.user_id, u.onboard_state
FROM quote_services qs
JOIN users u ON u.id = qs.user_id
WHERE qs.id = {quote_service_id};staging / test 才可暫時調整:
UPDATE users SET onboard_state = 1 WHERE id = {owner_user_id};呼叫成功後預期 users.onboard_state = 2。不要直接改 service owner;API 有 owner guard,必須使用該 service owner 的 session token。
Legacy Rule
legacy controller:
/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Controller/QuoteServicesController.php| legacy 行號 | 職責 |
|---|---|
3452-3467 | change_status($filter, $quote_service_id) 入口;JSON request 且 session 有效時,加上 QuoteService.user_id = current user owner guard。 |
3468-3471 | 預設 response:{"error":1,"status":"Invalid request"}。 |
3497-3499 | profile_ready 分支呼叫 _handle_profile_ready(),activity type 設為 ServiceProfileReady。 |
3501-3508 | type 有效時 save、回 {"error":0,"status":"Success"},並建立 quote service activity。 |
3989-3999 | _handle_profile_ready() 以 Redis key _handle_profile_ready_{user_id} 做 60 秒防重;重複呼叫只記 log 後 return。外層仍回 success 並寫 activity。 |
4003-4010 | 設定 quote_services.is_active = 1、is_archived = 0。 |
4012-4020 | 若 user_id > start_identity_free_credit_user_id,只更新 users.onboard_state = 2 後 return。 |
4024-4037 | 若已領過免費點數,或 wallet balance > 0,只更新 users.onboard_state = 2。 |
4038-4046 | 未領過且 wallet 為 0 時,排 TaskQueue.newQuoteService,取得 quote.free_credit_new_provider 免費點數設定。 |
4048-4068 | 一次性 email domain 不符合資格:free_credit = 0,寫 user_internal_logs。 |
4070-4088 | IP 黑名單不符合資格:free_credit = 0,寫 user_internal_logs。 |
4091-4122 | 補 users.phone,檢查相同電話;不符合資格時 free_credit = 0、寫 user_internal_logs、free_auto_quote = 0。 |
4125-4155 | free_credit > 0 時 lock user、加 wallet、onboard_state = 2、寫 free credit transaction 與 wallet balance log;exception 只記 log。 |
4156-4163 | free_credit <= 0 時只更新 users.onboard_state = 2。 |
4166 | 呼叫 sendProviderReadyToQuoteMail()。 |
legacy provider ready notification:
/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Model/QuoteService.php| legacy 行號 | 職責 |
|---|---|
4931-4964 | 建立 Pro_Ready event payload 基本欄位:user_id、quote_service_id。 |
4966-4971 | legacy email task 220 Ready To Quote Notification 已註解,不會進 event queue。 |
4973-4988 | free_credit > 0 時加入 MoEngage Receive_Free_Credit task。 |
4991-4993 | 寫入 event_queue.event_key = Pro_Ready。 |
New PHP 8.2 對照
| new 檔案行號 | 對應 legacy | 職責 |
|---|---|---|
Lib/Common/RouterRule/Mapping.php:53-56 | access log 實際 path | route 到 QuoteServices::change_status_profile_ready()。 |
Endpoint/V1/QuoteServices.php:135-152 | QuoteServicesController.php:3452-3499 | session/API guard、path id、owner guard、invalid request response。 |
Endpoint/V1/QuoteServices.php:153-157 | 3501-3504, 3989-4173 | 呼叫 QuoteService::handleProfileReady() 處理寫入與通知;再更新 quote_services.modified,對齊 legacy 外層 save($_data)。 |
Endpoint/V1/QuoteServices.php:159-171 | 3505-3508 | 建立 ServiceProfileReady activity,回 success response。 |
Lib/Model/QuoteService.php:94-104 | 3989-3999 | Redis 防重;重複呼叫時 helper return,endpoint 仍會回 success 並寫 activity。 |
Lib/Model/QuoteService.php:106-117 | 4003-4020 | 啟用 service、取消封存;超過 start_identity_free_credit_user_id 時只設 onboard 後 return。 |
Lib/Model/QuoteService.php:119-128, Transaction.php:202-213 | 4024-4037 | 判斷已領免費點數或 wallet balance > 0;符合時只設 onboard。 |
Lib/Model/QuoteService.php:130-137 | 4038-4046 | 排 newQuoteService,讀 free_credit_events,缺 DB event 時 fallback ProConfig::get('quote.free_credit_new_provider')。 |
Lib/Model/QuoteService.php:139-168, 337-344 | 4048-4088 | email domain / IP 資格檢查,寫 user_internal_logs。 |
Lib/Model/QuoteService.php:170-181, 252-293 | 4091-4122 | 補 phone、檢查相同電話、必要時關 free_auto_quote。 |
Lib/Model/QuoteService.php:184-230, FreeCreditEvent.php:21-33 | 4125-4163 | free credit wallet transaction、transactions、wallet_balance_logs、onboard fallback。 |
Lib/Model/QuoteService.php:296-334 | 4931-4993 | 寫 Pro_Ready event;free_credit > 0 時加入 Receive_Free_Credit MoEngage task。MoEngage first_name 照 legacy 使用 last_name . first_name。 |
Config / DB 設定檢查
切 staging / production 前要確認實際部署環境,不可只看本地 legacy checkout:
| key / table | 用途 | new 讀取位置 | 備註 |
|---|---|---|---|
start_identity_free_credit_user_id | 決定是否跳過舊版 profile ready 免費點數流程 | ConstantUtil::get('start_identity_free_credit_user_id') | user id 大於此值時只設 onboard,不排 queue / event。 |
free_credit_events.slug = quote.free_credit_new_provider | 免費點數金額與 event id | FreeCreditEvent::getEventBySlug(..., true) | 優先使用 DB event。 |
quote.free_credit_new_provider | DB event 不存在時的免費點數 fallback | ProConfig::get('quote.free_credit_new_provider') | 本機 Configuration.php 目前未見此 key;部署環境需確認。 |
legacy sendProviderReadyToQuoteMail() 會建立但不送出的 email replace content 讀到:
site.language
site.url
credit.info.url
email.signature
mail.icon.vendor_tips因 legacy email task 已註解,new 目前不讀這些 key;若日後恢復 220 Ready To Quote Notification email task,需同步補齊並驗證這些 config。
測試
docker exec -w /project-data cd63f9147e8d ./vendor/bin/phpunit tests/QuoteServicesChangeStatusProfileReadyTest.php結果:
OK (2 tests, 22 assertions)測試覆蓋:
- owner 可將自己的 service 標記 profile ready。
- 在目前
start_identity_free_credit_user_id = 1分支下,成功後is_active = 1、is_archived = 0、更新quote_services.modified、users.onboard_state = 2。 - 成功後建立
ServiceProfileReadyactivity。 - 此分支不新增
newQuoteServicetask、Pro_Readyevent、free credit transaction、wallet balance log。 - 非 owner 回 legacy invalid request,不寫 DB / queue / event。
測試會快照並還原 user 8616 的 wallet / onboard / phone 等欄位,避免污染共用測試使用者。
Staging 實測
2026-06-05 以 legacy staging 驗證:
POST /quote_services/change_status/profile_ready/9930.jsonresponse:
{"error":0,"status":"Success"}DB 結果:
quote_services.id = 9930:user_id = 8617、is_active = 1、is_archived = 0、modified = 2026-06-05 07:24:25。users.id = 8617:onboard_state = 2、available_wallet_amount = 4441。- 新增
quote_activities.id = 406809:quote_activity_type_id = 34、model = QuoteService、foreign_id = 9930。 - 未新增
task_queue.action = newQuoteService。 - 未新增
event_queue.event_key = Pro_Ready。 - 未新增
transactions.class = FreeCreditEvent;最近 wallet log 仍停在 2026-06-01,這次呼叫沒有改 wallet。