GET/POST /quote_feedback_comments/delete/id:{comment_id}.json
狀態:PHP 8 本地實作與測試完成,Staging 尚未驗證。
最後更新:2026-07-31
快速結論
id是 CakePHP colon named parameter,經(int)cast。- 只允許
comment_user_id = session user id的本人 hard delete。 - 不查 feedback,因此孤兒 comment 仍可由 owner刪除。
- Legacy 沒有限制 HTTP method;Production 同時有 POST 與 GET,不可自行改成只接受 DELETE/POST。
- 成功固定回
{"error":0,"message":"success"}。
Route、caller 與流量
正式流量形態:
POST /quote_feedback_comments/delete/id:{comment_id}.json
GET /quote_feedback_comments/delete/id:{comment_id}.json- Production 2026-06-29~2026-07-28:POST 7、GET 3,全部命中 Legacy。
- 現行
web-app找不到 delete caller;仍有正式流量,可能來自舊 App/其他 client,不能刪除 GET 支援。 - 2026-07-31 掃描 Legacy host
ip-10-5-2-19全部保留的get-lancer_access.log*:命中 3 筆 delete path,全部以.json結尾;其他 instances/ALB 尚待確認。
PHP 8 已使用明確且 anchored mapping:
^quote_feedback_comments/delete/id:([0-9]+)\.json$
→ QuoteFeedbackComments::delete / id / ${1}專用 mapping 與 generic File fallback 都有測試,涵蓋 invalid named value、slash/query path與 unknown action。
程式位置
Legacy
Root:/Users/mattsu/Documents/Site/get-lancer-docker-2/get-lancer
app/Plugin/Quotes/Controller/QuoteFeedbackCommentsController.phpbeforeFilter():8-18。delete():106-142。- session/request log:109-113。
- named input/owner query:118-127。
- hard delete/success:130-135。
- error mapping:137-140。
app/Plugin/Quotes/Model/QuoteFeedbackComment.php:2-18:只有belongsTo User,無 delete callback/dependent association。app/Controller/RestApiHelper.php:75-182:session、auth side effect、request info log。app/Controller/AppController.php:1223-1226, 1313-1343:named input、JSON response與 error warning log。
PHP 8
Endpoint/V1/QuoteFeedbackComments.phpdelete():94-130。.json副檔名 guard:132-135。- Legacy session/cache/access side effect:137-249。
- auth/action error response:222-265。
- request log:266-290、312-333。
- 原始 colon named parser:345-364。
Lib/Model/QuoteFeedbackComment.php- owner lookup:26-34。
- hard delete:77-81。
Lib/Common/RouterRule/Mapping.php:160-163:anchored delete mapping。tests/QuoteFeedbackCommentsSaveDeleteTest.php:384-559:GET/POST、owner、orphan、cast與 route negative。
逐段對照
| 階段 | Legacy | PHP 8 現況/要求 |
|---|---|---|
| guard | Legacy 可由 .json 或 Accept 判定 JSON;另驗 API key、session | PHP 8 只接受 .json;其餘 auth 已對齊 |
| input | colon named id,PHP 5.6 (int) | 已從 original path 解析,slash/query 不誤收 |
| DB read | comment id+session user id | 已對齊 |
| DB write | hard delete一筆 comment | 已對齊;不 join feedback |
| payment | 不適用 | 不可新增 |
| queue | endpoint無;auth cache miss可能 returnedQuoteService | 已保留 Legacy auth 時機 |
| activity | 不適用 | 不可新增 |
| notification | 不適用 | 不可新增 |
| log | request info;error warning | Legacy log 已保留;generic 差異待決策 |
| response | success與 code 1/3/4/999 | 已對齊並測試型別 |
Migration decision(2026-07-31,reviewer 已接受):PHP 8 不搬 Legacy RequestHandler->prefers('json') 的 Accept negotiation,只接受 .json URL。ip-10-5-2-19 retained logs 只看到 .json;無副檔名即使帶 Accept: application/json 也先回 {"error":1,"status":"invalid request"},不執行 delete。
執行順序與 input
- Request URL 必須以
.json結尾,且通過 API key/session。 - 取得 session user並寫 Legacy endpoint request info log。
- 讀 colon named
id,PHP 5.6(int)cast。 id=0時回 code 3;其他值查id + comment_user_id。- 查無資料時回 code 4;查到即 hard delete。
| URL input | Legacy 行為 |
|---|---|
missing、id:0、id:abc、id: | cast 0,error=3 |
id:1abc | cast 1,查 comment 1 |
id:-1 | cast -1,查無則 error=4 |
id:{owner row} | hard delete並 success |
id:{other user row} | 查詢即排除,error=4 |
slash /id/1 或 query ?id=1 | 不是 Cake named parameter;PHP 8 已驗證為 error=3 且不刪除,Legacy實測待補 |
DB write
SELECT id
FROM quote_feedback_comments
WHERE id=:comment_id
AND comment_user_id=:session_user_id
LIMIT 1;
DELETE FROM quote_feedback_comments
WHERE id=:comment_id;- 只刪一筆 comment;沒有 soft-delete欄位、transaction、cascade、feedback update、counter、activity、notification或 queue。
- 不可額外 join
quote_feedbacks或要求 feedback存在。Docker DB目前有 201 筆找不到 feedback的 orphan comments。 - 必須驗證 affected row 與測試 fixture restore;Legacy controller不檢查
delete()回傳值,找到 row後即回 success。
Response 與 error
成功:HTTP 200、application/json; charset=utf-8。
{"error":0,"message":"success"}action 內錯誤:
| 情境 | Body |
|---|---|
| invalid request/session path | {"error":1,"status":"invalid request"} |
| missing/0 id | {"error":3,"status":"require_comment_id"} |
| 不存在或非 owner | {"error":4,"status":"CommentNotFound"} |
| unknown exception | {"error":999,"status":"invalid request"} |
Invalid API key由全域 guard回 HTTP 401;blocked user為 HTTP 403。Invalid session可能先被 Legacy ACL 攔截,最終 HTTP/body仍需 Legacy Staging實測確認。
Side effect、log 與 config
- Domain side effect只有 hard delete。
- auth cache hit/miss、blocked check、user access與 returned-service queue時機必須與 Legacy相同,不可直接用 PHP 8 shared validator。
- request info log channel保留完整 path與實際 method
::GET/::POST;message為 user id,context含原始 API key,若有 request data/form也照記。 - error另由
handleProApiException()寫QuoteFeedbackCommentsControllerwarning。 - PHP 8 已保留 Legacy endpoint request log與 error warning,並停用這些相容 log 的 PHP 8 Slack handler。
- Router generic log與
client_usage_users是 Legacy沒有的額外行為,migration decision待 reviewer確認。 - 無 endpoint專用 ProConfig、URL、template、payment設定;部署只需核對 DB、Redis與 session共享狀態。
PHP 5.6 → 8.2 必測
- colon named parsing及
(int):missing、0、abc、1abc、negative。 - GET/POST都能執行;不得加 method guard。
- owner查詢型別與不存在/非 owner同樣回 code 4。
- hard delete成功與 DB failure時Legacy未檢查結果的行為。
- slash/query、duplicate named、URL-encoded named及 unknown action route negative。
測試與待辦
- PHP 8.2 syntax:通過。
- 全域
core:3 tests / 36 assertions;delete 核心覆蓋 GET/POST owner hard delete,並確認 non-owner 不可刪除。 - Other(
--exclude-group core):16 tests / 97 assertions;保留 orphan、missing/0/invalid/negative/prefix cast、slash/query negative、response value/type與 route guard。專用測試合計19 / 133。 - Regression:
quote_feedbacks/sent10/76、quote_feedback_tags/index12/68,全部通過。 - 尚待:其他 Production instances/ALB 的非
.json流量、Legacy/Staging response baseline、Staging hard-delete後 restore、未知 client確認、部署 Redis 核對、generic log/client_usage_users決策。Production ALB 不在本文件修改。