QuoteServices External Review Link

API:

GET /quote_services/external_review/link/{quote_service_id}.json

功能說明

provider 進入服務資料編輯頁時呼叫,用來預先取得服務評價邀請連結。前端可見入口是「服務評價」;點進該編輯內容後,內部標題顯示為「推薦」。前端呼叫鏈是 ServicesContainer.displayServiceWithIndex()serviceActions.getExternalReviewLink()APIManager.getExternalReviewLink()

成功 response:

{"error":0,"message":"Success","short_url":"..."}

正式機流量

2026-06-04 查正式機 access log:

4433 GET     /quote_services/external_review/link/{quote_service_id}.json 200
3568 OPTIONS /quote_services/external_review/link/{quote_service_id}.json 200
 125 POST    /quote_services/external_review/submit.json 200
  82 OPTIONS /quote_services/external_review/submit.json 200

本文件只涵蓋 link。同一組 legacy external_review 分支的 invite / submit 已拆成獨立文件處理。

已確認操作路徑

2026-06-04 staging 實測:

  1. provider 進入 /dashboard/profiles/
  2. 點選新增專家檔案。
  3. 前端進入 /dashboard/profiles/{quote_service_id}/0
  4. 進入服務資料編輯頁時觸發 GET /quote_services/external_review/link/{quote_service_id}.json

legacy response 範例:

{"error":0,"message":"Success","short_url":"https://p36.net/sw/NlkXw"}

快速結論

  • actor:service owner,需有效 REST API key 與 user session token。
  • legacy API:QuoteServicesController::external_review('link', $quote_service_id)
  • new API:已補 Endpoint/V1/QuoteServices.php::external_review_link()
  • routing:已補 /quote_services/external_review/link/{quote_service_id}.json
  • response:
    • 無有效 session:{"error":1,"message":"Invalid session"}
    • service 不屬於 session user:{"error":3,"message":"Invalid service"}
    • 成功:{"error":0,"message":"Success","short_url":"..."}
    • 短網址建立失敗:{"error":2,"message":"Failed to shorten URL"}
  • DB side effect:
    • quote_services.external_review_url 已有值:不寫 DB,直接回傳既有值。
    • quote_services.external_review_url 為空:建立 security_hashes,產生短網址,寫回 quote_services.external_review_url

Legacy Rule

legacy 檔案:

/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Controller/QuoteServicesController.php
/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Model/QuoteService.php

link 分支:

  1. JSON request 預設回 {"error":1,"message":"Invalid session"}
  2. session 有效後,以 QuoteService.id + QuoteService.user_id 查 service。
  3. 找不到 service 時回 {"error":3,"message":"Invalid service"}
  4. 找到 service 後呼叫 QuoteService::getExternalReviewUrl()
  5. 若 service 已有 external_review_url,直接回該值。
  6. 若 service 沒有 external_review_url,建立 SecurityHash,長網址格式為 /review/service/{quote_service_id}/{hash},再用短網址服務產生 short URL 並寫回 quote_services.external_review_url
  7. short URL 有值時回 success;否則回 Failed to shorten URL

新舊程式對照

detail doc 必須保留實際行號,避免只寫「已補 action」但看不出 owner guard、short URL 建立與 DB write 是否對齊。

Legacy PHP 5.6

legacy controller:

/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Controller/QuoteServicesController.php
legacy 行號職責
3571-3579external_review($action, $id) 入口;submit / invite 先分流,其他 action 進入 link 分支。
3580-3586JSON request 下建立預設 Invalid session response,並檢查 REST API session。
3587-3594QuoteService.id + QuoteService.user_id 查 service;找不到回 Invalid service。
3595-3603呼叫 QuoteService::getExternalReviewUrl();有 short URL 回 success,否則回 Failed to shorten URL。
3606-3607render JSON response。

legacy model:

/Users/mattsu/Documents/Site/get-lancer-php56/app/Plugin/Quotes/Model/QuoteService.php
legacy 行號職責
357-362getExternalReviewUrl() 入口;未指定 service 時取 user 第一個 service。
363-379quote_services.external_review_url;空值才建立新 URL 並寫回 service,否則直接回既有 URL。
382-388建立 security_hashes,組 /review/service/{quote_service_id}/{hash} 長網址,轉成 short URL。

New PHP 8.2

new 檔案行號對應 legacy職責
Lib/Common/RouterRule/Mapping.php:53-56access log pathroute /quote_services/external_review/link/{quote_service_id}.jsonQuoteServices::external_review_link()
Endpoint/V1/QuoteServices.php:135-170QuoteServicesController.php:3580-3607session guard、owner guard、short URL response mapping。
Lib/Model/QuoteService.php:1697-1727QuoteService.php:357-379既有 URL 直接回傳;空值時建立 URL 並寫回 quote_services.external_review_url
Lib/Model/QuoteService.php:1729-1735QuoteService.php:382-388建立 security_hashes,組 review URL,再轉短網址。
tests/QuoteServicesExternalReviewLinkTest.php:46-563595-3603owner 取得既有 URL 的 success response。
tests/QuoteServicesExternalReviewLinkTest.php:58-683587-3594非 owner 回 Invalid service。
tests/QuoteServicesExternalReviewLinkTest.php:70-793580-3586無 session 回 Invalid session。

逐段對照

new 行號對應 legacy職責
Mapping.php:53-56access log path將 legacy link path 顯式 route 到新版 endpoint。
QuoteServices.php:137-1423580-3586驗 REST API key + session token;失敗回 error=1, message=Invalid session
QuoteServices.php:144-1553587-3594以 path quote_service_id 與 session user 做 owner guard;找不到回 error=3
QuoteServices.php:157-1643595-3599呼叫 model 取得 short URL;有值回 success 與 short_url
QuoteServices.php:166-1693600-3603short URL 空值時回 error=2, message=Failed to shorten URL
QuoteService.php:1697-1727357-379保留 legacy lazy-create:已有 external_review_url 不寫 DB,空值才建立並寫回。
QuoteService.php:1729-1735382-388建立 hash,長網址格式為 /review/service/{quote_service_id}/{hash},再轉 short URL。

測試

docker exec -w /project-data cd63f9147e8d vendor/bin/phpunit tests/QuoteServicesExternalReviewLinkTest.php

測試覆蓋:

  • owner 可以取得既有 external_review_url
  • 非 owner 回 legacy invalid service。
  • 無 session token 回 legacy invalid session。

測試刻意使用既有 external_review_url fixture,不觸發外部短網址服務。