QuoteBids Edit
對應 legacy API:
POST /quote_bids/edit/{quote_bid_id}.json快速結論
- 功能:provider 在案件列表 / 報價卡片切換
provider_tag,目前 web-app 實際只用於標記 / 取消favorite。 - HTTP path:
POST /quote_bids/edit/{quote_bid_id}.json - legacy 入口:
QuoteBidsController::edit($id) - new 入口:
Endpoint/V1/QuoteBids.php::edit() - 正式機流量:2026-05-28 查到
POST200 合計16569筆,另有OPTIONS200 合計918筆。 - 搬移狀態:new action 已存在;2026-05-29 補齊 legacy response、
provider_tag寫入語意與 PHPUnit。
正式機 Access Log
機器:ip-10-5-2-242
查詢範圍:
/var/log/apache2/get-lancer_access.log
/var/log/apache2/get-lancer_access.log.1
/var/log/apache2/get-lancer_access.log.*.gz候選 API 正規化後結果:
| API | 筆數 |
|---|---|
POST /quote_bids/edit/{quote_bid_id}.json 200 | 16569 |
OPTIONS /quote_bids/edit/{quote_bid_id}.json 200 | 918 |
GET /quote_bids/consumer_want_to_see_more_quote/{quote_request_id}/page:{page}/limit:{limit}.json 200 | 1630 |
POST /quote_bids/provider_request_review/{quote_bid_id}.json 200 | 957 |
判斷:edit 是這批未完整 audit 的 quote_bids API 中流量最高者,優先處理。
Web-App 呼叫
/Users/mattsu/Documents/Site/web-app/modules/utils/api-manager.js:2337-2352
markTagWithBidId(bid_id, tag)
-> POST /quote_bids/edit/{bid_id}.json
-> FormData provider_tag = tag
-> success condition: data.message == 'Success'目前 web-app 送出的 provider_tag 來源:
| 檔案 | 行為 |
|---|---|
MatchItem.js:109-126 | provider_tag 空值時送 favorite,否則送空字串。 |
QuoteRequestSheet.js:187-199 | provider_tag 空值時送 favorite,否則送空字串。 |
CasesContainer.js:180-182 | match 後直接送 favorite。 |
結論:目前 web-app 只會送 favorite 或空字串。Activity.js 有處理其他 tag 的顯示 fallback,但不是送出來源。
Legacy 規則
QuoteBidsController::edit($id):
| legacy 行號 | 規則 |
|---|---|
5086-5087 | 預設 response:error=1, message=Invalid request。 |
5088-5089 | 必須是 JSON request 且 API session valid;成功後從 session 取 provider user id。 |
5092-5098 | 用 quote_bid_id + provider_user_id 找 bid,並 contain QuoteRequest。 |
5099 | bid 存在且 request data isset(provider_tag) 才進入成功流程;只檢查參數存在且非 null,不限制值。 |
5100-5101 | 直接更新 quote_bids.provider_tag = request provider_tag。空字串會寫空字串,不是 NULL。 |
5102 | 建立 UpdateQuoteBid activity,param1 = json_encode(request data)。 |
5103 | 呼叫 setMyWorkUnreadCount(provider_user_id, [bid => ['t' => archived ? 'a' : 'd', 'c' => 0]])。 |
5104-5105 | 成功 response:{"error":0,"message":"Success"}。 |
5106-5108 | 找不到 bid 或沒有 provider_tag:{"error":3,"message":"Not found"}。 |
5110-5112 | session invalid:{"error":2,"message":"Invalid session"}。 |
新舊程式對照
| New PHP 8.2 | 對應 legacy | 狀態 |
|---|---|---|
Endpoint/V1/QuoteBids.php:3533-3540 | QuoteBidsController.php:5088-5089, 5110-5112 | 已對齊 invalid session response:error=2, message=Invalid session。 |
Endpoint/V1/QuoteBids.php:3542-3547 | QuoteBidsController.php:5099 | 已對齊:從 path 取 quote_bid_id,且只要求 isset(provider_tag)。 |
Endpoint/V1/QuoteBids.php:3549-3567 | QuoteBidsController.php:5092-5099, 5106-5108 | 已對齊 not found response:error=3, message=Not found。 |
Endpoint/V1/QuoteBids.php:3574-3578 | QuoteBidsController.php:5100-5101 | 已對齊:寫入原始 provider_tag 字串;空字串維持空字串,不轉 NULL。 |
Endpoint/V1/QuoteBids.php:3580 | QuoteBidsController.php:5103 | 已對齊 unread count 更新。 |
Endpoint/V1/QuoteBids.php:3583-3591 | QuoteBidsController.php:5102 | 已對齊:建立 UpdateQuoteBid activity,param1 使用 request data JSON;若 request row 缺失,requestor_user_id 以 null 寫入,避免 PHP 8.2 warning 中斷流程。 |
Endpoint/V1/QuoteBids.php:3593-3596 | QuoteBidsController.php:5104-5105, 5114 | 已對齊:成功回 {"error":0,"message":"Success"}。 |
2026-05-29 Staging 觀察
使用目前 staging 呼叫:
POST https://api-staging.pro360.com.tw/quote_bids/edit/2147689479.json
provider_tag=favorite部署前 response:
{"error":0,"message":"success"}這不是 QuoteBids::edit() action 自己回的 response。修正前的 new action 執行完沒有呼叫 $this->json();RouterV3::dispatch() 在 action 正常結束後會補預設 response:
$endpoint->json([
'error' => 0,
'message' => 'success',
]);所以小寫 success 來自 new framework fallback,不是 legacy 行為。這和 legacy / web-app 期待的 Success 大小寫不一致;web-app markTagWithBidId() 是用 data.message == 'Success' 判斷成功。新程式已改為 action 內明確回 Success,避免依賴 framework 預設成功訊息。
PHPUnit
測試檔:
tests/QuoteBidsEditTest.php覆蓋:
| 測試 | 規則 |
|---|---|
testProviderCanMarkBidAsFavorite | provider_tag=favorite 成功、DB 更新、建立 UpdateQuoteBid activity。 |
testProviderCanClearTagWithBlankString | 空字串可清除 tag,DB 寫空字串,activity param 保留 provider_tag:""。 |
testLegacyAllowsNonFavoriteProviderTagValue | legacy 只檢查參數存在,不限制 tag 值。 |
testMissingQuoteRequestStillUpdatesBidLikeLegacy | bid 存在但 request row 缺失時仍更新 tag,activity requestor_user_id = NULL。 |
testMissingProviderTagReturnsNotFoundLikeLegacy | 沒帶 provider_tag 回 error=3, message=Not found。 |
testNullProviderTagReturnsNotFoundLikeLegacyIssetCheck | provider_tag = null 依 legacy isset 規則視為沒帶。 |
testOtherProviderCannotEditBid | 非 bid owner 回 error=3, message=Not found。 |
testInvalidSessionReturnsLegacyResponse | session invalid 回 error=2, message=Invalid session。 |
執行結果:
vendor/bin/phpunit tests/QuoteBidsEditTest.php
OK (8 tests, 33 assertions)待回填
- 新 code 部署後,用 staging 重打同一種
provider_tag=favoritecurl,確認 response 變為{"error":0,"message":"Success"},並回查 DBquote_bids.provider_tag與UpdateQuoteBidactivity。