限制與風控規則

文件狀態:草稿 / 以 search_add 建立第一版架構
最後驗證:2026-05-07
來源:pro360_api_82 search_add code、既有 PHPUnit、Common Process Documents

目的

這裡整理「會限制使用者操作次數、阻擋流程、或因環境不同而改變判斷結果」的共同規則。

這類規則常見於:

  • 提出需求次數上限
  • 同分類 / 同專家 / 同案件重複操作限制
  • Redis 防連點或短時間 rate limit
  • production-only 風控
  • 測試環境為了可重現而繞過或強制開啟的限制

完整 business flow 仍放在 業務流程;這裡只回答「限制在哪裡、怎麼算、環境是否有差異、測試怎麼避免誤判」。

不回答什麼

  • 不重寫完整 API 流程。
  • 不記錄單次測試 ID,除非是必要的誤判案例。
  • 不把所有 guard 都列進來;只有會反覆影響測試、migration、排查的限制規則才放這裡。
  • 不把 downstream queue / payment 規則混進來;那些放在 Queue、付款或 Log 對應文件。

文件架構

限制與風控規則/
  README.md
  search_add.md
  redis_double_click.md
  環境差異.md

後續可依流程擴充:

  quote_request_copy.md
  provider_accept_narrow_match.md
  want_to_contact_provider.md

目前先建立:

文件用途
search_addsearch_add 提出需求與發案前風控限制
redis_double_clickRedis 短 TTL 防連點 / 去重的共同判讀方式
環境差異測試、staging、production 對限制與風控規則的差異總覽

後續若某個限制跨多支 API 使用,再抽成獨立文件。例如 Redis 防連點可從 search_add / copy / payment 拆成 redis_double_click.md

規則分類

類型判斷方式常見來源例子
DB count limit查資料表筆數與時間窗quote_requests, quote_bids同 user / category 24 小時內提出需求上限
Redis short TTLincrementKey() / isDoubleClick()RedisUtil防連點、短時間重複操作
daily marker每日一筆紀錄daily_access每日 user access activity,注意不是發案上限
production-onlyEnvFactory::getEnv()code guard相同專業類別專家不可發案
config-basedProConfig / DB 設定config / categoryquote.bid_count_limit, category flags
exception user / category寫死例外code constant / literal id特定 user 或 category 不套用限制

每條限制規則必寫欄位

新增限制文件時,至少寫清楚:

欄位說明
規則名稱例如「同分類 24 小時提出需求上限」
入口流程例如 search_add, copy, provider_accept_narrow_match
判斷時機建資料前、建資料後、worker、付款前、通知前
限制條件user/category/request/provider/time window/count
上限值寫死值、config、DB 欄位或 Redis TTL
使用資料table / Redis key / config
環境差異測試、staging、production 是否不同
例外條件official user、特定 category、特定 user id
對外結果API error / message / status
測試注意需要 seed 幾筆資料、是否要清 Redis / DB side effect

環境差異標示

限制規則必須特別標示「測試與正式環境是否一致」。

常見差異:

差異類型說明測試風險
production-only guard非 production 直接跳過staging / PHPUnit 成功不代表 production 會成功
force env flag測試用 env 強制開 production branch測試通過代表該 branch 可跑,不代表 staging 預設會跑
Redis 開關use_redis 不同防連點 / lock 在本機或測試環境可能不生效
live DB drift測試資料會隨時間變動24 小時 / 30 天 count 可能今天和明天不同
worker timingqueue 被即時搬走不要把查不到 queue row 當成限制沒跑

排查順序

遇到疑似「次數限制 / 風控擋住」時:

  1. 先確認 API response 的 error / message
  2. 找到對應流程文件,例如 search_add
  3. 確認限制是同步 guard、Redis、DB count 還是 production-only。
  4. 查使用資料前先確認 schema。
  5. 查環境設定與 env flag。
  6. 如果是測試,確認 fixture 是否已清理:
quote_requests
quote_request_limit_ids
daily_access
Redis key
queue / log side effect

維護原則

  • 不把「測試 fixture 為了製造限制」誤寫成產品規則。
  • 不把 daily_access 當成提出需求上限;它是每日 user access activity marker。
  • 有時間窗的限制要寫明使用 DB created、local timezone、還是 Redis TTL。
  • 有 production-only 的限制要寫明 staging / PHPUnit 預設是否會跳過。
  • 如果限制依賴 live DB count,測試文件要說明資料會漂移。