Async Fallbacks

這份文件專門說明那些不屬於同步 response 保證的流程。

對應程式:

legacy 的 manual / related fallback 不是直接塞進 search_add 當次 response。

正確流程是:

  1. search_add 同步完成 request create、auto / narrow、finalize
  2. QuoteRequest::checkR1ManualMatchStartNoAutoQuote() 判斷是否要補排 downstream task
  3. R1 是一般多專家案件時補排 newQuoteRequest,由 NewQuoteRequestHandler 後續執行一般 manual / related match
  4. R1 是 direct reserve / narrow 類案件時補排 newNarrowMatch

所以如果你只看同步 response,最多只能判斷:

  • sync auto / narrow 是否和 legacy 對齊

不能直接判斷:

  • 最終 manual / related bid 是否已經全部建立

這次已對齊的點

  • R2 完成後,若確認 R2 與其對應 R1 都沒有 auto quote,會依 R1 match_type 補排 newQuoteRequestnewNarrowMatch
  • task_queue 已補去重,避免重複排同一筆 action/value
  • NewQuoteRequestHandler regression 已驗證會建立 is_narrow_match = 0 的 manual bid,且維持 legacy async manual bid 欄位形狀:narrow_status_id=0quote_status_id/provider_status_id=1/1pricing_unit=NULLprice_note=NULL

Production legacy baseline

2026-05-18 正式機 legacy baseline:

  • 4465474446546744654634465460 都有 task_queue_log.action = newQuoteRequestretry = 0
  • task started/executed 時間落在大量 non-narrow manual bids 的 created 時間範圍內。
  • async bids 型態是 is_auto_quote=0is_narrow_match=0is_want_to_contact_provider=1is_related=0narrow_status_id=0、fee 使用 manual_fee。先前以 (string) 驗證 pricing_unitprice_note 為空字串,不能區分 DB raw NULL'';2026-08-07 依 canonical legacy code/schema 與切換前 staging raw baseline,更正兩欄契約為 NULL
  • task_queue 查不到但 task_queue_log 查得到,是 worker 已搬走 queue 的正常情況。

Raw NULL parity 更正(2026-08-07)

  • Legacy QuoteService.php:3967-3993 建立一般 manual / related bid 時沒有指定 pricing_unitprice_note
  • Legacy QuoteBid::buildBulkInsertQuery()QuoteBid.php:4658-4699)只 INSERT data set 實際出現的欄位;這兩欄不會被補成空字串。
  • Canonical legacy schema 與 staging SHOW COLUMNS 都顯示兩欄可為 NULL、default NULL
  • 切換前由 legacy newQuoteRequest 建立的 staging request 22929 共 75 筆一般/related manual bids,兩欄 raw value 全部都是 NULL;task log 為 action=newQuoteRequestretry=0
  • Regression test 改用 assertNull();不得再以 (string)$value === '' 掩蓋 raw DB 型別。2026-08-07 targeted integration test:1 test / 32 assertions,通過。

測試入口