◆ wport | pm_37

Enterprise API v1(REST API for Job CRUD)PRD(給後端 API 規格產生器使用)

Enterprise API v1(REST Job CRUD)

來源 doc/feature/pm_37/enterprise-api-v1-mockup.md

Enterprise API v1(REST API for Job CRUD)PRD(給後端 API 規格產生器使用)

本 PRD 對應 Coda backlog i-uL6dSrzo8o(原名「資料匯出 API」,正名為「Enterprise API(v1:REST API for Job CRUD)」)。 v1 範圍:REST API + wport 後台人工核發;v2(前端 Setting 自助申請 + 企業端 UI 整合)與 v3(CLI)各自獨立 PRD。 此 PRD 為純 API 功能,v1 不含企業端前端 UI;UI 區塊以 ops 後台與 API 行為描述替代(ops / AMS 後台另有低保真 Storybook mockup,見 §9)。


1. 文件資訊

  • 文件類型:API 功能需求規格書(v1:後端 + ops 後台)
  • 適用對象:後端開發、ops、產品、QA、企業端 API 使用者
  • 最後更新:2026/08/18
  • 版本:1.1.0(2026/08/18:金鑰終態動作由「撤銷 Revoke」正名為「刪除 Delete」,且語義改為硬刪除、不可復原;見 §3.4 DR-13。全文件用語、狀態機、事件、信件、AMS 與企業自助兩端 UI 已同步)
  • 版本(前):1.0.0(2026/05/13:Enterprise API v1 首版)
  • 對應 Storybook:企業端無 UI(v1);ops / AMS 後台有低保真 mockup:storybook/src/stories/mockups/siteadmin/EnterpriseApiKeyAdmin.stories.ts
  • Storybook 連結https://storybook.wport.me/?path=/docs/mockups-siteadmin-enterprise-api-key-admin-demo—docs
  • 建立日期:2026/05/13
  • PRD 代號:pm_37

2. 開發進度與設計來源

開發進度

  • 前端 PR #:N/A(v1 無前端)
  • 後端 PR #:[TBD]
  • Ops 後台 PR #:[TBD]

設計來源

  • Figma 連結:N/A(v1 無 UI 設計稿)
  • 競品對標(SaaS):Stripe API(key 命名、idempotency、live/test 分離)、GitHub REST API(PAT scope、rate limit header)、Anthropic API(usage 透明)、Shopify Admin API(partial success batch)

3. 功能摘要(Feature Summary)

3.1 功能概述

  • 功能名稱:Enterprise API v1(REST API for Job CRUD)
  • 主要使用者角色:企業端 Owner / Admin(透過程式呼叫 API)、wport ops(後台核發/管理 key)
  • 核心目標
    • 讓企業 HR 跳脫 wport 前端 UI 限制,透過程式化方式 batch 操作職缺(建立、編輯、上下架)
    • 為後續 v2(前端自助申請 + 企業端整合 UI)、v3(CLI 工具)、未來 MCP server 打基礎
    • 緊跟 AI 工具普及趨勢(Cursor / Claude)的整合需求

3.2 範圍界定

  • 包含範圍(v1)

    • REST API 端點:職缺 CRUD(含 batch)、上架/下架/刪除/關閉、列表查詢、單筆查詢
    • 認證機制:Bearer API Key(company-scoped、hash 儲存)
    • Quota:月度固定額度 + 分鐘級 rate limit + Idempotency-Key 必填(寫操作)
    • Audit log:全量記錄(caller_company_id、acting_user_id、endpoint、ip、result、latency)
    • Wport 後台 ops 介面:核發 / 刪除 / Rotate key、查 usage、設企業專屬 quota override
    • OpenAPI Spec:維護(為將來 SDK、MCP server 自動產出)
  • 排除範圍(明確 v1 不做)

    • 前端 Setting 頁面 API key 自助申請 UI(v2)
    • 企業端 UI 內的 API 整合區塊(v2)
    • CLI 工具產出(v3)
    • 付費升級流程 / 計費整合(架構預留,UI 不做)
    • 候選人 / 履歷相關 API(v1 收斂為職缺 CRUD;其他端點視 RD 時間納為 good-to-have)
    • 全平台人才搜尋 API
    • 應徵者列表 / 應徵狀態更新 API
    • Webhook 推送
    • IP allowlist
    • Key 過期機制 / user 自助 rotate
    • Test / Live key 分離
    • MCP server 實作(v1 僅維護 OpenAPI Spec 為基礎)

3.3 成功條件(KPI,3 個月內)

  • 申請 API key 的企業 ≥ 10 家
  • 月 API call 量 ≥ 50,000 次
  • 透過 API 建立的職缺 ≥ 500 筆
  • API 5xx 錯誤率 < 0.5%
  • API p95 latency < 500ms

3.4 設計決策依據(Design Rationale)

此節記錄 v1 主要設計選擇的「為什麼」,包含:選項對比、借鏡的主流 SaaS、以及 wport(人力銀行 / B2B / HR 用戶)情境下的判斷。 目的:讓 RD、未來 PM、QA、稽核人員讀 PRD 時不只看見規則,也理解規則的權衡來由。

DR-1:認證機制 → Bearer API Key(非 OAuth)

  • 選項:A. Bearer API Key(簡單 token) / B. OAuth 2.0 Client Credentials / C. mTLS
  • 採用:A
  • SaaS 對標:Stripe(Authorization: Bearer sk_live_...)、Anthropic API、OpenAI API、Shopify Admin API
  • wport context:v1 用戶是 HR + AI 工具(Cursor / Claude),不是企業 IT 工程師。Bearer key 在 curl / Python requests / Cursor agent 中最直觀;OAuth 需要 token refresh 邏輯,對非工程師用戶過度複雜。v2 高級企業客戶若需 SSO 整合,再升 OAuth。

DR-2:Key 綁定層級 → (user_id, company_id) 雙綁定

  • 選項:A. company-scoped(一公司一把) / B. user-scoped(個人 token) / C. (user, company) 雙綁定 / D. token-per-app(OAuth 風)
  • 採用:C
  • SaaS 對標
    • GitHub PAT(最直接對標):每個 user 在 organization context 下產 token,org admin 可看到組織內所有人的 token policy 並刪除
    • Linear Personal API Key:user-level 但 workspace admin 可見
    • Slack User Token vs Workspace Token:個人 token 仍歸屬於 workspace
  • wport context:統一帳號制度下一個 user 可能屬於多家公司;單純 user-scoped 無法表達「我用 A 公司身份操作」;單純 company-scoped 失去個人課責(key 外洩追不到人)。雙綁定同時滿足:個人歸屬(audit)+ 企業課責(usage 共享、Admin 可刪除)。

DR-3:每 user 每公司 1 把 key(經 Eric 確認

  • 選項:A. 1 把 / B. 3 把(dev/prod/CI 分流) / C. 5 把 / D. 無上限
  • 採用:A
  • SaaS 對標
    • Stripe restricted keys 允許多把(但用戶是工程師)
    • GitHub PAT 預設無上限(用戶是工程師)
    • Linear、Notion personal token 預設 1 把(用戶是 PM/設計師等非工程師)
  • wport context:v1 主要用戶為 HR(非工程師),每人一個工作流(接 Cursor / Claude / 自家 ATS),不需要 dev mindset 的多 key 分流。
  • 重要對話記錄(2026/05/13,Eric & PM Claude)

    「就一家公司的 hr 而言,不是應該是一家公司給予自己的就一把 key 就好?」

    • 原 PRD 提案「3 把/user」沿用工程師預設,被指出不符合 HR 用戶心智。
    • 結論:v1 採 1 把/user/company,需要重發者用 Rotate(舊 key 失效、發新 key)。
  • 延伸路徑:若 v2 後實際使用發現 HR 需區分 AI 工具 / ATS 整合 / 個人腳本,再放寬上限。

DR-4:申請角色 → Owner / Admin / Manager 皆可(Q1 = B,經 Eric 確認

  • 選項:A. 僅 Owner/Admin / B. Owner/Admin/Manager 皆可 / C. 所有成員(含 Member)
  • 採用:B
  • SaaS 對標
    • GitHub:org member 都能建 PAT,org owner 用 policy 限制 scope,不限制建立行為
    • Linear:workspace member 都能建 personal API key
  • wport context:BR-016 規定 Manager 可建立 / 編輯 / 發布職缺;既然能用 UI 發職缺,沒有理由禁止透過 API 做同樣的事。Member 仍排除(無職缺操作權)。
  • 未來延伸(v2):可在公司 settings 加 allow_manager_apply switch 讓嚴格管控的企業關閉 Manager 自助申請;v1 預設全開(簡化)。

DR-5:Key 上限以 user×company 計算(取代「每公司硬上限」)

  • 舊設計問題:原 PRD「單公司 5 把」對 10 人 HR 團隊不夠(10 × 1 = 10 > 5)
  • 新規則:每 (user, company) 1 把 → 公司總 key 數隨成員自然成長,無硬上限
  • Admin 控制權:Owner / Admin 可(v1 透過 ops、v2 透過前端)看到公司下所有人的 key 並一鍵刪除 → 此即 governance 控制點
  • SaaS 對標:GitHub Organization PAT Policy:org 不限總數,但 admin 可審批 / 刪除

DR-6:Key 命名前綴 wpk_live_

  • 採用wpk_live_<32 chars>
  • SaaS 對標:Stripe sk_live_ / pk_live_ / rk_live_
  • wport context:前綴 = secret scanning 入口(GitHub secret scanning、GitGuardian 可加 wport 規則自動偵測 push 到 git 的 key);明確區隔 live / test(v2 加 test)。

DR-7:Idempotency-Key 強制必填於寫操作

  • 採用:必填於 POST / PATCH / DELETE,TTL 24 小時
  • SaaS 對標:Stripe(同設計,TTL 24h)
  • wport context:HR batch 上傳 100 筆職缺,網路抖動 / 程式 bug 重試最常見;不強制必填會造成重複建職缺,事後清理痛苦。

DR-8:Quota 共享於 company 層級(不分 user)

  • 採用:5000 calls/month per company(usage 跨該公司所有 user × key 加總)
  • SaaS 對標:Stripe(org-level pricing)、Linear(workspace-level seat & API limit)
  • wport context:付費未來會接 company-level plan(企業付費),usage 必須 company-level 才能對齊計費單位。

DR-9:v1 排除 candidate / 履歷 API

  • 排除理由:v1 收斂為「職缺 CRUD」可在 1 個 sprint 完成 MVP;候選人 API 涉及大量 BR-017 細節(目前 BR-017 標「待確認」),先別開
  • SaaS 對標:OpenAI 初期僅開 completion,再逐步加 fine-tune / embeddings — 漸進開放
  • 後續:v1.1 補完 BR-017 細節後可加 candidate read API

DR-10:v1 不做前端 UI,ops 人工核發

  • 採用:v1 申請流程 = user email 給 wport → ops 後台核發 → 寄信
  • SaaS 對標
    • OpenAI GPT-4 API 初期:waitlist + 人工核發
    • Anthropic API 初期:design partner 邀請制
  • wport context:v1 預期 < 50 把 key,人工成本可接受;早期需要 ops vet 用戶、收集反饋。v2 才上自助 UI。

DR-11:Batch 採 Partial Success

  • SaaS 對標:Shopify Admin API、Slack chat.scheduleMessage batch、HubSpot batch endpoints
  • wport context:HR batch 100 筆,1 筆格式錯不該整批 rollback(重試成本、quota 浪費)

DR-12:維護 OpenAPI Spec(v1 即做)

  • 採用:v1 必須維護 openapi.yaml
  • SaaS 對標:Stripe、Twilio、GitHub 都以 OpenAPI 為 SDK / 文件 / 自動化基礎
  • wport context:v2 SDK、v3 CLI、未來 MCP server 全依賴此 spec;若 v1 不做,技術債在 v2 爆發

DR-13:金鑰終態動作 → 「刪除」(硬刪除、不可復原),取代「撤銷」(Eric 2026/08/18 裁決

  • 改動:v1.0.0 的「撤銷 / Revoke」全面改名為「刪除 / Delete」;行為同步由「保留該列、狀態改 revoked」改為「硬刪除:該筆自列表永久移除、不可復原」。
  • 選項
    • A. Revoke —— 保留列、狀態標 revoked(v1.0.0 原設計)
    • B. Delete —— 硬刪除,列表不留任何一列(採用)
    • C. 字面叫 Delete、實作 soft delete(DB 留 deleted_at、UI 永久隱藏)
  • 採用B(文案與資料行為一致)。C 僅作為 RD 若需短期 debug 保留的可接受退路,但對外契約不變:刪除後查不到、列不出、無法復原,且 API 不得因此洩漏該 key 曾存在。
  • SaaS 對標
    • GitHub PAT / fine-grained token:動作即 Delete,刪除後 token 自清單消失,歷史只在 audit log
    • Stripe restricted key:提供 Delete,刪除後不再出現於 API keys 清單
    • Google Cloud API key:終態動作為 Delete key
    • AWS IAM access keyDeactivate(可逆中間態)+ Delete(終態) 兩段式;wport v1 無「停用」需求,只取終態
    • 反例(刻意不沿用):OAuth 授權情境才叫 Revoke(收回「已授予的存取」,憑證本體仍在)。wport 個人線 CLI 走 OAuth(pm_47 / pm_41 wport sessions revoke維持 revoke 用語,與本節的公司金鑰刪除不混用
  • wport context
    • 使用者是 HR(非工程師)。中文「撤銷」的心智接近「作廢但東西還在」,而 HR 的實際意圖是「這把不要了,清掉」。與 DR-3 / DR-4 同一條原則:以 HR 心智選詞,不沿用工程師語彙
    • 金鑰列表是操作面板、不是歷史檔案。pm_41 每公司上限 10 把,若撤銷後仍佔一列,列表很快被殘影塞滿,還得再補「隱藏已撤銷」篩選才可用;改為刪除後,列表恆等於「目前有效的整合」,也讓「達上限 → 清掉不用的」動線成立。
  • 權衡(trade-off)與代價
    • 失去列表上的「撤銷於 YYYY-MM-DD」線索 → 改以 audit log 為唯一歷史來源(§5.2 ApiAuditLog,保留 365 天,含刪除者、時間、AMS 端理由)。這是本決策唯一實質代價,接受;代價落在 support 追溯,必須查 log 而非查列表。
    • 誤刪不可復原 → 以二次確認彈窗(§6.2 OPS-2、企業自助端 Storybook)緩解;不做垃圾桶 / 復原期——HR 場景無此需求,且與「刪了就是刪了」的資安直覺相衝,保留期反而讓外洩金鑰的失效時點變得模糊。
    • 401 語義簡化且更安全:key 已不存在,系統無從區分「被刪」與「根本沒這把」,統一回 invalid_api_key(不再有 revoked_api_key)——順帶避免對外洩漏「這把 key 曾經存在」。
  • 影響面:§5.2 狀態機去掉 revoked 終態、§10.3 / §10.5、事件改名 enterprise_api_key_deleted(§13.3)、§17.2 改為刪除通知信、§13.4 術語字典;AMS 後台與企業自助端(pm_41 軌道 A / B)UI 文案與 API(DELETE /:enc_id)一致;前端正式站 i18n companyApiKey.revoke.* 須改名(§16)。

4. 商業規則對齊(Business Rules Alignment)

4.1 本功能使用到的業務規則

規則 ID規則摘要是否關鍵在本 PRD 的對應
BR-001email 驗證後才能登入✅ 是申請者 email 必須已驗證
BR-005公司未驗證可建職缺但無法上架✅ 是API 可建 draft,publish endpoint 強制檢查公司驗證狀態
BR-008職缺發布必填欄位✅ 是API publish 強制檢查同一組必填欄位
BR-009職缺狀態機(含終態不可逆)✅ 是API 操作對齊狀態機;deleted/closed 為終態
BR-016角色權限矩陣(Owner/Admin/Manager/Member)✅ 是僅 Owner/Admin 可申請 + 使用 API
BR-017資料存取控制✅ 是API caller 僅可操作所屬公司資源
BR-018電子郵件發送規則⚠️ 補充本 PRD 提案新增通知類型:API key 核發 / 刪除 / Rotate 通知信
BR-022每帳號最多建立 10 間公司➖ 相關API key 為 company-scoped,多公司需各自申請 key
公司職缺上限 800(BR-005 區塊註記)✅ 是API 達 800 上限 → 429 jobs_quota_exceeded

4.2 補充說明 / 新規則提案

  • BR-018 提案補充:新增以下 email 通知類型(待落地後正式回寫 business-rules.md):
    • enterprise_api_key_issued:核發 key(含明文 key 一次性顯示,CTA:開發者文件連結)
    • enterprise_api_key_deleted刪除 key 通知(DR-13)
    • enterprise_api_key_rotated:Rotate key 通知(含新 key 明文一次性顯示)
    • enterprise_api_quota_warning:[v2] 達 80% quota 通知(v1 不做)
  • BR-020「資料匯出規則」釐清:BR-020 為「使用者個資匯出(GDPR 等)」用途,與本 Enterprise API 無關。Coda 原命名「資料匯出 API」屬語意混淆,已於 Stage 9 改名。
  • 企業職缺 quota 透通:v1 沿用既有 800 上限,不在 API quota 中重新計算。
  • 角色限制(新):v1 開放 Owner / Admin / Manager 申請與使用;Member 不可申請。
    • 理由(見 DR-4):BR-016 規定 Manager 可建立 / 編輯 / 發布職缺;既然 Manager 能用 UI 發職缺,沒有理由禁止透過 API 做同樣事。Member 無職缺操作權,故排除。
    • v2 延伸:未來可加 allow_manager_apply per-company policy switch,讓嚴格管控企業關閉 Manager 自助申請。
  • Key 綁定模型(新,見 DR-2、DR-3、DR-5):API key 為 (user_id, company_id) 雙綁定;每 user 在每家公司最多 1 把 active key;公司總 key 數無硬上限(自然隨成員數成長);Owner / Admin 對公司下所有人的 key 有刪除權
  • 金鑰終態動作(新,見 DR-13):終態動作為 刪除(Delete)=硬刪除——確認後該 key 自所有列表永久消失、不可復原,無 revoked 狀態;歷史僅存於 ApiAuditLog(365 天)。刪除後任何以該 key 的呼叫一律回 401 invalid_api_key

5. 資料實體與欄位(Data Entities & Fields)

注意:本節描述的是「需要追蹤 / 儲存的資訊」,不是 API payload schema。
API 的具體欄位名稱、JSON 結構、optional/required 等由 OpenAPI Spec 決定(RD 責任)。

5.1 實體列表與需求

實體用途必須追蹤的資訊
ApiKey企業端認證憑證綁定關係(user + company)、金鑰內容、狀態、時間戳記、使用記錄
ApiUsage月度 quota 管理公司、月度週期、已用額度、設定上限、重置時間
ApiAuditLog稽核與監控金鑰 ID、公司、呼叫者(user)、HTTP method、endpoint、IP、status code、錯誤碼、延遲、時間戳記
IdempotencyRecord寫操作去重idempotency key、請求指紋、回應、過期時間(24h)
Job職缺(既有)API 操作時須檢查:company_id、status(狀態機)、updated_at(樂觀鎖)、必填欄位集合

5.2 實體資料需求說明

ApiKey

為什麼需要:認證 + 課責
必須儲存

  • (user_id, company_id) 雙綁定(DR-2):支持個人課責 + 企業管理
  • Key 狀態:pending → active → deleted(=資料列消失) / rejected(狀態機,§10.3)
  • 時間軸:建立時間、啟用時間(無「刪除時間」欄位——列都不在了;刪除時間記在 audit log,DR-13)
  • 使用履歷:最後使用時間(用於監控活躍度)
  • 唯一性約束:每 (user, company) 最多 1 把 active key(DR-3);刪除後該名額立即釋出,可馬上重新申請
  • Rotate 行為:舊 key 刪除;新 key → active(同一交易內完成,避免中間態)

注意

  • 金鑰本身只需儲存 hash(+ salt;演算法由 RD 決定,見 §15)
  • 明文僅核發信中一次性顯示
  • 前綴 wpk_live_ 用於識別(不需特別儲存字首,生成時包含)
  • 刪除=硬刪除(DR-13):不留 revoked 狀態列。若 RD 因除錯需要採 soft delete,對外行為必須等同硬刪除(查不到、列不出、不可復原、不得洩漏曾存在)

ApiUsage

為什麼需要:計費 + 限流
必須追蹤

  • Quota 聚合層級:公司(不分 user),跨該公司所有 key 加總(DR-8)
  • 月度週期:YYYY-MM 格式(UTC+8 時區)
  • 已用額度:本月累計 API call 次數
  • 設定上限:預設 5000;ops 可 override per-company(§8.5、DR-8)
  • 重置時間:下月 1 日起算

注意

  • 與既有公司職缺上限(800)分開追蹤;不衝突

ApiAuditLog

為什麼需要:稽核 + 監控 + 故障排查
必須記錄

  • 身份:api_key_id、company_id、acting_user_id(key 申請者)
  • 請求:HTTP method、endpoint、請求 ID、idempotency key
  • 網路:caller IP、user agent
  • 回應:HTTP status code、錯誤碼、端到端延遲(ms)
  • 時間:API 呼叫時間戳記

注意

  • 異步寫入(不阻擋 API 回應)
  • 保留 365 天(§8.5)
  • 不在 log 中明文記錄 key(§12.3)
  • key 刪除是唯一歷史來源(DR-13):key 生命週期事件(核發 / 改名 / Rotate / 刪除)須同樣落 log,至少含 api_key_id、key 名稱與遮罩前綴快照、操作者、時間、AMS 端刪除理由;否則 key 硬刪除後 support 完全無從追溯

IdempotencyRecord

為什麼需要:寫操作去重
必須儲存

  • Idempotency-Key:client 提供的去重識別符
  • 請求指紋:method + endpoint + payload hash(識別相同請求)
  • 快取內容:原始回應(status code + body)
  • 過期策略:24 小時後自動清理(DR-7)

注意

  • Scope:per api_key_id(不同 key 的相同 key 字串視為不同)
  • 儲存位置自由(Redis 或 DB;由 RD 決定)

Job(既有,API 操作涉及的欄位)

API 需要檢查的

  • 所有權:company_id 必須 = caller key 的 company_id(§7.1 ACT-5~9)
  • 必填欄位:發布時需檢查對齊 BR-008 規定的集合
  • 樂觀鎖:更新時需對比 updated_at / version(§10.5 並發更新)
  • 狀態機:操作需對齊 BR-009(§10.4)

注意

  • Job 的欄位結構由既有 schema 決定,API 不改變;本 PRD 只列出 API 操作時關鍵的檢查點

6. 畫面區塊與資料需求(UI Sections & Data Needs)

v1 無 wport 企業端 UI;本節改為描述 wport ops 後台介面API caller 視角的「行為輸入輸出」

6.1 區塊列表

區塊 ID區塊名稱說明屬於
OPS-1API Key 申請佇列顯示 pending 申請列表ops 後台
OPS-2API Key 管理列出所有 key、可核發 / 刪除 / Rotate / 改名ops 後台
OPS-3Usage 監控每企業月度用量、超限警示ops 後台
OPS-4Quota 設定設定企業專屬 quota overrideops 後台
OPS-5Audit Log 檢視查詢稽核日誌(依 company / 時間 / endpoint)ops 後台

6.2 區塊資料需求

OPS-1:申請佇列

  • 顯示實體:ApiKey[] where status='pending'
  • 篩選:公司名稱、申請時間
  • 操作:核發(自動觸發郵件)、駁回(含理由)

OPS-2:Key 管理

  • 顯示:ApiKey[] 全狀態(刪除者不再出現,DR-13)
  • 列表欄位:company_name、user_email(key 申請者)、key_prefix、status、created_at、last_used_at
  • 篩選:依公司、依 user、依狀態(狀態選項不含 revoked
  • 操作:刪除、Rotate(產生新 key 並使舊 key 失效)、改名
  • 刪除互動(DR-13):需二次確認彈窗,明示「永久移除、無法復原」+ key 名稱;AMS 端刪除理由必填(稽核 / support 追溯用,缺 reason → 400),企業自助端免填(pm_41 BR-API-CLI-005)。確認後該列自列表消失,歷史查 audit log(OPS-5)
  • Admin 視角預備(v2):v2 前端 UI 啟用時,Owner / Admin 可在公司 settings 看到此公司下所有 user 的 key 並刪除;v1 透過 ops 代為操作

OPS-3:Usage 監控

  • 顯示:當月 ApiUsage[] 排行
  • 警示:使用率 ≥ 80% / 100%
  • 排序:依使用率 DESC

OPS-4:Quota 設定

  • 預設值:5000 calls/month
  • override 機制:per-company 設定,後續可 per-key

OPS-5:Audit Log

  • 篩選:company、api_key、endpoint、time range、status_code、error_code
  • 分頁:每頁 100 筆
  • 匯出:CSV(ops 內部使用,不對外)

7. 使用者動作與後端需求(User Actions & Backend Needs)

7.1 企業端(API caller)

動作 ID動作類型需要後端涉及實體說明
ACT-1建立單筆職缺WriteJob必填驗證、寫入
ACT-2Batch 建立職缺WriteJob單次 ≤ 100 筆、partial success
ACT-3列出自家職缺ReadJobpagination + 篩選
ACT-4取得單筆職缺ReadJobby enc_id
ACT-5更新職缺WriteJoboptimistic lock
ACT-6上架職缺WriteJob強制驗證 BR-005、BR-008
ACT-7下架職缺WriteJob狀態轉換
ACT-8刪除職缺WriteJob進入終態
ACT-9關閉職缺WriteJob進入終態

7.2 Ops 後台

動作 ID動作類型需要後端涉及實體
OPS-ACT-1核發 keyWriteApiKey
OPS-ACT-2駁回申請WriteApiKey
OPS-ACT-3刪除 key(硬刪除,DR-13)WriteApiKey
OPS-ACT-4Rotate keyWriteApiKey
OPS-ACT-5設定 quota overrideWriteApiUsage
OPS-ACT-6查 audit logReadApiAuditLog

8. API Hints(提示用,非最終 API 設計)

URL path、HTTP status code、payload schema 由後端最終決定。

8.1 認證

  • Authorization: Bearer wpk_live_<32 chars>
  • 必填 headers:AuthorizationIdempotency-Key(POST/PATCH/DELETE 必填)、X-Request-ID(選填,建議 client 提供 UUID)
  • 回應 headers:X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-ResetX-Request-ID

8.2 統一錯誤格式(建議參考 RFC 7807 簡化版)

{
  "error": {
    "code": "company_not_verified",
    "message": "Company verification is required before publishing jobs.",
    "details": { "company_id": 123, "verification_status": "pending" },
    "request_id": "req_abc123"
  }
}

8.3 資料讀取需求(Read)

  • HINT-GET-1:列出自家職缺
    • 輸入:page / cursorstatus?updated_after?limit?(預設 20,max 100)
    • 對應動作:ACT-3
  • HINT-GET-2:取得單筆職缺
    • 輸入:enc_id
    • 對應動作:ACT-4

8.4 資料寫入需求(Write)

  • HINT-MUTATION-1:建立職缺(單筆 / batch)
    • 輸入:Job payload(必填欄位對齊 BR-008)
    • Idempotency-Key 必填
    • 行為:建立為 draft;公司已驗證且帶 publish=true 參數可直接上架(或拆開 endpoint,[RD 決定])
  • HINT-MUTATION-2:更新職缺
    • 輸入:enc_id、partial payload、If-Match: <updated_at> 或 version
  • HINT-MUTATION-3:狀態轉換(publish / unpublish / close / delete)
    • 輸入:enc_id
    • 行為:對齊 BR-009 狀態機
  • HINT-MUTATION-4:Batch 建立
    • 輸入:{ jobs: Job[] } 單次 ≤ 100
    • 回應:partial success(succeeded[] + failed[])

8.5 Quota / Rate Limit 設定(建議值,[RD 決定])

維度預設值可 override
月度 quota5000 calls / month per company(usage 跨該公司所有 user 加總,DR-8)per-company override
分鐘級 rate limit60 calls / minuteper-key
Batch 單次上限100 筆全域
Idempotency TTL24 小時全域
Audit log 保留365 天全域
每 (user, company) active key1 把(DR-3)無 override(v1)
公司總 key 數無硬上限(自然隨成員增長,DR-5)

8.6 OpenAPI Spec 維護要求

  • v1 必須維護 openapi.yaml,作為:
    • 文件來源(自動產 reference docs)
    • 將來 SDK 生成(TypeScript / Python)
    • 將來 MCP server 自動橋接基礎
  • 路徑:[RD 決定],建議 /api/v1/enterprise/openapi.yaml 公開

9. 導航 / Storybook Map

v1 企業端無前端 UI;下列為 ops / AMS 後台的低保真 mockup(治理面,非企業端)。

  • Storybook 標題Mockups/Siteadmin/EnterpriseApiKeyAdmin
  • Stories 路徑storybook/src/stories/mockups/siteadmin/EnterpriseApiKeyAdmin.stories.ts
  • Storybook 連結https://storybook.wport.me/?path=/docs/mockups-siteadmin-enterprise-api-key-admin-demo—docs
  • 情境控制initialScreen(list / empty / loading / error / issue / onetime / detail / rename / rotate / quota / delete)、initialOrigin(issue / rotate)
  • 相關(企業自助端,pm_41 軌道 A)Mockups/公司/API 金鑰自助申請mockups-company-apikeyselfservice)——刪除確認彈窗沿用正式站企業後台 CommonDialog 樣式(naive-ui n-modal preset="dialog":550px / 圓角 12px / 標題置中 / footer 197×197 / 危險鈕 error 紅)
  • 對應 production 路由
    • 企業 API:/api/v1/enterprise/*(namespace 獨立)
    • Ops 後台:既有後台路由擴充([RD/ops 決定])

10. Flowcharts(User / System / State Machines)

10.1 User Flow(含 ops 流程)

flowchart TD
    Start([HR / 企業成員想用 API]) --> Apply[user 個人 email 申請<br/>註明:以 X 公司 Y 角色申請]
    Apply --> OpsRecv{ops 收件並檢核}
    OpsRecv -- 公司未驗證 --> Reject1[寄駁回信<br/>引導完成公司驗證]
    OpsRecv -- 申請者角色非 O/A/M --> Reject2[寄駁回信<br/>需 Owner/Admin/Manager 申請]
    OpsRecv -- email 未驗證 --> Reject3[寄駁回信<br/>需先完成 email 驗證]
    OpsRecv -- 該 user×company 已有 active key --> Reject4[寄信提示已有 key<br/>建議聯繫 Rotate]
    OpsRecv -- 全部符合 --> Issue[ops 後台核發 key<br/>系統寄發明文 key 信件給該 user]
    Reject1 --> End1([結束])
    Reject2 --> End1
    Reject3 --> End1
    Reject4 --> End1
    Issue --> Use[user 使用 key 呼叫 API]
    Use --> Op{API 操作類型}
    Op -- 建立職缺 --> CreateFlow[必填驗證 → 寫入 DB]
    Op -- 上架職缺 --> PublishFlow{公司已驗證?}
    PublishFlow -- 否 --> PublishFail[403 company_not_verified]
    PublishFlow -- 是 --> PublishOk[狀態 → published]
    Op -- 其他 CRUD --> OtherFlow[依資源狀態決定]
    CreateFlow --> Done([API 回應])
    PublishOk --> Done
    PublishFail --> Done
    OtherFlow --> Done

    subgraph 異常路徑
        Quota[公司達月度 quota<br/>跨該公司所有 user 加總] --> Q429[429 quota_exceeded]
        Delete[ops / Admin 刪除 key(硬刪除)] --> R401[後續 call 401 invalid_api_key]
    end

10.2 System Flow(API call lifecycle)

sequenceDiagram
    participant C as Client (企業)
    participant GW as API Gateway
    participant Auth as Auth Service
    participant RL as Rate Limiter (Redis)
    participant Idem as Idempotency Store
    participant H as Handler (Job Service)
    participant DB as DB
    participant Audit as Audit Log (async)

    C->>GW: POST /api/v1/enterprise/jobs<br/>Authorization: Bearer wpk_live_xxx<br/>Idempotency-Key: uuid

    GW->>Auth: 驗證 key (hash 比對)
    alt key invalid / 已被刪除
        Auth-->>GW: 401
        GW-->>C: 401 invalid_api_key
        GW->>Audit: log (async)
    else valid
        Auth-->>GW: company_id + scopes
    end

    GW->>RL: 檢查 quota & rate limit
    alt 超限
        RL-->>GW: 429 + reset_at
        GW-->>C: 429 quota_exceeded
        GW->>Audit: log (async)
    else 通過
        RL-->>GW: ok
    end

    GW->>Idem: 查 Idempotency-Key
    alt 已存在 (重放)
        Idem-->>GW: cached response
        GW-->>C: 200 (原回應)
    else 不存在
        Idem-->>GW: not found
        GW->>H: 執行業務邏輯
        H->>DB: 寫入 (transaction)
        DB-->>H: ok
        H-->>GW: result
        GW->>Idem: cache response (TTL 24h)
        GW->>RL: usage += 1 (atomic)
        GW-->>C: 200 / 201
        GW->>Audit: log (async)
    end

10.3 API Key 狀態機

stateDiagram-v2
    [*] --> Pending: 企業申請
    Pending --> Active: ops 核發
    Pending --> Rejected: ops 駁回
    Active --> Deleted: ops / Admin 刪除、Rotate(舊 key)
    Rejected --> [*]
    Deleted --> [*]
    note right of Active: 永久有效直到被刪除<br/>v1 無 user-side rotate
    note right of Deleted: 終態=資料列消失(硬刪除,DR-13)<br/>不留 revoked 狀態;歷史只在 audit log

10.4 職缺狀態機(API 視角,對齊 BR-009)

stateDiagram-v2
    [*] --> Draft: POST jobs
    Draft --> Published: PATCH publish<br/>(必填齊 + 公司驗證)
    Published --> Unpublished: PATCH unpublish
    Unpublished --> Published: PATCH publish
    Draft --> Deleted: DELETE
    Published --> Deleted: DELETE
    Unpublished --> Deleted: DELETE
    Published --> Closed: PATCH close
    Unpublished --> Closed: PATCH close
    Deleted --> [*]: 終態
    Closed --> [*]: 終態

10.5 Edge Case Coverage(必填)

類別情境系統行為API 回應可重試資料一致性策略備註
Network & PerformanceAPI call 逾時 > 30sgateway 切斷、不寫入504 gateway_timeoutYes(搭 Idempotency-Key)寫操作未提交 → 0 副作用
Network & Performance高延遲 batch同步至完成或 60s 上限200 partial / 504Yes成功筆數已落地,失敗可重送
Network & Performance重複提交(race)Idempotency-Key 去重重放回原 responseN/A同 fingerprint 視為同一筆
Data & Input必填欄位缺漏BE 驗證拒絕400 missing_required_field + fieldN/A不寫入
Data & Input欄位超長 / 格式錯BE 驗證拒絕422 invalid_value + field + reasonN/A不寫入
Data & InputBatch 超過 100 筆gateway 拒絕413 payload_too_largeN/A不寫入
Data & InputJSON 解析失敗gateway 拒絕400 invalid_jsonN/A不寫入
User InterruptionClient 中途斷線BE 可能已提交;client 重連用 Idempotency-Key 安全重送YesIdempotency 確保 0 副作用
User Interruption瀏覽器關閉N/A純 API 場景無瀏覽器
User Interruption重新整理N/A純 API 場景
Auth & LifecycleKey 於呼叫途中被刪除進行中 call 完成、下一個 401401 invalid_api_key(不再有 revoked_api_key;不揭露該 key 曾存在,DR-13)No(需重新申請)已完成 call 結果保留
Auth & Lifecycle公司被停用立即拒絕後續 call403 company_suspendedNo
Auth & Lifecycle並發更新同職缺optimistic lock (updated_at / version)409 conflict + 最新資料Yes(client 解決後)後到失敗、不覆寫
Logical InconsistencyBatch partial success部分成功部分失敗200 + succeeded[] + failed[]失敗項 Yes成功項已落地、失敗項可重送
Logical Inconsistency公司未驗證卻 publish拒絕;草稿保留403 company_not_verifiedYes(驗證後)草稿仍存在
Logical Inconsistency終態職缺被改 / 上下架拒絕409 invalid_state_transitionNoBR-009
Logical InconsistencyIdempotency-Key 衝突同 key 不同 payload409 idempotency_conflictNo(換 key 或修 payload)
Auth & Lifecycle重複刪除同一把 key(並發 / 重送)第一次成功,之後查無此 key404 api_key_not_foundNo硬刪除後無列可刪,non-idempotent 差異僅在狀態碼DR-13
Logical Inconsistency越權操作resource.company_id ≠ key.company_id403 forbidden(write)/ 404(read)No不洩漏資源存在性(read)

11. Mock Data Schema

  • 資料來源:v1 無前端 UI,無 mock;後端直接對接既有 Job service + 新增 ApiKey / ApiUsage / ApiAuditLog 表
  • CRUD 行為:透過真實 API 操作真實 DB;ops 後台亦操作真實資料
  • 情境切換:N/A

12. 實作備註(Implementation Notes)

12.1 後端必做事項

  • API namespace 獨立:/api/v1/enterprise/*
  • 重用既有 Job service / 公司驗證 service,不雙寫
  • API key 一律 hash + per-key salt 儲存;明文僅核發信中一次性顯示
  • Rate limiter 建議 Redis sliding window;DB counter 為退路(注意競態)
  • Audit log 異步寫入(建議 queue),不阻塞 API 回應;保留 365 天
  • Key 刪除為硬刪除(DR-13):DELETE /admin/enterprise-api-keys/:enc_id,刪除前先落 audit log(含 key 名稱 / 遮罩前綴快照、操作者、理由),再刪列;刪除後同 key 呼叫一律 401 invalid_api_key,快取 / rate limiter 內的 key 記錄同步失效
  • OpenAPI Spec 必須維護(為 v2/v3、SDK、未來 MCP 鋪路)
  • 預留付費擴充:DB schema 設計時保留 plan_idquota_override_reasonpaid_quota_addon 等欄位(不實作 UI)

12.2 後端可決定事項(標註 [RD 決定]

  • 具體 endpoint URL 命名(如 POST /api/v1/enterprise/jobs vs POST /api/v1/enterprise/job/create
  • Token 編碼(opaque random vs JWT);hash 演算法(SHA-256 建議)
  • Rate limiter 實作(Redis vs DB)
  • Pagination 機制(cursor 建議 vs offset 可接受)
  • Publish 是否拆獨立 endpoint(PATCH /jobs/{id}/publish vs POST /jobs?publish=true
  • v1 是否一併支援 good-to-have endpoint(應徵者列表、人才搜尋等)
  • Idempotency cache 後端選擇(Redis vs DB)

12.3 禁止事項

  • ❌ 不直接修改 business-rules.md;新規則先於本 PRD 描述
  • ❌ 不對外洩漏 candidate PII 超出既有 UI 範圍
  • ❌ 不在 v1 做付費 UI / 自助申請 UI / CLI
  • ❌ 不在 logs 中明文記錄 API key

12.4 對齊 SaaS 業界實踐

  • Key 命名 wpk_live_<32>:借鏡 Stripe sk_live_,前綴利於 secret scanning(如 GitHub secret scanning 對接)
  • Idempotency-Key + 24h TTL:借鏡 Stripe
  • Partial success batch:借鏡 Shopify / Slack
  • Rate limit header(X-RateLimit-Remaining 等):借鏡 GitHub
  • OpenAPI Spec 維護:借鏡 Stripe / Twilio(SDK 自動產出基礎)

13. 四大一致性表格(v1 凍結)

13.1 欄位對照表

欄位型別用途SoT版本
api_key.enc_idstring對外 IDPRD(本 PRD)v1
api_key.company_idint綁定公司(雙綁定)PRD §5.2、DR-2v1
api_key.user_idint綁定 user(雙綁定)PRD §5.2、DR-2v1
api_key.key_prefixstring wpk_live_識別 + scanningPRD、DR-6v1
api_key.statusenum(pending / active / rejectedrevoked,刪除即刪列,DR-13)狀態PRD(本 PRD §5.2)v1.1
api_usage.periodstring YYYY-MM月度聚合PRDv1
api_usage.limitint(預設 5000)月額度(company-level,DR-8)PRD(可由 ops override)v1
job.statusenum職缺狀態business-rules.md BR-009既有
job.* 必填集上架條件business-rules.md BR-008既有

13.2 常數表

常數來源版本
月度預設 quota(per company)5000 calls/monthPRD §8.5、DR-8v1
分鐘 rate limit60 calls/minPRD §8.5v1
Batch 上限100 筆PRD §8.5、DR-11v1
Idempotency TTL24 小時PRD §8.5、DR-7v1
Audit log 保留365 天PRD §8.5v1
Key 命名前綴wpk_live_PRD §12.4、DR-6v1
每 (user, company) active key1 把PRD §8.5、DR-3v1
公司總 key 數無硬上限PRD §8.5、DR-5v1
申請角色Owner / Admin / ManagerPRD §4.2、DR-4v1
公司職缺上限800business-rules.md BR-005 區塊既有

13.3 事件字典

事件名觸發時機Payload 摘要訂閱者
enterprise_api_key_issuedops 核發 key{ company_id, api_key_id, plain_key(明文一次性)}Email service
enterprise_api_key_deletedops / 企業端刪除(硬刪除){ company_id, api_key_id, key_name, reason? }Email service、Audit log
enterprise_api_key_rotatedops Rotate{ company_id, api_key_id, new_plain_key }Email service
enterprise_api_call_completedAPI 完成(成功/失敗){ company_id, api_key_id, endpoint, status, latency }Audit log (async)
enterprise_api_quota_warning[v2] 達 80%

13.4 術語字典

定義用法統一
API Key企業端認證憑證;(user, company) 雙綁定(DR-2)不稱「Token」「Secret」「Credential」
Quota月度可用 API call 額度不稱「Limit」(避免與 rate limit 混淆)
Rate Limit分鐘級限流不稱「Quota」
Idempotency-Key重試去重識別統一 header 命名
Delete / 刪除永久移除 key(硬刪除、不可復原,DR-13)不稱「Revoke」「撤銷」「Disable」「停用」;OAuth 授權情境(pm_47 個人線)才用 Revoke,兩者不混用
Rotate產生新 key 並使舊 key 失效不稱「Refresh」「Regenerate」
Enterprise API本功能對外名稱不再稱「資料匯出 API」

14. 版本凍結表

項目v1 / v2Blocking?理由決策者日期
REST API(職缺 CRUD)v1✅ Blocking核心Eric2026/05/13
API Key 認證(Bearer)v1✅ Blocking核心Eric2026/05/13
後台核發 / 刪除 / Rotatev1✅ Blocking無 UI 必要替代Eric2026/05/13
金鑰終態動作=刪除(硬刪除、不可復原)v1✅ Blocking文案與資料行為一致;見 DR-13Eric2026/08/18
刪除後的垃圾桶 / 復原期不做❌ Non-blocking與「刪了就是刪了」的資安直覺相衝;HR 場景無需求(DR-13)Eric2026/08/18
Quota / Rate limit + 429v1✅ Blocking防濫用Eric2026/05/13
Idempotency-Keyv1✅ Blocking防重複寫入Eric2026/05/13
Audit logv1✅ Blocking法遵 / 監控Eric2026/05/13
OpenAPI Spec 維護v1✅ Blocking為 v2/v3 / MCP 鋪路Eric2026/05/13
應徵者 / 人才搜尋 APIv1(good-to-have)❌ Non-blocking後端視時間決定Eric + RD2026/05/13
前端 Setting 自助申請v2❌ Non-blocking獨立 PRDEric2026/05/13
企業 UI 整合區塊v2❌ Non-blocking獨立 PRDEric2026/05/13
CLI 工具v3❌ Non-blocking獨立 PRDEric2026/05/13
MCP server 完整實作未定❌ Non-blockingv1 僅維護 OpenAPI 為基礎Eric2026/05/13
付費 UI / 計費未定❌ Non-blocking架構預留Eric2026/05/13
Webhook / IP allowlist / Test key未定❌ Non-blockingv2+Eric2026/05/13

15. Token / API 契約完整性(Hard Gate)

項目規範
TTL(key 有效期)永久有效直到被刪除(v1);v2 可加 expiry option
Delete(刪除)政策ops 後台 / 企業端立即執行硬刪除;下一個 call 回 401 invalid_api_key;進行中 call 不中斷;不可復原、無垃圾桶;歷史僅存 audit log(DR-13)
Expiration 行為N/A(v1 無自動過期)
Idempotency必填於所有寫操作;TTL 24h;同 key 不同 payload → 409 conflict
即時權限重檢每次 call 重新驗證 key.status + company.status(從快取或 DB)
Hash 演算法SHA-256 + per-key salt(建議,[RD 最終決定])
明文顯示僅核發信中一次性顯示;DB 不存明文

16. Sync-Fix List(跨產出物同步動作)

動作物件OwnerBlocking?預定完成
更新 Coda backlog i-uL6dSrzo8o 名稱為「Enterprise API(v1:REST API for Job CRUD)」並回寫 PRD 欄位coda/coda_backlog.jsonEric✅ Blocking 上線Stage 9(本次 commit)
提案補充 BR-018 通知類型(key 核發 / 刪除 / Rotate)business-rules.mdEric⚠️ 本案落地後正式回寫上線後
維護 OpenAPI Spec 並建立 reference docs siteRDRD✅ Blocking v1 上線RD spec 階段
後台 ops 介面擴充(OPS-1 ~ OPS-5)wport 後台ops + RD✅ Blocking v1 上線RD spec 階段
Email template 建立(3 種新 type)通知服務RD✅ Blocking v1 上線RD spec 階段
Secret scanning rule(wpk_live_ 前綴)GitHub / GitGuardianDevOps❌ Non-blocking(建議)上線前
DR-13 用語同步:撤銷 → 刪除(軌道 A 自助頁 / 軌道 B AMS 文案、BR-API-CLI-005 / 010)doc/feature/pm_41/wport-cli-v2-mockup.mdPM✅ Blocking(文件一致性)本次一併回寫
DR-13 mockup 同步:AMS EnterpriseApiKeyAdmin 第 7 畫面改「刪除」;企業自助頁刪除鈕 + 二次確認彈窗(正式站 CommonDialog 樣式)、刪除後該列消失storybook/src/mockups/enterprise-api-key-admin-demo.vuestorybook/src/mockupcomponents/account/MockupApiKeySelfService.vuePM✅ Blocking(設計交付)本次一併完成
DR-13 前端 i18n 改名companyApiKey.revoke.*companyApiKey.delete.*(title / desc / button / confirmButton)、limitReached 文案「撤銷」→「刪除」、狀態字典移除 status.revokedW101-Web/packages/i18n/src/locales/*.jsonFE✅ Blocking 上線FE 排程
DR-13 前端行為改名revokeCompanyApiKeydeleteCompanyApiKeyrevoke-btn-* testid、確認彈窗文案;刪除成功後自列表移除該筆(不再標 revoked)W101-Web/apps/recruitment/src/views/account-center/api-keys/FE✅ Blocking 上線FE 排程
DR-13 後端契約POST /:enc_id/revoke 收斂為 DELETE /:enc_id;移除 revoked 狀態與 revoked_api_key 錯誤碼(統一 invalid_api_key);刪除前先落 audit log後端 + OpenAPI SpecRD✅ Blocking 上線RD spec 階段

17. Email Template(必填)

17.1 Key 核發信

  • 收件人:申請的 user(個人 email,非公司公用信箱)
  • Subject:[wport] 您的 Enterprise API Key 已核發({{company_name}})
  • Body 摘要
    • 招呼 + 您於 {{company_name}}(角色:{{role_name}})申請的 API Key 已核發
    • 明文 API Key(僅此一次顯示)wpk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    • 安全提醒:請立即複製保存;wport 不會再次寄送;切勿提交至 git;外洩請立即聯繫客服刪除
    • 提醒:此 key 綁定您個人 + {{company_name}} 身份;若離開公司,請主動聯繫 wport 刪除
    • CTA Label:「查看開發者文件」
    • CTA URL:https://docs.wport.me/enterprise-api/v1/getting-started([RD 決定最終 URL])
  • Query/Token 替換{{user_name}}{{company_name}}{{role_name}}{{plain_key}}{{docs_url}}{{contact_url}}

17.2 Key 刪除信(DR-13;原「撤銷信」)

  • Subject:[wport] 您的 Enterprise API Key 已被刪除
  • Body 摘要
    • 招呼 + key name + 刪除時間 + ops 填寫的刪除理由(企業自助刪除時無理由欄,該段省略)
    • 明示:此金鑰已永久移除、無法復原;使用它的整合會立即中斷
    • 引導:如需繼續使用,請重新申請一把新金鑰(名額已釋出)
    • CTA Label:「聯繫客服」
    • CTA URL:https://wport.me/contact
  • Query/Token 替換{{company_name}}{{key_name}}{{deleted_at}}{{delete_reason}}{{contact_url}}

17.3 Key Rotate 信

  • Subject:[wport] 您的 Enterprise API Key 已 Rotate
  • Body 摘要
    • 招呼 + 舊 key name + 新 key 明文(一次性)
    • 提醒:舊 key 已立即失效,請更新所有整合
    • CTA Label:「查看開發者文件」
    • CTA URL:同 17.1
  • Query/Token 替換:同 17.1

18. PRD 問題清單

#PRD section / ruleIssueSuggested fixCategoryImpactSoT
1§4.2 BR-018 提案新增 3 種 email 通知類型尚未正式回寫 business-rules.md上線後由 PM 發起 BR 更新 PR規則漂移business-rules.md
2§8.5 Quota 預設值5000/月為建議值,需 RD 與 ops 確認生產環境承載RD spec 階段拍板,必要時於 ops 後台允許 override容量規劃PRD §8.5
3§7.1 ACT 範圍應徵者 / 人才搜尋 API 列為 good-to-have,未明確 in/outRD 在 spec 階段決定並回寫此 PRD「3.2 排除範圍」範圍模糊PRD
4§12.2 [RD 決定] 項多個項目留給 RD 決定(URL 命名、Token 編碼等)RD 在 spec 階段補齊;本 PRD 不阻擋細節未拍板RD spec
5§4.1 BR-022多公司情境下 user 在多家公司分別申請 key 的 onboarding 文件未定義文件側補充;不影響後端實作文件docs.wport.me
6§3.2 排除範圍候選人 PII 範圍對齊「既有 UI 範圍」,但 BR-017 對 API 存取控制細節為「待確認」後續開放應徵者 / 人才搜尋 API 時,須先補完 BR-017 細節並提案規則缺口中(未來 v1.x)business-rules.md
7§3.4 DR-3v1 預設「1 把/user/company」,若 HR 實際反饋需多把(如分流 AI 工具 / ATS / CI),需 v2 放寬上限上線 3 個月後檢視;於 v2 PRD 重新討論用戶體驗PRD v2
8§3.4 DR-4v1 預設開放 Manager 申請;若實際發現濫用,需在 v2 加 allow_manager_apply policy switch 給 Admin 收緊v2 PRD 一併設計治理彈性PRD v2
9§3.4 DR-13硬刪除後,key 歷史存在 audit log;若 audit log 未記 key 生命週期事件(僅記 API 呼叫),support 將完全無從追溯「這把 key 何時被誰刪掉」RD spec 階段確認 audit log 涵蓋核發 / 改名 / Rotate / 刪除四類生命週期事件(§5.2、§12.1)稽核缺口PRD §5.2 / RD spec
10§3.4 DR-13前端 / i18n / 後端端點仍為 revoke 命名(正式站企業後台已上線),改名前 PRD 與產品用語不一致依 §16 Sync-Fix 四列排程;改名期間以本 PRD 為 SoT用語漂移PRD §13.4

19. 下一步(Next Steps)

  1. RD 接手撰寫 OpenAPI Spec + 後端實作規格
  2. Ops 規劃後台 OPS-1 ~ OPS-5 介面實作
  3. DevOps 設定 secret scanning rule(wpk_live_ 前綴)
  4. 上線前 PM 發起 BR-018 補充 PR(3 種新 email 通知類型)
  5. DR-13 改名落地:依 §16 Sync-Fix 推動前端 i18n / 行為、後端端點與錯誤碼、audit log 生命週期事件四項(正式站企業後台目前仍為 revoke 命名)
  6. 上線後 3 個月檢視 KPI;達標後啟動 v2(前端自助申請 UI)PRD

**此次prd大部分由opus 4.7 hight所完成 文件結束