本卡屬 FR-132 A.6(子母卡 CM-2559),機制三張之二。做第二層「元素」:一支 v-can 指令取代九種散寫判斷,配三支守衛測試讓規範有牙齒。建議 model:opus。
頁內按鈕、連結、選單項要不要出現,以後只有一種寫法:v-can="'grc.job.update'",沒權限就不渲染。今天前端有九種寫法(hasCap 37 處、can 13、pagePermission.includes 4、isPlatformAdmin 43、isAuditor 9、isProjectManager 40…)互不相通,守衛測試掃不出漏網。本卡做指令、做守衛,不回頭大掃既有寫法——八棒實作碰到哪支檔換哪支。
FE 無任何權限 directive(src/main.js:167-170 只有 tooltip/badge/ripple/styleclass)
權限來源:src/stores/userStore.js 的 hasCap(CM-2560 後讀 /users/me/capabilities 的全集)
既有 AST 守衛先例:src/__tests__/socket-render-no-vhtml.spec.js(vitest 掃源碼)
盤點表:inventory/a6-button-capabilities.md「怎麼讀」段定義了三種多權限語意(hasAny/兩者都要/依情境擇一)
資料層條件(專案角色、輪次狀態):D-A6-4 以 AND 疊加,不由指令處理
v-can:值為字串=需要這顆;陣列=hasAny;物件 { all: [...] }=兩者都要。無權限→元素不渲染(移除 DOM,不是 display:none;用 comment 節點佔位,比照 v-if 語意)。超管旁路讀 store 的 bypass。權限名拼錯(不在 /capabilities/menu 清單)→ dev 模式 console.warn 一次。v-can 只管公司層;專案角色/狀態條件照舊寫 v-if,兩者同時存在時 v-can 在外層元素或同元素並列(Vue 同元素 v-if 與自訂指令可並存,指令在 v-if 為真時才掛)。文件寫清楚這個寫法。hasCap(/can(/pagePermission.includes 散寫:以現況檔名+次數為基線,多一處就紅(八棒清一支減一條)。③ v-can 的值必須是三段式名或已知變數,字面錯字紅。