quote_bid_contact
文件狀態:草稿 / 部分已對 new API / 待補付款與 transaction 實測來源
最後驗證:2026-05-07
來源:Common Process Documents 整理、quote_bids migration docs;待補 legacy / new code 逐段來源與 PHPUnit 對照
目的
quote_bid_contact 是 consumer 從 quote card 正式聯絡 provider 的業務流程。
主要 API:
POST /quote_bids/want_to_contact_provider/{quote_bid_id}.json這份文件是完整業務 trace 入口,回答「consumer 正式聯絡 provider 後,哪些資料表與 downstream side effect 會發生」。單張 table 的欄位細節請看 quote_bids/want_to_contact_provider;扣款分支請看 quote_bid_contact_charge。
不回答什麼
- 不收錄 migration 狀態、PHPUnit 覆蓋狀態、正式機 access log 統計。
- 不完整重寫
transactions金流分支。 - 不描述 search_add 如何建立 quote card;search_add 見 search_add。
主流程簡圖
consumer 在 quote card 按聯絡 provider
-> 驗 API key 與 user session
-> 確認 session user 是 quote_requests.user_id
-> 讀取 quote_bids / quote_requests / provider
-> 若有 message,先寫 message / activity
-> 若有 message,做 message classification
-> message rejected / insignificant 時回 error 17,不成立正式聯絡
-> message 通過或無 message,進入 processWantToContactProvider
-> 更新 quote_bids contact 狀態
-> provider contact charge / transaction
-> 建 AutoQuoteContact activity
-> 送 task_event_queue / event_queue
-> 補 requestor note conversation
-> 回 successActor 與身份
| 角色 | 判斷方式 |
|---|---|
| consumer / requestor | session user 必須是 quote_requests.user_id |
| provider | quote_bids.provider_user_id |
| contact target | quote_bids.id 指到的 provider bid |
| payer | provider,contact charge 不是扣 consumer |
不要把「consumer 發起聯絡」誤解為 consumer 付款。這條流程的扣款主體是 provider,因為正式接觸新客源會進入 quote bid contact charge。
主要資料表順序
| 階段 | 資料表 | 說明 |
|---|---|---|
| bid / request guard | quote_bids, quote_requests | 確認 bid、request owner、provider、request 狀態 |
| message | messages, message_contents, quote_activities | consumer message 可能先寫入,即使最後 error 17 |
| classification | quote_bid_classify_contacts | 記錄 message 分類結果 |
| contact state | quote_bids | is_want_to_contact_provider, contact_provider_on, reason |
| charge | transactions, users, stripe_customers | provider wallet / card / transaction |
| activity | quote_activities | AutoQuoteContact 等正式聯絡活動 |
| async | task_event_queue, event_queue | counter、SMS、provider notification |
Message classification
如果 request body 有 message,流程會先寫入聊天室,再做分類。
| classes | 意義 | 是否成立正式聯絡 |
|---|---|---|
not-reject | 訊息有效 | 是 |
insignificant | 訊息過於空泛 | 否 |
rejected | 訊息不符合規則 | 否 |
insignificant / rejected 時,legacy 對外 response:
{"error":17,"status":""}此時可能已存在:
messages
message_contents
message 類型 quote_activities
quote_bid_classify_contacts但正式聯絡不成立,通常不應看到:
quote_bids.is_want_to_contact_provider = 1
quote_bids.contact_provider_on 有值
quote_activities.AutoQuoteContact
正式 contact charge transaction成功狀態
正式聯絡成功後,重點欄位:
quote_bids.is_want_to_contact_provider = 1
quote_bids.contact_provider_on = NOW()
quote_bids.is_interested = 1
quote_bids.reason = <reason>若流程有扣款或 subscription:
quote_bids.total_site_fee
quote_bids.quote_user_subscription_log_id
transactions.class = QuoteBid
transactions.foreign_id = quote_bid_id扣款成功與否不要只看 quote_user_subscription_log_id,要搭配 transaction real_pay_date 與 application log 判讀。完整規則見 quote_bid_contact_charge。
Activity / Queue
成功正式聯絡 provider 時,常見 side effect:
quote_activities.AutoQuoteContact
task_event_queue.bid_contact_count
task_event_queue.sent_contact_provider_sms
event_queue.Contact_ProAutoQuoteContact activity 在非 narrow match contact 時:
param1 = NULL
param2 = reasonnarrow match accept 轉進 contact 主線時,activity 參數語意不同,請看 narrow_match 與 provider_accept_narrow_match。
Queue 可能已被 worker 搬到 log table,驗 downstream 時要接受:
event_queue OR event_queue_log_1..event_queue_log_4
task_event_queue OR task_event_queue_log第一輪排查順序
- 查
quote_bidscontact state。 - 若 request 有帶 message,查
quote_bid_classify_contacts。 - 查
quote_activities是否有AutoQuoteContact。 - 查
transactions與付款 log。 - 查 queue 或 log。
查 bid 與 request
SELECT
qb.id,
qb.quote_request_id,
qr.user_id AS requestor_user_id,
qb.provider_user_id,
qb.quote_service_id,
qb.is_auto_quote,
qb.is_contact_charge,
qb.is_want_to_contact_provider,
qb.contact_provider_on,
qb.reason,
qb.total_site_fee,
qb.quote_user_subscription_log_id,
qr.auto_quote_contact_count
FROM quote_bids qb
INNER JOIN quote_requests qr ON qr.id = qb.quote_request_id
WHERE qb.id = <quote_bid_id>;查 message classification
SELECT
id,
quote_bid_id,
message,
model_version,
classes,
params,
created
FROM quote_bid_classify_contacts
WHERE quote_bid_id = <quote_bid_id>
ORDER BY id DESC
LIMIT 10;查 transaction
SELECT
id,
created,
user_id,
foreign_id,
class,
transaction_type_id,
amount,
real_pay_amount,
real_pay_date,
stripe_charge_id,
wallet_balance
FROM transactions
WHERE class = 'QuoteBid'
AND foreign_id = <quote_bid_id>
ORDER BY id DESC;判讀原則
- 有 message 不代表正式聯絡成功。
error=17代表 message 分類擋下,通常不進 contact charge。- 正式聯絡成功先看
is_want_to_contact_provider與contact_provider_on。 - 付款異常先看 Log 與告警流程 與 quote_bid_contact_charge。
- downstream queue 驗證要接受 queue 或 log 任一存在。