SearchAdd Request Normalization
快速結論
這段負責把 multipart / nested payload 正規化成 SearchAddInput。它不做 DB side effect。
current 入口:
SearchAddInput::fromRequest()
-> SearchAddRequestNormalizer::normalize()新舊程式對應
Current Legacy
主要入口:
/Users/mattsu/Documents/Site/get-lancer-docker-2/get-lancer/app/Plugin/Quotes/Controller/QuoteRequestsController.php::search_add()| legacy 區段 | 職責 |
|---|---|
raw User[...] / QuoteRequest[...] / Form[...] handling | 解析前端送出的 nested form payload。 |
| checkbox / array form handling | 保留 multi-select、travel preference、time 類欄位語意。 |
FormSummary handling | 保留 legacy summary payload。 |
Current PHP 8.2
| current 位置 | 職責 |
|---|---|
Endpoint/V1/SearchAdd.php:110 | 從 request 建立 SearchAddInput。 |
Lib/SearchAdd/SearchAddInput.php:74-102 | fromRequest() 把 raw request 轉成 input,並保留 travelpref writer 所需的 raw Form 值。 |
Lib/SearchAdd/SearchAddRequestNormalizer.php | 正規化 multipart / nested payload。 |
Lib/SearchAdd/SearchAddInput.php:478-646 | 拆出 QuoteRequest、User、Form、nested rows 與基本型別。 |
行號對照
| new 行號 | 對應 legacy | 職責 |
|---|---|---|
Endpoint/V1/SearchAdd.php:110 | QuoteRequestsController.php:1808 | 進入 search_add request 處理入口。 |
SearchAddInput.php:74-102 | QuoteRequestsController.php:1827-1855, 2025-2031 | 從 request 取 payload;保留 decode 後 raw Form,再 normalize 並拆成 input 區塊。 |
SearchAddRequestNormalizer.php:29-75 | QuoteRequestsController.php:1827-1852, 2490-2510 | FormSummary 預設、urldecode、iOS summary flatten、移除 base64 內容。 |
SearchAddRequestNormalizer.php:82-99, 165-183 | QuoteRequestsController.php:1854-1855 | 一般 Form 值做 rawurldecode 與 scalar-list normalization。 |
SearchAddInput.php:81, 115, 161-163, 545-583 | QuoteRequestsController.php:1854-1855 | 另保留 decode 後、尚未攤平的 Form;只供 DB type 已確認為 travelpref 的 writer 使用。 |
SearchAddRequestNormalizer.php:105-118 | QuoteRequestsController.php:2050-2055 | QuoteRequest[phone_no] / User[phone] 移除非數字與 + 以外字元。 |
SearchAddRequestNormalizer.php:124-134 | QuoteRequestsController.php:2645-2646 | preserve_to_quote_service_id alias 成 preserve_quote_service_id。 |
SearchAddRequestNormalizer.php:140-159 | QuoteRequestsController.php:2640-2642, 3041-3055 | landing page url decode。 |
SearchAddRequestNormalizer.php:211-239 | QuoteRequestsController.php:1941-1960 | country / state / city input 正規化。 |
SearchAddInput.php:478-565 | QuoteRequestsController.php:1863, 2020-2047 | 拆出 quote category、QuoteRequest、User、Form payload。 |
SearchAddInput.php:589-621 | QuoteRequestsController.php:2978-2994, 2966-2977 | 拆 nested QuoteRequestLandingPage、FormTime rows。 |
SearchAddInput.php:445-473 | QuoteRequestsController.php:2492-2495, 2904-2931 | 建單初值沿用 object JSON;單值/JSON array 由 form 寫表後的 updater 決定最終 DB flags。 |
Side Effects
無 DB side effect。
這段只產生後續流程使用的 input model。
不可改變的契約
- 不可把
travelprefJSON 字串陣列變成逗號字串後寫入 DB。 - request normalization 只做
Form[...]urldecode 與 scalar list normalization;{"value":"..."}/[{"value":"..."}]的攤平要留在 form submission writer,因為那裡才知道欄位 type,才能排除travelpref。 FormSummary要保留原始 legacy summary 語意。QuoteRequest[match_type]的 raw 值只代表輸入,最終落表仍要經 category 規則正規化。- request normalization 不應做 actor / DB 寫入。
Verification
主要測試:
tests/SearchAddInputTest.php
tests/FormSubmissionWriterTest.php
tests/SearchAddTravelPreferenceIntegrationTest.php
tests/SearchAddStep2IntegrationTest.php2026-08-04 驗證:raw / normalized 分流 Core 2 tests / 3 assertions、Other 2 tests / 4 assertions;DB transaction 1 test / 7 assertions 通過。
待確認 / 風險
- PHP array 不是本次 BAC-3658 的「字串 array」格式;只有 JSON string-array 走 raw travelpref 路徑,避免自行擴張 caller contract。
- location alias 已確認到
SearchAddRequestNormalizer.php:211-239;後續若要追 state/city 建立細節,應從resolveCountryId()/resolveStateId()/resolveCityId()再拆第三層文件。