2026-08-01 · 對應 docs/plans/2026-08-01-inquiry-lookup-flow-spec.md §0.5 本輪邊界
· 分支 docs/notification-open-questions @ 4fdc0f4
at-contact-us-plugin @ f5d8b59 → 1638213,
檔名同時改成流程序號):
4.3.2-0-…-check_record_form.jpg —— 狀態 ④ 重新取得連結表單4.3.2-1-…-check_record_list.jpg —— 狀態 ③ 無 atc_c 的清單4.3.2-2-…-check_record.jpg —— 狀態 ③ 有 atc_c 的單筆頁4.3-* 四張已改名為 4.3.1-*(Send Inquiry 側)。
三張稿把版面完全定死了,下面 B 區的 tab 決議與 A 區的附件決議都獲得印證,
但也帶出兩個新的規格張力(見 C 區)。
你剛剛回答的兩題,已可直接進實作。
D7 的「答:」原本是空的,只有開發方建議「顯示檔名、可下載(走同一簽章機制)」。
連帶要求:現行下載端點 admin_post_inwin_atc_download 是後台專用
(Caps::can_view() + action-specific nonce),未登入用戶走不通。本輪需新增一條
前台簽章下載路徑,授權鏈為「驗 token/session → 取 case_hash 對應案件 →
確認該案件的 email_hash 等於憑證中的 → 確認附件的
(form_type, case_id) 指向該案件 → PathGuard::resolve_within() 後輸出」。
既有 DownloadEndpoint::authorise() 的純函式設計可沿用,但授權來源要多一種。
⚠️ 這等於在 2026-08-01-inquiry-attachment-hardening.md 剛封起來的附件直連防線上
再開一個受控入口。該 runbook 的三環境 curl -I 驗收項目要同步擴充:
「無憑證直接打前台下載端點必須非 200」。
✅ 設計稿印證:單筆稿的「您的詢問」區塊畫出「附件:📎 photo.jpg 📎 spec.pdf」, 迴紋針 + 檔名的樣式就是可點連結;「我們的回覆」區塊同樣有「附件:📎 manual.pdf」。 這個決議與 Lilith 的稿一致。
客戶 G-1 答「以送出時的 ICL_LANGUAGE_CODE 為準」,但那講的是給用戶的信;
客戶從未針對客服信表態。直接照抄會得到「日本用戶送出 → 客服收到日文通知信」。
{locale}」。
收件人 Nelly.hsieh@in-win.com.tw / service@art-tangency.com 都在台灣。
本題整體仍屬下一輪(第 9 題未結案),本輪先擇一並在 spec 註記 —— 這是你先前的裁示。
規格留了選擇空間或根本沒寫,我依既有實作慣例擇一。不同意的話現在講,改起來便宜。
兩份文件對不上:客戶 C10 答「4.3.2 查看紀錄是獨立頁面,由 Lilith 建頁貼
[at_contact_records]」(2026-07-28);spec §6 則寫「Check Record tab
由『顯示但未開放』改為實作四態頁面」(2026-08-01)。
/contact-us/?atc_e=…&atc_exp=…&atc_t=…,
shortcode 偵測到 token 參數就自動切到 Check Record tab。
C10 的核心理由是「簽章連結必須有落地 URL」—— 帶 query string 的表單頁同樣是落地 URL, 理由不受影響。且 C9 的答覆(雙入口 tab)比 C10 晚,tab 本身就是客戶看過的設計。 不另開頁也省掉「兩個 shortcode、兩個頁面、四個 Elementor 頁要維護」。
✅ 設計稿印證,此項已可視為定案:三張 4.3.2-* 稿的頁首都是同一組
Send Inquiry / Check Record tab、Check Record 呈紅色 active 狀態,
麵包屑一律是 Support > Contact US,footer 與五個據點區塊也完全相同 ——
畫的就是同一頁的另一個 tab,不是另一個頁面。C10 的「獨立頁面」已被後續設計取代。
spec 原文是「以常數或設定頁欄位提供,不查路由表」,兩者皆可。
日後 CS 三維路由補上時,改的是「收件人來源從設定欄位換成查表」,兩種做法的可逆性一樣; 但設定頁欄位讓客戶自己就能改收件人,不必為了換一個信箱發版。 同時把 spec §11 清單裡的「設定頁四欄」一次補齊(寄件者名稱/寄件者 Email/備援收件信箱/查詢連結有效天數)。
case_hash
spec §2.4 / §3 安全約束 3
spec 只寫「驗證後 session 30 分鐘」「session 綁定類型」,沒指定實作形式。
HMAC(type|email_hash|exp),30 分鐘。
頁內從清單切到單筆時走 ?atc_view={case_hash} —— case_hash 是 keyed HMAC,
本來就設計成可出現在 URL 上;由 cookie 授權 email 作用域,再驗該案件確實屬於這個
email_hash。這樣不必為每個清單項目重新簽一次完整 token
(重簽會靜默延長 exp,與 §7「每封信簽發當下重新計算 exp」的意圖打架)。
spec 只說在 CanonicalSchema::shared_case_columns() / shared_case_keys()
加 email_hash / case_hash 欄位與索引,沒交代既有列怎麼辦。
Migrator::data_steps() 目前是空陣列,正好是第一個),
用同一張表的 email / sn 明文欄位回填。
不回填的話既有案件的 hash 是空字串 —— 查詢一律落空,而且是靜默落空。
mlab 目前案件數趨近於零,成本可忽略;正式站上線前跑一次即可。
回填必須在 inwin_atc_hash_key 產生之後執行,順序不能顛倒。
spec 要求「同一 Email 60 秒內只能請求一次」。既有 RateLimiter 是送出用的
IP_LIMIT=3/10 分 + EMAIL_LIMIT=5/24 小時,語意不同。
RateLimiter 這個類別的注入式設計,但用獨立的 transient 前綴與獨立常數。
共用計數器會讓「查了三次紀錄」把「還能送幾張單」吃掉,反過來也一樣 —— 兩者是不同的濫用面向。
RateLimiter 的 allow()/record()/release()
競態限制(見該類別 docblock)在這裡同樣存在,同樣接受。
客戶 F2 答「3 語系 × 3 類 = 9 個模板,其餘語系 fallback 英文」。
但站上 WPML active 語系只有 en,且既有 ResultScreen
就是 zh-hant / en 兩版、完全相等比對。
ResultScreen 的兩版模式。
第三語系(日文)等 WPML 真的啟用該語系再補,模板結構本來就支援多加一版。 現在做 9 個模板,其中 3 個永遠不會被觸發。
atc_replies 不建表,但留一個回傳空陣列的讀取縫
spec §0.5 / §6
spec 要求「查詢頁的回覆區塊版面與 atc_replies 的讀取路徑要先留,
以『查無回覆』空狀態呈現」,但表本輪不建 —— 讀取路徑無表可讀。
[],並在 docblock 寫明
「下一輪換成真正的 repository,呼叫端不動」。
這樣版面、空狀態、與呼叫點都到位,下一輪只換一個實作類別,不必重做查詢頁 —— 正是 spec 那句話的目的。
這幾項我沒有足夠依據自己決定,但也還沒到非答不可 —— 排在對應 task 開始前給答案即可。 前兩項是讀完新設計稿才浮出來的。
客戶 D8 明確答「前台不顯示任何狀態標籤」,理由寫得很完整 —— 「回覆區塊的有無本身就是狀態」,還附了一張對照表,並提到附帶好處是 「省去一組需要 10 語系翻譯的介面字串」。
但新的清單稿在每一列右側放了一欄無標題的「已回覆」標籤
(CN202607300001 有、CN202607280015 沒有、CN202607150003 有)。
單筆稿則確實沒有任何狀態標籤,完全符合 D8。
D8 的推論前提是「使用者看得到回覆區塊」—— 那只在單筆頁為真。清單頁看不到任何回覆內容, 沒有標籤就無從分辨哪幾筆已處理,D8 想省掉的那個資訊反而沒有替代來源。 所以我傾向照稿做:清單頁保留標籤、單筆頁不放標籤。
要你確認的:atc_replies 不建表 → 所有列都會是「未回覆」(無標籤)。
標籤的版面要先做,但實際上這一輪不會有任何一列亮起來。
清單稿的四欄是「案件編號 / 送出時間 / 聯絡主題 / (已回覆)」,
沒有任何一欄畫成連結樣式,也沒有右側的〔查看〕按鈕欄 ——
但單筆稿的頁首有「← 返回我的詢問紀錄」,證明兩頁之間確實要能互相走。
對照 spec §4 的信 4 版面,信件裡是每列右側一個明確的〔查看〕。清單頁稿上沒有對應物。
cursor: pointer + hover 底色),案件編號同時做成連結樣式。
不另加一欄〔查看〕,因為稿上的欄寬已經排定,加欄會破壞與稿的對齊; 案件編號本來就是這一列的識別,做成連結最不需要解釋。 若你要求嚴格照稿(完全不改樣式、只有整列可點),也可以,但無障礙上會弱一些。
spec 拍板「存檔時驗證寄件者網域必須等於站台網域
(wp_parse_url(home_url(), PHP_URL_HOST) 去掉 www.)」,
且明文「不得提供『我知道風險,強制存檔』的勾選框」,唯一放寬路徑是
apply_filters('inwin_atc_allowed_sender_domains', …)。
照這條規則,三個環境算出來的合法寄件網域分別是
inwin.mlab.host / inwin.demo1.app / 正式站網域。
問題在於 mlab 與 demo1 這兩個網域沒有真實信箱、也沒有 SPF 記錄,
寄出去必進垃圾桶或直接被拒。
inwin_atc_allowed_sender_domains filter 在
wp-config.php 放行,還是靠 Mailpit 攔截、根本不出站?noreply@ 信箱誰去 SiteGround 開?這是上線的硬前置,
不開就整套機制失效。
查詢機制做完之後,/contact-us/ 與 /rma/ 才第一次有完整迴圈可交付。
目前這兩頁仍是舊的 Elementor 表單,只有 preview 頁(103975 / 103976)在跑新 shortcode。
影響的是「客服收不到通知」這個功能倒退持續多久。信 2 本輪就會補上, 所以換過去之後客服是收得到的 —— 缺的只有「已回覆通知」。
寫程式不受影響,但手測跑不完。做到驗收那一步之前要先處理掉。
spec §5 實查結論。本機開發預期用 Mailpit 攔截,但目前沒有驗證過 wp_mail()
真的會落到 Mailpit(PHP 8.0 isolate 的 sendmail_path 沒查)。
第一個寄信 task 開始前要先確認,否則測出來的「有寄信」其實是靜默失敗。
client_max_body_size 2M vs 附件上限 5MB
站台 conf 寫死 2M,超過 2MB 的附件會被 nginx 以 413 擋掉、PHP 完全看不到。
這條在查詢頁本身不觸發,但「附件可下載」的手測需要先有一個夠大的附件存在。
改 conf 之後記得 不要用 herd restart nginx(它會說謊),
要請你跑 ! sudo kill -HUP <master_pid>。
inwin_atc_hash_key 必須進備份清單
spec §2.2 的紅字要求。這把 key 遺失=該站所有詢問紀錄永久查不回來, 連重發都救不了。交付說明要寫,三個環境各自產生的值也要各自記錄。
這些已經有結論了,結論就是「下一輪」。列出來避免被誤當成漏掉。
| 項目 | 為什麼延後 |
|---|---|
| 信 3(已獲回覆通知) | 需先有後台回覆功能與 atc_replies 表,兩者皆未做 |
| CS 三維路由 | open-questions 第 5、6、7 題全未決;本輪以固定收件人繞過。這三題加起來是「一週 vs 一天」的差別 |
| 第 1 題:RMA 範圍爭議 | 客戶規格明文排除 RMA,但實作是共用底層一起做的。屬通知寄送端 |
| 第 8 題:代理商國家不產生 submission | RMA 專屬,與查詢端無關 |
第 10 題:mail_failed 對後台清單的影響 |
需要先有 atc_mail_log;本輪不建 |
contact-rma-spec §11 的原有清單,沒有一項擋到本輪實作,放這裡只是不讓它們消失。
custo_admin 副作用
從三張 4.3.2-* 稿抄下來的,實作時照這個做,不用再回去翻圖。
稿只有繁中版,英文版文案要開發端自己補(比照 ResultScreen::TEMPLATE_EN 的做法)。
| 狀態 | 版面與文案 |
|---|---|
| ④ check_record_form |
標題「查詢您的詢問紀錄」 說明「請輸入您送出詢問時使用的電子信箱,我們會將查詢連結寄給您。」 欄位: E-mail*(必填)/案件編號(選填)按鈕:取得查詢連結(左側信封 icon,與 Send Inquiry 的 Send 鈕同款) ⚠️ 稿上筆誤:案件編號欄的 placeholder 誤植成 Insert your e-mail,實作要改
|
| ③ 清單 check_record_list |
標題「您的詢問紀錄」 四欄: 案件編號 / 送出時間(YYYY-MM-DD,不含時分)/
聯絡主題(= purpose_label)/ 無標題的「已回覆」標籤欄表頭下一條細線,列間無框線。範例列 3 筆,實際每頁 20 筆(spec §7) |
| ③ 單筆 check_record |
頁首「← 返回我的詢問紀錄」接著 案件編號:… / 送出時間:…(含時分,如 2026-07-30 14:32)小標「您的詢問」+ 細線 → 國家/地區、產品分類、聯絡主題、姓名、E-Mail、電話、訊息內容、附件 小標「我們的回覆」+ 細線 → 回覆時間、回覆內容、附件 沒有任何狀態標籤(符合 D8) |
email_hash,顯示遮罩值等於用 hash 反推明文);
狀態 ③ 已通過簽章驗證,顯示自己的 Email 是合理的。atc_replies 不建表)。
spec §0.5 已明文要求版面與讀取路徑要先留、以空狀態呈現,不得因為沒資料就省略,
否則下一輪要重做查詢頁。