語意欄位,而非表單元件
排程中閱讀時間 5 分鐘 作者 NT²
密碼欄位不是「這個畫面上的一個機密文字框」。它是整座保管箱都理解的語意欄位型別——連遮罩、健康檢查、共用預設值與傳輸格式都包含在內。
語意欄位,而非表單元件
主張:意義存在於一份型別目錄中
插槽,而非空白頁定下了文件模型:類別、範本、項目、欄位型別。這篇文章要點名讓跨領域結構得以運作的樞紐:欄位的意義是全域的。
在 NT² Vault 中,欄位首先不是一個元件。它是一種語意欄位型別——在登錄表中擁有穩定身分。介面可以把這種型別呈現為機密輸入框、日期選擇器,或附件插槽。這些編輯器只是實作。真正的產品契約是型別本身:這個值代表什麼意義、它帶有哪些能力,以及當項目以密文形式離開記憶體時該如何定址。
主張是:當一座保管箱必須同時服務憑證、銀行、文件、IT 資產等多種類別,卻又不想為每個垂直領域各自發明一套平行型別宇宙時,語意欄位勝過各畫面各自為政的表單元件。
限制:元件鍵名無法跨場景延續
早期的結構化應用程式,常會這樣建模表單:欄位配置鍵叫 password,元件型別叫 secret,把 { "password": "…" } 存進 JSON。這對單一範本行得通。但當產品成長,它就會失靈。
鍵名會變成口耳相傳的民俗知識。 帳號欄位到底是 accountNumber、account_no,還是 acct?不同範本各自發明不同字串。搜尋投影、共用遮罩與遷移程式碼,都得為每一種同義詞各寫一段特例。
元件不代表意義。 一個 text 元件可能是銀行名稱,也可能是復原提示。一個 secret 元件可能是密碼,也可能是 TOTP 種子。跨領域功能無法只靠元件種類,就去判斷「這是不是一個到期日欄位」。
傳輸格式會被 UI 上的偶然決定綁死。 若持久化的密文直接內嵌表單作者自訂的自由字串鍵,那麼重新命名一個標籤或拆分一個畫面,就會變成一次儲存遷移。可攜式備份與複本批次都會繼承這個爛攤子。
擴充性會變成外掛劇場。 誘人的逃生口是「讓使用者自訂欄位型別」或「讓套件出貨可執行的 JavaScript 編輯器」。這條路會把本機保管箱變成一個信任邊界無上限、相容性難以掌控的擴充主機——正好與精簡、可稽核的加密與結構描述核心背道而馳。
NT² 需要的是一份登錄表,讓一個 FieldTypeId 在任何地方都代表同一件事,而新領域則是重用、或審慎擴充這份目錄,而不是各自分岔出去。
設計:FieldTypeId、能力旗標、穩定索引
語意身分
每個欄位型別都有一個穩定識別碼——也就是你用產品語言思考時所用的那個領域關鍵字:密碼、使用者名稱、到期日、IBAN、文件號碼等等。範本不會為機密發明私有的鍵字串;它們只是把登錄表中的型別配置進一套有序的結構描述裡。
範本作者選的是語意,而不是「我想要一個圓角文字框」。編輯器種類(機密、日期、多行文字、二進位附件參照……)是由型別定義推導出來的,這樣介面能維持一致,而儲存層也能維持單純。
能力旗標,而不是靠類別口耳相傳
型別定義帶有能力旗標——供其他子系統讀取的機器可讀標記與預設值:
- 這個值是否可以投影進本機搜尋文字;
- 它是否應該在揭露前保持遮罩;
- 共用/呈現時的預設敏感度;
- 是否參與特徵組合(例如「這組欄位看起來像一份銀行摘要」,或「這一列有值得掃描的密碼」)。
正因為有這些能力旗標,護照文件上的到期日和 TLS 憑證項目上的到期日,才能共享同一套提醒行為,而不必讓每個類別各自寫死一套私有的小框架。
傳輸時的穩定索引
在記憶體中與領域程式碼裡,值是以語意 id 定址的。當欄位以封裝後的內容資料塊離開記憶體時,定址方式改成登錄表清單中的穩定數字欄位索引——而不是把長得像密碼的字串鍵散落在密文裡。姊妹文章CBF:結構化欄位離開記憶體的方式談的是容器本身;登錄表則說明了為什麼這個資料塊能持續演化。
flowchart LR
Author[範本作者] --> Place[配置 FieldTypeId]
Place --> UI[依型別定義產生編輯器]
Place --> Caps[能力旗標]
Place --> Wire[內容資料塊中的 fieldIndex]
Caps --> Search[本機搜尋投影]
Caps --> Share[共用/呈現預設值]
Caps --> Features[到期、健康檢查……]
套件合併成單一目錄
欄位定義以資料套件的形式出貨,並在執行期合併成一份登錄表。核心套件涵蓋日常機密與備註。領域套件則新增財務、IT、醫療等專門詞彙,並盡量重用「密碼」、「日期」之類的共享型別,而不必每個套件都重新定義一次。類別範本接著把這些型別組合成結構描述——這是本系列下一篇的主題。
不必發明新型別的客製化層級
產品仍需要彈性。登錄表模型允許在範本層級與稀疏的逐項目層級,用既有型別做延伸。它不允許的是讓終端使用者從設定介面自行鑄造帶有全新傳輸索引的全新欄位型別。結構是靠組合與精心維護的目錄成長來擴展的——不是靠把每座保管箱都變成一台型別編譯器。
取捨:精心維護的意義,勝過無限的自訂型別
一份封閉的語意目錄,感覺比「想加什麼欄位都可以」更嚴格。這是刻意的。
| 你放棄的 | 你保留的 |
|---|---|
| 使用者自訂欄位型別 | 跨領域共享的意義 |
| 以套件內建可執行編輯器作為擴充路徑 | 通用編輯器加上宣告式規則 |
| 每個畫面各自私有的鍵字串 | 以 id 推理的穩定索引與遷移 |
| 只靠類別 slug 決定功能開關 | 依使用中欄位能力決定功能開關 |
新領域仍然可以持續出貨。它們以套件的形式出貨,盡量重用既有型別,只有在目錄真的缺少某個概念時,才審慎地新增經過版本控管的型別。這比自由格式的鍵名慢——但比在搜尋、共用與備份中同時維護五個「帳號」的同義詞,成本要低得多。
我們拒絕什麼
我們拒絕把使用者自訂欄位型別當成產品逃生口。 自訂範本可以排列既有型別;它們不能變成繞過登錄表的側門型別系統。
我們拒絕以可執行的套件 JavaScript 作為擴充欄位的方式。 領域套件與社群套件應該維持在資料加宣告式規則的層次。若一座保管箱必須執行不受信任的編輯器程式碼才能理解一個日期欄位,它就已經偏離了結構化資產的初衷。
我們拒絕把元件種類當成真理來源。 編輯器呈現型別;型別不會因此塌陷成編輯器。
我們拒絕在持久密文中使用自由格式的機密鍵名。 字串化型別的酬載,正是空白頁在加密之後借屍還魂的方式。
從元件到欄位
如果你曾經遷移過一份表單,發現同一個機密欄位竟然有三個名字,你就已經懂得為什麼語意欄位如此重要。NT² 把這個教訓寫成登錄表規則:意義集中管理;畫面只是投影。
接下來請閱讀從同一套型別系統組合出各個領域——說明欄位套件與類別套件如何把一份目錄變成多個垂直領域。至於這些欄位最終變成的封裝資料塊,可參考CBF:結構化欄位離開記憶體的方式。
最後更新 2026-11-19
相關故事
- 從同一套型別系統組合出各個領域
閱讀時間 5 分鐘
- 四個介面,一組欄位
閱讀時間 5 分鐘
- 插槽,而非空白頁
閱讀時間 6 分鐘