Commit 188fa0c
異體字落地替換第三階段 work plan:按欄位型別全面套用
第一階段建了 char_variant_map schema,第二階段接了 3 類呼叫點(BIOG_MAIN 姓名、
ALTNAME_DATA 別名、書名批次匯入),但採逐點手掛,因此全庫仍有 9 個缺口。本文件是
第三階段的實作計畫:把落地替換擴張成「所有文本型別欄位都過一遍」的通用機制,並留下
防止日後再漏的常規(AGENTS.md §1.3 + skill + 架構測試)。
僅新增文件,不含任何實作改動。
使用者敲定的決策:
- 以**欄位型別**判定範圍(所有 varchar/char/text 類都過,不預判有沒有中文)——
對照表 key 全是 CJK,套在拼音欄上必然 no-op,所以型別判定就夠,且會自動跟上 schema 演進
- **預設 lenient(全量規則)**,strict 只用於人名與別名欄且是逐欄位例外
- 備註欄也替換
- 不做既有資料回溯校正
- 眾包核准回填+提案核准直接寫庫分支+v1 token 端點都補,restore 不做內容替換
- 已被閘門下架且有 React/v2 替代品的 legacy Blade 路徑全部不做;
仍在使用且無替代者的舊路徑(v1 token API、crowdsourcing confirm、saveas 等)保留
- 本身用於文本替換/字形對照,或語義上必須保留原字的地方一律不掛
- 拉丁人名欄(BIOG_MAIN 9 欄 + ALTNAME_DATA 4 欄)全部排除
- 「標籤→代碼」查表鍵採兩側都替換
計畫過程中發現、並已寫進文件的幾個關鍵風險:
- **不回溯 + 精確比對 = 可能製造新分裂**(D7)。最尖銳的是 resolveNameCode():
只替換傳入值會錯過既有變體形列、鑄出第二個 name code,比不替換更糟。
所有身分/去重比對都必須兩形都探
- **幂等需要三個前提**(D8):傳遞閉包、兩欄限單一 codepoint、環只丟環邊;
且順序必須是「過濾→移除環邊→算閉包」(反過來會在環上無限迴圈)
- **文本型 PK 成員替換會改變列身分**,且 ASSOC_DATA.c_text_title 會改寫對面那個人的
鏡像列 PK 成員而該側無衝突檢查(撞唯一鍵會冒成 500 而非 409)
- **搜尋路徑完全沒有異體字歸一化**(D9),上線後新舊字形互相搜不到;
真正的槓桿在姓名搜尋/FTS 建索引,不是 VariantCharNormalizer(那是拼音派生)
驗證:七輪 review agent + 三輪 codex,逐一對真實程式碼查證引用的檔案:行號與推理;
最後一輪 codex 回報「沒有需修正的實質問題」。過程中修掉的實質錯誤包括
Eloquent observer 方案不可實作(該表沒有 model、寫入全是 DB::table())、
標籤 map 鍵碰撞會讓合法代碼被判 invalid、以及 5 個 varchar 自參照樹狀父鍵
(含 STATUS_TYPES 的 _parent_code 命名變體)漏排會直接斷樹。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent c24ba53 commit 188fa0c
1 file changed
Lines changed: 385 additions & 0 deletions
0 commit comments