公司資訊編輯、公司註冊 2.0 Mockup PRD(給後端 API 規格產生器使用)
此範本專門給 30%-feature-gen 產出的 mockup PRD 使用。 backend-api-spec-generator 會讀取這份文件與 Storybook mockups 來產生後端 API 規格。
1. 文件資訊
- 文件類型:Mockup 需求規格書(前後端共用視圖)
- 適用對象:前端開發、後端開發、產品、QA
- 最後更新:2026/07/08
- 版本:1.6.0
- PRD 識別碼:
pm_38 - 對應 Coda rowId:
i-ZHiJ-arBOE - 對應 Storybook:
storybook/src/stories/mockups/company/CompanyEditRegisterV2.stories.ts - Storybook 連結:https://storybook.wport.me/?path=/docs/mockups-company-companyeditregisterv2—docs
- 文件入口(網頁版):https://prd.wport.me/pm_38/company-edit-register-v2/
- 建立日期:2026/05/15
1.1 修訂紀錄
| 版本 | 日期 | 摘要 |
|---|---|---|
| 1.6.0 | 2026/07/08 | D23:VN/TH tax_id 改為 Step 1 必填;補 §4.4.4 三國格式規則(VN MST 10/13 碼、TH DBD MOA 13 碼);FE+BE 共同 checksum 驗證 |
| 1.5.0 | 2026/07/07 | D17/D22:對齊現行 production(Step 1 即建立公司);補 lifecycle_status / profile_complete;Logo gate 改綁 BR-014;v1.4 mockup 敘述之「尾端一次 POST」為文件誤差,予以修正 |
1.5 工程師回饋裁決(company-review 回應,2026/06/24)
以下為針對工程師 company-review 回饋及 §13.8 / §13.9 盤點之 PM 裁決,優先於本文後續較舊敘述; backend-api-spec-generator 請以本節為準。 每筆裁決須含「為何」——避免 RD 只知結論、不知取捨理由。
| # | 議題 | 裁決 | 為何 | 落地備註 |
|---|---|---|---|---|
| D1 | TW 統編驗證來源(雙軌查詢) | ① GCIS live API 優先 → ② 全國營業稅籍登記資料集(本地查)fallback → ③ 皆無仍可註冊,僅不帶入 derived | GCIS 已實測可行、資料較完整;稅籍資料集補 GCIS 未涵蓋類型(教育/醫療/NPO 等);雙源皆無時不擋註冊 | BE 代理+cache;TaxIdLookupResult.raw_source 標來源;詳 §4.4.2、§8.1 |
| D2 | org_type 驗證分層 | 不做(兩源對統編統一查法:存在/狀態/名稱) | 分層驗證增加規則與 UX 複雜度 | org_type 若資料集有帶,可選存為顯示屬性 |
| D3 | 統編唯一性(公司 UID) | 本期實作:認證前多帳號可共用同一統編;公司認證(人工審核)通過時確立一統編一公司;註冊「檢查可用性」僅擋已認證占用 + 審核防重 | 統編是公司在平台的業務 UID;兩源驗證只證明統編為真,不能防兩帳號搶同一統編;人工審核為最終裁決——未認證前可共存,認證後才鎖定為單一公司 | 沿用 validate-uniform-number(is_available 對已認證占用);company-approval-process-flowchart.md §統編驗證規則 |
| D4 | 越南 / 泰國查核 | v1 維持「文件上傳 + WPort 人工審核」baseline | 官方 API 可用性未驗證,寫死 endpoint 風險高 | 人工審核由 iCan 泰國、越南同仁支援;自動查核待 RD 逐國確認;PRD 不寫死特定 API |
| D5 | 教育/醫療/法人/NPO 與稅籍預填 | 維持既有開放;依 D1 稅籍資料集 fallback,填寫統編後可查詢——有資料則預填 derived,無則手動填寫 | 這些實體類型原先已可註冊;新增全國營業稅籍登記資料集是補 GCIS 未涵蓋者,提升帶入率而非限制開放 | 稅籍命中 → TaxIdLookupResult 預填;雙源皆無 → 手動 + 人工審核 |
| D6 | 支援市場 / 第三國 | tw / vn / th(第三國=泰國) | 對齊 BR-023 與 pm_34 全球化招募承諾 | 原文 ID 筆誤已更正 |
| D7 | Storybook UI | Step2「公司註冊國家/地區」欄位移至「統一編號」之上 | 國家決定統編格式與驗證來源,應先選 | 已於 storybook 落地(MockupStep2CompanyBasicV2) |
| D8 | 求職者視角預覽 | 公司編輯頁加「預覽(以求職者視角)」按鈕 | 企業設完 visibility 後需 WYSIWYG 確認對外樣貌 | 預覽套用 4 欄 visibility;電話/地址/員工恆常顯示(D15);與 pm_41 scope 對齊 |
| D9 | 多語系(i18n)分層 | A 介面 UI:v1 做 i18n。B 政府帶入 + C 企業自填:v1 原文顯示、不翻譯 | UI 字串走既有 i18n 機制、成本低;企業自填內容機翻品質差、per-locale 資料模型成本高 | 收斂 §13.8 G8;自填欄位維持單一字串 |
| D10 | 統編鎖定(BR-024) | 守 BR-024:TW 查詢成功 → tax_id_verified=true 且 tax_id_locked=true;統編與 country_code 唯讀 | 統編是法人身分錨點;鎖定防驗證後偷換身分規避審核;變更走客服可審計。權衡 P1「改了就重驗」後,法遵與資料完整性優先 | 狀態表 §4.4.2;待補 mockup:locked 時國家 :disabled |
| D11 | 介紹影片欄位 | 最多 3 個影片 URL(0–3 彈性);v1 無獨立照片欄 | mockup 實際只有 URL 輸入、無照片上傳;0–3 比固定 3 行友善(P7) | label 改「介紹影片 URL」;intro_photos[] 延 v2 |
| D12 | derived 覆寫 / 重新拉取 | v1 不做覆寫旗標;「重新拉取」一律覆蓋全部 derived;diff modal 延 v2 | 「重新拉取」語意即同步政府公示(BR-024),以官方 API 為準、全覆蓋 derived;平時編輯仍允許手改。v1 不逐欄裁決(無覆寫旗標/diff),因登記資料變動極低、diff UX 成本高(P8);接受低頻手改被蓋風險,客訴再評估 v2 | 收斂 G1/D6 |
| D13 | 痛點/得獎/里程碑排序 | v1 做拖曳排序 + display_order | 品牌敘事順序有主觀需求;mockup 缺拖曳是實作 gap,非產品否定 | mockup 待補拖曳 UI |
| D14 | visibility migration | 不全體 backfill。既有已勾「不顯示」者原樣保留;v2 新增開關(負責人/設立/董監事)無歷史值 → 預設顯示;資本額無歷史值 → 預設不顯示 | 不 backfill 以免覆寫既有企業已設定的顯示偏好;v2 新增欄位無歷史值則用產品預設 | 見 D15 |
| D15 | 顯示預設與範圍(BR-025) | 可切換欄位僅 4 個:資本額(預設不顯示)、設立日期/負責人/董監事(預設顯示)。電話 / 地址 / 員工人數不納入 BR-025,公開頁恆常顯示(無開關) | 資本額為 derived 中唯一預設隱藏;其餘 v2 新增開關預設顯示。電話/地址/員工在現行版已恆常公開,v2 不新增隱藏能力。註冊聯絡電話類型預設 市話(landline) | 見 D14 migration;改 mockup:移除 phone/address/employee_count 的 visibility checkbox |
| D16 | 公開頁統編 | 維持公開頁顯示統編;不顯示統編驗證徽章(見 D20) | 統編仍是台灣求職者辨識公司身分的慣用資訊(對齊 104);C 端信任門檻以 BR-005 公司認證為準,不需另掛統編徽章 | 拒絕 P4(顯示統編);徽章見 D20 |
| D17 | Logo 必填 | 修訂(D22):註冊精靈允許無 Logo 進入下一步;硬性 gate 改綁 profile_complete(BR-014),非「完成註冊」 | Logo 仍是 BR-006 / BR-014 搜尋曝光硬條件;僑外生信任靠 C 端曝光 gate(BR-014 不完整不出現於搜尋/公開頁 404),非靠延後建立公司。Step 1 早建 draft 可提升註冊漏斗留存;Logo gate 前移至「可被搜尋」層,避免註冊尾端一次擋死 | UI 強提示上傳 Logo;完成度 checklist;另追蹤 Step1 建立率、profile_complete 率、首職缺上架率 |
| D22 | 公司建立時機與 lifecycle | 維持現行 production:Step 1「下一步」即 POST /companies;v1.5 新增 lifecycle_status(預設 draft)與 profile_complete(BR-014 計算);後續步驟 PATCH 更新 | 現行後端已是 Step 1 建立;v1.4 PRD/mockup 誤寫為尾端一次提交。本次變更是補狀態機與 C 端 gate,非改建立時機。分層:存在(draft)→ 可搜尋(profile_complete)→ 可上架職缺(BR-005) | lifecycle_status:draft | profile_complete;draft 計入 BR-022;30 天未更新 draft 清理(見 §4.2) |
| D18 | 市場 / 底部區塊 | v1 維持 TW/VN/TH;底部 4 區塊全留 | 三市場已對齊 BR-023;VN/TH 走文件審核仍須支援註冊。4 區塊已進 mockup/KPI,砍 scope 成本高於收益 | 拒絕 P3、P6 |
| D19 | country_code 大小寫 | 全平台統一小寫 tw / vn / th | 避免 FE/BE enum 大小寫不一致的 subtle bug | §5.2 刪「ISO」字樣 |
| D20 | 統編驗證徽章(C 端) | v1 不顯示「經濟部已驗證」等統編徽章;tax_id_verified 僅供後端鎖定/稽核 | 上架職缺須通過 BR-005 公司認證,C 端信任訊號已涵蓋;有統編資料 ≠ 需掛徽章;避免與 derived 可手改語意混淆(原 G2) | 收斂 G2;改 mockup:移除公開頁/編輯頁統編徽章 |
| D21 | 非支援市場註冊 | v1 僅 tw / vn / th;不處理白名單以外國家註冊;不做 waitlist/留 email 出口 | 本期無力服務三國以外市場(審核 SOP、客服、職缺曝光链路未備);註冊選項由 /countries/supported 白名單驅動,未列即不可註冊 | 收斂 P10;§4.4.1 |
| D23 | VN/TH 登記號必填與格式 | 三國 tax_id 皆 Step 1 必填;VN/TH 做 FE+BE 格式驗證(checksum,見 §4.4.4),不呼叫政府 API、不 lock | 登記號是平台公司 UID 基礎(D3);VN/TH 無可靠 API(D4)但仍須攔截明顯錯誤;真實性靠 BR-005 文件 + iCan 人工審核 | Storybook:storybook/src/utils/company-tax-id.ts;BE 須複製同規則 |
註:TW 統編查詢查詢順序以 D1 為準:GCIS live → 稅籍資料集 fallback → 皆無則手動註冊。本文「商工登記/GCIS」指第一順位來源;「稅籍資料集」指第二順位。
2. 開發進度與設計來源
Mockup 交付策略(本次)
- 本 PRD 的 Storybook mockup 採 copy-first 1:1 快照策略(先依當下 production 畫面 1:1 複製,再做需求增量)。
- 此 mockup 用途為 本次前後端需求對齊;正式功能上線後不承諾長期與 production 持續同步。
- 為避免影響正式站,mockup 變更僅限
storybook/,不直接改動 production 元件行為。
開發進度
- 前端 PR #:TBD(待 Storybook mockup 完成後排程)
- 後端 PR #:TBD(API 規格由 OpenAPI Spec 產出後排程)
設計來源
- Figma 連結:待補(建議建立
Company 2.0design file) - 既有 FE 參照:
- 公司快速註冊 Storybook:
storybook/src/mockupcomponents/company/MockupCompanyQuickRegisterPage.vue - 公司編輯頁(incremental 基準):production FE,未在 Storybook 建立 baseline,本次將以
storybook-mockup-gen補上基準頁,再以 diff 視覺化新增區塊
- 公司快速註冊 Storybook:
- SaaS Benchmark:
- LinkedIn Company Page(cover image 1128×191、影片貼文、milestones)
- 104 公司頁(簡介、影片、福利、得獎、里程碑、員工心聲)
- CakeResume Company Profile(cover、影片、mission、milestones、awards)
- Wellfound(cover、影片、mission、team highlights)
3. 模擬頁面摘要(Mockup Summary)
3.1 功能概述
- 功能名稱:公司資訊編輯、公司註冊 2.0
- 主要使用者角色:Employer(Owner / Admin);Manager 不可編輯公司資訊(依 BR-016)
- 核心目標:
- 提升公司頁面資料準確度(透過商工登記公示資料 API 自動帶入)並減少人工填寫
- 強化公司品牌呈現能力(Banner + 影片 + 痛點/得獎/里程碑),縮短求職者決策距離
- 提供企業對欄位(資本額、負責人、設立日期、董監事)的「顯示/隱藏」控制權;資本額預設不公開,其餘預設公開(D15)。電話、地址、員工人數恆常公開(D15,延續既有 WPort)
- 平衡註冊轉換與 C 端信任(D22):維持現行 Step 1 建立公司;新增
profile_completegate 控制 C 端可見性;職缺上架仍由 BR-005 gate
3.2 範圍界定
v1(必含,本次交付)
- 公司註冊流程:
- 先選「公司註冊國家/地區」(可搜尋下拉,必填,
/v2/api/countries/supported,v1 僅 TW/VN/TH;見 D7)→ 再輸入登記號碼:- TW:8 碼統一編號 → GCIS live 優先,查無則 稅籍資料集 fallback(D1)
- VN:10 或 13 碼 MST(稅籍編號) 必填;格式驗證 FE+BE(D23)
- TH:13 碼 DBD 法人登記號碼(MOA) 必填;格式驗證 FE+BE(D23)
- TW 命中則帶入公司名稱、資本額、負責人、地址、設立日期;雙源皆無仍可註冊(見 D1)。Step 1「下一步」即建立
draft公司(D22)
- 公司頁(Step3):Logo 上傳區塊強化顯示;允許暫不上傳進入下一步(D17),但顯示完成度提示:「上傳 Logo 後才可被求職者於公司搜尋找到」
- 公司頁頂部新增 Banner 上傳
- 公司介紹區改為最多 3 個介紹影片 URL(0–3 彈性;v1 無獨立照片欄,見 D11)
- 「其他福利」下方新增 4 個 free text 區塊:痛點、得獎、里程碑、QA(可折疊)
- 統編驗證通過後該欄位鎖定,不可修改(見 D10)
- 先選「公司註冊國家/地區」(可搜尋下拉,必填,
- 公司編輯頁(incremental):
- 公司基本資料區:先「公司註冊國家/地區」再統編(D7);derived 欄位可手動覆寫 + 重新拉取
- 公司頁:Banner 上傳、Logo 上傳強化(完成度 gate,見 D17)、介紹區 3 組 URL、福利區下方四區塊(含可折疊 QA)
- 新增「公司介紹影片」URL 連結欄位(最多 3 個,0–3 彈性;支援 YouTube / Vimeo;與介紹區合併呈現)
- 統一編號顯示於公司頁面(管理頁 + 公開頁)
- 新增 3 個新欄位:設立日期、負責人、董監事,每個欄位均有「不顯示」勾選(電話、地址、員工人數不提供隱藏開關,見 D15)
- 「其他福利」下方新增 4 個選填 free text 區塊:解決的痛點、得獎資訊、里程碑、QA(可折疊)
Nice-to-have(v2,本次不交付)
- 影片 oEmbed 預覽縮圖、自動抓 metadata
- 員工心聲、福利圖示化
- 公司資料變更歷史審計
- Banner / Logo 智能裁切
- 統編 API 失效時的人工申訴流程
Out of scope
- 跨國法遵深度客製(V Card / 國際統編等)
- 公司資料 GDPR 級別匯出
- 公司頁面 SEO 結構重構(已有 pm_33)
- 統編以外的政府資料源整合
3.3 成功條件
| KPI | 目標 | 量測方式 |
|---|---|---|
| 新註冊公司:統編 API 帶入成功率 | ≥ 85% | API 200 與帶入欄位非空之比例 |
| 新註冊:Step 1 建立 draft 率 | ≥ 70%(基線待上線後校正) | 進入精靈且完成 Step 1 POST /companies 之比例 |
新註冊:profile_complete 率 | ≥ 55%(基線待上線後校正) | 30 天內由 draft 轉為 profile_complete=true 之比例 |
| 新註冊:首個職缺上架率 | 追蹤(無硬性目標 v1) | 建立 draft 後 60 天內至少一職缺上架(須 BR-005)之比例 |
| 上線 30 天:既有公司 Banner 上傳率 | ≥ 40% | 已上 banner 公司數 / 全體 |
| 上線 30 天:4 個選填區塊任一填寫率 | ≥ 25% | 至少填一個區塊(痛點/得獎/里程碑/QA)的公司比例 |
| 公司資料完整性(BR-014 完整度) | 平均 +15% vs. 上線前 | 完整欄位數 / 總欄位數 |
4. 商業規則對齊(Business Rules Alignment)
供 backend-api-spec-generator 對齊
prd/business-rules.md。 新功能若有新規則,先在此描述,再視情況回寫至 business-rules。
4.1 本功能使用到的業務規則
| 規則 ID | 規則摘要 | 是否關鍵 | 備註 |
|---|---|---|---|
| BR-004 | 只有 email 已驗證的帳號可建立公司 | ✅ 是 | 註冊精靈仍需此前置條件 |
| BR-005 | 公司驗證需上傳擇一公司文件(含統編編配通知書等六類,見 BR-005 全文) | ✅ 是 | 統編 API 帶入≠通過公司驗證;二者分離 |
| BR-006 | 未上傳 logo 無法在公司搜尋中被找到 | ✅ 是 | Logo 硬性 gate 綁 profile_complete(D17/D22);draft 公司不進搜尋 |
| BR-014 | 公司搜尋顯示條件需「公司名稱、Logo、電話、地區、地址、公司介紹、產業類別」皆填寫 | ✅ 是 | 電話、地址恆常公開(D15),與 BR-014 一致;滿足時 BE 設 profile_complete=true |
| BR-016 | 角色權限矩陣 | ✅ 是 | 公司編輯:Owner / Admin 可操作;Manager / Member 不可 |
| BR-022 | 每帳號最多 10 間公司 | ✅ 是 | draft 計入上限(D22);30 天未更新 draft 自動清理 |
4.2 補充說明(新規則 / BR 更新建議)
新規則建議(待 BR 更新):
-
公司 Lifecycle(D22;建議納入 business-rules 或 API 層文件)
- 狀態欄位:
lifecycle_status:draft|profile_complete draft:Step 1POST /companies建立;B 端可續填、可建職缺草稿;C 端不出現於公司搜尋(BR-006/014)、公開頁 API 回 404profile_complete:BE 依 BR-014 全欄位判定為 true 時自動設定(含 Logo);方可出現於公司搜尋、公開頁可開- 職缺上架:仍須 BR-005 公司認證(與
lifecycle_status獨立);發布職缺時若未profile_complete→ 導向公司編輯補齊;若未通過 BR-005 → 導向驗證上傳 - BR-022:
draft計入每帳號 10 間上限 - 清理:
lifecycle_status=draft且updated_at超過 30 天 → BE 排程硬刪除(連同無職缺之空殼);有職缺草稿者不自動刪(改為標記待清理/通知 Owner,[RD 可細化]) - 完成度 API:
GET /companies/{id}/profile-completeness回傳 BR-014 各欄位是否已填 +missing_fields[](供 FE checklist)
- 狀態欄位:
-
BR-024(建議新增):統一編號驗證後不可變更
- 描述:透過商工登記公示資料 API 驗證通過的統編,於該公司生命週期內不可修改
- 適用範圍:所有透過 v2 註冊流程建立或編輯時補登的公司
- 變更途徑:僅限後台人員(人工審核)介入,且需留下審計記錄
- UI 影響:統編欄位於驗證通過後顯示為唯讀(不顯示統編驗證徽章,見 D20)
- 理由(Why):避免企業透過自助修改規避稅務/法遵驗證;對齊 BR-005 公司驗證精神
- 補充:API 帶入的衍生欄位(公司名稱、資本額、負責人、地址、設立日期)允許企業點按「重新拉取」更新(資料源來自政府公開資料,本身為事實)
- 國家鎖定:
tax_id_locked=true時,country_code不可變更(後端拒絕;如需調整須聯繫客服人工處理)
-
BR-025(建議新增):公司欄位顯示偏好(Field Visibility Preferences)
- 描述:企業可控制以下欄位是否對外(公司公開頁)顯示——僅此 4 欄:
- 資本額(
is_capital_amount_visible) - 設立日期(
is_establishment_date_visible) - 負責人(
is_representative_visible) - 董監事(
is_directors_visible)
- 資本額(
- 不納入本規則(恆常公開、無開關,見 D15):聯絡電話(
phone)、公司地址(address)、員工人數(employee_count_range_code)——延續既有 WPort,v2 不新增隱藏能力 - 預設值(D15):
- 資本額 → 預設不顯示(
false) - 設立日期、負責人、董監事 → 預設顯示(
true)
- 資本額 → 預設不顯示(
- Migration(D14):既有已勾「不顯示」者原樣保留;v2 新增三欄(負責人/設立/董監事)無歷史值 → 顯示;資本額無歷史值 → 不顯示
- 適用範圍:公司公開頁(C 端);公司管理頁(B 端內部)永遠顯示
- 與 BR-014 之關係:顯示偏好不影響「公司搜尋顯示條件」的資料完整度判定(資料層存在即視為填寫,不影響搜尋曝光)
- 理由(Why):降低企業對公開敏感資訊的填寫抗拒;非隱私保護(政府公開資料仍可他處查得)
- 描述:企業可控制以下欄位是否對外(公司公開頁)顯示——僅此 4 欄:
4.3 ⚠️ 衝突檢查結果
無硬衝突。BR-005(公司驗證需文件)與本功能「統編 API 帶入」屬於不同流程:
- 統編 API 帶入:自助、即時、用於資料初始化
- 公司驗證:人工審核、需上傳 PDF、用於職缺上架資格
- Lifecycle 分層(D22):
draft(早建立)→profile_complete(BR-014,C 端可搜尋)→ BR-005 公司認證(職缺可上架) - 統編 API 帶入為資料初始化;求職者端信任以 BR-005 公司認證為準(上架職缺必須通過)。v1 不另顯示統編驗證徽章(D20)
4.4 市場 rollout 決策(v1,2026-06-22 確認)
原則:註冊國家 = 平台承諾能完整服務的市場清單,不是全球 ISO 國家表。
選項由後端/v2/api/countries/supported白名單驅動;FE 不 hardcode 全量國家。
4.4.1 已支援市場(Supported Markets)
| 市場 | country_code | v1 狀態 | 備註 |
|---|---|---|---|
| 台灣 | tw | ✅ 開放 | 既有核心市場;GCIS live + 稅籍資料集雙軌帶入(D1) |
| 越南 | vn | ✅ 開放 | 對齊 pm_34 全球化招募擴張 |
| 泰國 | th | ✅ 開放 | 東南亞 expansion 第二站 |
- 註冊 / 編輯下拉:僅顯示上表三國(D21)。
- 不開放全球:印尼、新加坡、日本等不在 v1 註冊選項;本期不處理白名單以外國家註冊,不另做 waitlist/留 email 出口。待審核 SOP、幣別、客服、職缺曝光链路 ready 後,由 BE 擴白名單即可,無需改 DB schema。
4.4.2 非台灣:tax_id / 公司登記號碼行為
TW 統編查詢瀑布(D1):
checksum 通過 → ① GCIS live API
→ ② 若 GCIS 查無/失敗:全國營業稅籍登記資料集(本地)
→ ③ 雙源皆無:found=false,允許手動填寫並完成註冊(tax_id_verified=false)
| 條件 | 欄位 label | 驗證 | 查詢來源 | tax_id_verified | 「檢查可用性」 |
|---|---|---|---|---|---|
country_code = tw + GCIS 或稅籍命中 | 統一編號 | 8 碼 + checksum | ① GCIS 或 ② 稅籍 | true 並 lock | ✅ 顯示 |
country_code = tw + 雙源皆無 | 統一編號 | 8 碼 + checksum | — | false,不 lock | ✅ 顯示 |
country_code = tw + API 全失敗後手填 | 統一編號 | 8 碼 + checksum | — | false,不 lock | ✅ 顯示 |
country_code ∈ {vn, th} | 見 §4.4.4 label | 必填 + checksum(§4.4.4) | ❌ 不查 | false,不 lock | 可選(D3;僅擋已認證占用) |
已移除(v1.6):非 TW 且未填 → 選填;VN/TH 自 v1.6 起改為必填(D23)。
tax_id_verified × tax_id_locked 狀態表(D10 定案):
| 情境 | tax_id_verified | tax_id_locked | 統編欄位 | country_code |
|---|---|---|---|---|
| TW + GCIS 或稅籍查詢成功 | true | true | 唯讀(無徽章,D20) | 唯讀(locked 時) |
| TW + 雙源皆無/手動填寫 | false | false | 可編輯 | 可編輯 |
| VN / TH | false | false | 可編輯 | 可編輯 |
- 統編唯一性(D3):認證前多帳號可共用同一統編;公司認證通過後一統編一公司;
validate-uniform-number僅擋已認證占用 + 審核防重 - 資料帶入:derived 欄位**僅在 TW + 查詢成功(GCIS 或稅籍)**時於 Step3 帶入;非 TW 手動填寫
- Step2 成功提示:TW 統編查詢成功僅顯示 inline「✓ 查詢成功,資料將帶入公司頁」,不在 Step2 展開 derived 編輯區(不掛統編驗證徽章,D20)。
- 重新拉取:編輯頁「重新拉取最新登記資料」按鈕僅在
country_code = tw時顯示。
4.4.3 聯絡電話與 country_code 連動
country_code | 國碼選項 | 手機 placeholder | 市話 placeholder |
|---|---|---|---|
tw | +886 | 09xx-xxx-xxx | 02-xxxx-xxxx |
vn | +84 | 09x xxx xxxx | 028 xxxx xxxx |
th | +66 | 08x-xxx-xxxx | 02-xxx-xxxx |
- v1 不開全球國碼表:聯絡電話國碼下拉僅
+886/+84/+66,與 supported markets 一致。 - 預設連動:使用者選擇「公司註冊國家/地區」後,國碼預設帶入對應值(仍可手動改,但僅限三選一)。
- 電話類型:維持既有
mobile/landline下拉;預設landline(市話);格式驗證依country_code + dial_code規則表(BE 為 SoT)。 - 與 BR-014:電話、地址須存在以符合搜尋曝光;二者恆常公開(D15),無 visibility 開關
4.4.4 tax_id 格式規則表(三國;D23)
原則:三國共用
tax_id欄位;country_code決定 label、placeholder、驗證規則與儲存格式。
FE 與 BE 必須實作相同規則(Storybook 參考:storybook/src/utils/company-tax-id.ts);POST /companies非法格式回422+error_code: TAX_ID_INVALID_FORMAT。
VN/TH 僅格式驗證,不設tax_id_verified/不 lock;真實性由 BR-005 文件 + iCan 人工審核(D4)把關。
三國碼數一覽
| 市場 | 官方名稱 | UI label | 碼數 | 儲存(compact) | 範例 |
|---|---|---|---|---|---|
tw | 統一編號 | 統一編號 | 8 碼 | 12345678 | 22099131 |
vn | MST(Mã số thuế/企業識別號碼) | 稅籍編號(MST) | 10 碼(總公司)或 13 碼(分公司) | 0100233488 或 0314409058002 | 0100233488/0314409058-002 |
th | DBD 法人登記號碼(MOA) | 法人登記號碼 | 固定 13 碼 | 0994000617721 | 0994000617721(顯示可為 0-9940-00617-72-1) |
泰國說明(th)
- 此號碼為泰國商業發展部(Department of Business Development, DBD)核發的法人登記號碼(Memorandum of Association Number, MOA)。
- 在泰國實務上,此 13 碼號碼通常也作為法人稅籍號(Taxpayer Identification Number, TIN)使用(多數有限公司兩者同號)。
- v1 驗證採 MOA 規則:第 1 碼須為
0(有限公司),第 13 碼為 checksum;拒絕自然人 13 碼身分證(PIN)誤填。 - 合夥企業(第 1 碼 1–3)格式待 iCan 確認後 v1.1 擴充;不符 MOA 者仍可走 BR-005 文件人工審核。
越南說明(vn)
- MST(Mã số thuế)自 2021 企業登記改革後,與企業識別號碼合一,作為稅籍與社保識別碼。
- 10 碼:獨立法人/總公司(
N1N2省份碼 + 7 碼序號 + 第 10 碼 checksum)。 - 13 碼:分公司/分支機構(10 碼母體 +
-+001–999);輸入可含連字號,儲存為 13 碼 compact。
驗證規則(演算法 SoT:python-stdnum 同等邏輯)
country_code | 輸入清理 | 長度 | Checksum | 額外 component 拒絕 |
|---|---|---|---|---|
tw | 移除非數字 | 8 | 權重 1,2,1,2,1,2,4,1;第 7 碼為 7 時允許 +1 特例 | — |
vn | 移除非數字與 - | 10 或 13 | 第 10 碼:weights (31,29,23,19,17,13,7,5,3) × 前 9 碼 | N3–N9 全 0;13 碼尾 3 碼不可 000 |
th | 移除非數字與 - | 13 | 第 13 碼:mod-11(同泰國身分證演算法) | 第 1 碼須 0(MOA);拒絕 PIN |
錯誤碼(FE / BE 共用)
error_code | 情境 | UI 文案(zh-TW 範例) |
|---|---|---|
TAX_ID_EMPTY | 未填 | 請輸入登記號碼 |
TAX_ID_INVALID_LENGTH | 碼數不符 | 登記號碼長度不正確 |
TAX_ID_INVALID_FORMAT | 含非法字元 | 登記號碼格式不正確 |
TAX_ID_INVALID_CHECKSUM | checksum 失敗 | 登記號碼檢查碼錯誤,請確認是否輸入正確 |
TAX_ID_INVALID_COMPONENT | component 規則 | 登記號碼內容不符合規則 |
TAX_ID_PERSONAL_ID_REJECTED | TH 誤填身分證 | 請輸入法人登記號碼,不可使用自然人身分證字號 |
5. 資料實體與欄位(Data Entities & Fields)
依 Rule 30:本節描述「需要追蹤什麼資料、為什麼」,不勾選 API JSON 命名 / 加密策略 / DB schema。實際 API/DB 由 OpenAPI Spec(RD 負責)決定。 欄位命名僅供 Storybook TypeScript 介面參考,最終以 Storybook mockup 為準。
5.1 實體列表
| 實體名稱 | 說明 | 來源頁面/區塊 |
|---|---|---|
| Company(擴充) | 公司主體;本次新增 banner、影片、統編、欄位顯示偏好、痛點/得獎/里程碑/QA | 公司編輯頁、公司公開頁 |
| TaxIdLookupResult | 統編查詢結果(GCIS 或稅籍資料集;暫存於前端) | 註冊精靈、編輯頁「重新拉取」 |
| CompanyMilestone | 公司里程碑(年份 + 標題 + 描述) | 公司編輯頁「里程碑」區塊 |
| CompanyAward | 得獎資訊(年份 + 獎項名稱 + 頒發單位 + 描述) | 公司編輯頁「得獎資訊」區塊 |
| CompanyPainPoint | 解決的痛點(標題 + 描述) | 公司編輯頁「解決的痛點」區塊 |
| CompanyQaItem | 公司 Q&A(問題 + 回答,可折疊區塊內多筆) | 公司編輯頁「QA」區塊 |
| CompanyFieldVisibility | 欄位顯示偏好;對應 BR-025 | 公司編輯頁、公開頁顯示控制 |
| CompanyVideoLink | 介紹影片 URL(最多 3 個,含 provider 與 video_id 解析) | 公司編輯頁「介紹影片」區塊 |
5.2 實體欄位定義(TypeScript 介面,僅供 Storybook 參考)
// 公司主體(擴充欄位;既有欄位不重複列)
interface CompanyV2 {
enc_id: string;
// —— Lifecycle(D22)——
lifecycle_status: 'draft' | 'profile_complete';
profile_complete: boolean; // BE 依 BR-014 計算;與 lifecycle_status 同步
// —— Step 1 建立 draft 必填 ——
name: string;
country_code: string; // 公司註冊國家/地區(小寫 tw/vn/th;**先於**統編選擇;supported markets only)
phone: string; // 聯絡電話(Step 1)
tax_id: string; // 三國皆必填(D23);TW:8 碼統編;VN:MST 10/13 碼;TH:DBD MOA 13 碼
tax_id_verified: boolean; // GCIS 或稅籍資料集驗證通過
tax_id_verified_at?: string; // 驗證時間
tax_id_locked: boolean; // 驗證通過後 true → FE 唯讀
// —— profile_complete 必填(BR-014;含於註冊後續步驟或編輯頁補齊)——
logo_url?: string; // draft 可空;profile_complete 時必填
intro: string;
// industry_category_codes[]、area_codes 等 BR-014 欄位(既有 schema,略)
// —— 商工登記公示資料帶入欄位(derived,允許重新拉取)——
capital_amount?: number; // 資本額
representative_name?: string; // 負責人
registered_address?: string; // 登記地址
establishment_date?: string; // 核准設立日期 (YYYY-MM-DD)
directors?: string[]; // 董監事(陣列,名單)
// —— 既有可編輯欄位 ——
// intro 已列於 profile_complete 區
// ... (其他既有欄位省略)
// —— 新增:自訂 Banner ——
banner_url?: string;
// —— 新增:介紹影片(最多 3 個)——
video_links?: CompanyVideoLink[];
// —— 新增:欄位顯示偏好(對應 BR-025)——
field_visibility: CompanyFieldVisibility;
// —— 新增:4 個選填區塊(痛點/得獎/里程碑/QA)——
pain_points?: CompanyPainPoint[]; // 解決的痛點
awards?: CompanyAward[]; // 得獎資訊
milestones?: CompanyMilestone[]; // 里程碑
qa_items?: CompanyQaItem[]; // Q&A(可折疊)
}
interface TaxIdLookupResult {
tax_id: string;
found: boolean; // 是否查到(GCIS 或稅籍任一命中即 true)
company_name?: string;
capital_amount?: number;
representative_name?: string;
registered_address?: string;
establishment_date?: string;
directors?: string[];
raw_source?: 'gcis_open_data' | 'tax_registry_dataset'; // D1:標示命中來源
fetched_at: string;
// 例外時的回傳
error_code?: 'NOT_FOUND' | 'INVALID_FORMAT' | 'API_DOWN' | 'RATE_LIMITED';
error_message?: string;
}
interface CompanyVideoLink {
url: string;
provider: 'youtube' | 'vimeo' | 'other';
video_id?: string; // 由 URL 解析
title?: string; // oEmbed 抓取(v2 才做)
}
interface CompanyFieldVisibility {
is_capital_amount_visible: boolean; // 預設 false(D15)
is_establishment_date_visible: boolean; // 預設 true
is_representative_visible: boolean; // 預設 true
is_directors_visible: boolean; // 預設 true
// phone / address / employee_count:無 visibility 欄位(D15,恆常公開)
}
interface CompanyMilestone {
year: number; // 例:2018
title: string; // 例:「A 輪募資完成」
description?: string;
display_order: number; // 拖曳排序(D13);預設可依 year 升冪
}
interface CompanyAward {
year: number;
name: string; // 獎項名稱
issuer?: string; // 頒發單位
description?: string;
display_order: number; // 拖曳排序(D13);預設可依 year 降冪
}
interface CompanyPainPoint {
title: string;
description: string;
display_order: number; // 拖曳排序(D13)
}
interface CompanyQaItem {
question: string;
answer: string;
display_order: number; // 拖曳排序(D13);預設依輸入序
}
5.3 容量限制(必記)
| 欄位 | 上限 | 備註 |
|---|---|---|
| Banner 檔案 | ≤ 5 MB;JPG/PNG/WebP;建議 1920×400(4.8:1) | 為高解析顯示保留空間 |
| Logo 檔案 | ≤ 2 MB;JPG/PNG;建議 ≥ 200×200 | 既有規則延續 |
| 介紹影片 | 最多 3 個;URL 長度 ≤ 500 | YouTube/Vimeo URL whitelist |
| 解決的痛點 | 最多 5 條;標題 ≤ 60 字;描述 ≤ 300 字 | 避免冗長 |
| 得獎資訊 | 最多 20 筆;名稱 ≤ 100 字;描述 ≤ 200 字 | |
| 里程碑 | 最多 20 筆;標題 ≤ 80 字;描述 ≤ 300 字 | 依年份或 display_order |
| QA | 最多 20 筆;問題 ≤ 120 字;回答 ≤ 500 字 | 可折疊區塊 |
| 統一編號(TW) | 固定 8 位數字 | 含 checksum 驗證(§4.4.4) |
| 稅籍編號 MST(VN) | 10 或 13 位數字 | 13 碼為分公司;含 checksum;儲存 compact |
| 法人登記號碼 MOA(TH) | 固定 13 位數字 | DBD 核發;第 1 碼須 0;含 checksum |
6. 畫面區塊與資料需求(UI Sections & Data Needs)
6.1 區塊列表
| 區塊 ID | 區塊名稱 | 出現位置 | 說明 |
|---|---|---|---|
| SEC-REG-1b | 註冊精靈:國家選擇 | 公司註冊精靈(公司基本資料) | 先於統編;可搜尋下拉;必填;supported markets(TW/VN/TH)(D7) |
| SEC-REG-1 | 註冊精靈:統編 / 登記號碼 | 公司註冊精靈 | TW:GCIS 查詢 + 檢查可用性(D1);VN/TH:格式驗證必填(D23,§4.4.4) |
| SEC-REG-1c | 註冊精靈:聯絡電話 | 公司註冊精靈(公司基本資料) | 國碼(+886/+84/+66)依 country 預設;電話類型 mobile/landline |
| SEC-REG-1d | 註冊精靈:Step 1 建立 draft | 公司註冊精靈(公司基本資料) | Step 1「下一步」→ POST /companies;lifecycle_status=draft(D22) |
| SEC-REG-2 | 註冊精靈:Logo 步 | 公司註冊精靈 | Logo 強提示;允許暫不上傳進入下一步(D17);未完成 BR-014 時顯示完成度 checklist |
| SEC-EDIT-1 | 公司基本資料區(incremental) | 公司編輯頁 | 顯示統編(唯讀)+ 國家(可搜尋下拉) + derived 欄位(可手動覆寫 + 重新拉取按鈕) |
| SEC-EDIT-2 | 自訂 Banner 區 | 公司編輯頁 | 上傳/裁切/移除 |
| SEC-EDIT-3 | 介紹影片區 | 公司編輯頁 | 最多 3 個 URL(0–3 彈性)+ 即時 validation + 預覽縮圖(v2) |
| SEC-EDIT-4 | 欄位顯示偏好區 | 公司編輯頁 | 4 個 checkbox:資本額、設立日期、負責人、董監事(D15) |
| SEC-EDIT-5 | 解決的痛點區 | 公司編輯頁底部 | 動態新增/移除/排序 |
| SEC-EDIT-6 | 得獎資訊區 | 公司編輯頁底部 | 動態新增/移除/排序 |
| SEC-EDIT-7 | 里程碑區 | 公司編輯頁底部 | 動態新增/移除/排序 |
| SEC-EDIT-7b | QA 區 | 公司編輯頁底部 | 可折疊;問答多筆;動態新增/移除/排序 |
| SEC-EDIT-8 | 預覽(求職者視角) | 公司編輯頁標題列 | 「預覽(以求職者視角)」按鈕 → 開公開頁預覽,套用 field_visibility(隱藏欄位不顯示),頂部顯示預覽橫幅,可「結束預覽,回到編輯」 |
| SEC-PUB-1 | 公司公開頁:Banner | 公司公開頁頂部 | 若未上 banner,fallback 顯示既有預設色塊 |
| SEC-PUB-2 | 公司公開頁:統編顯示 | 公司公開頁基本資料區 | 顯示統編(不顯示統編驗證徽章,D20) |
| SEC-PUB-3 | 公司公開頁:影片區 | 公司公開頁中段 | 影片嵌入(iframe),最多 3 個 |
| SEC-PUB-4 | 公司公開頁:痛點/得獎/里程碑/QA | 公司公開頁底部 | 四段獨立可摺疊區塊;若無資料則整段不顯示 |
6.2 各區塊資料需求
SEC-REG-1b 註冊精靈:公司註冊國家/地區
- 位置:公司基本資料表單內,先於統一編號 / 公司登記號碼欄位(D7)
- 元件:可搜尋下拉(Storybook mock:
n-select+filterable;production:PrimeVueSelect+filter) - 驗證:必填
- 選項:
/v2/api/countries/supported(v1 白名單:tw、vn、th) - 預設:依使用者 IP/語系建議;台灣公司預設
tw - 連動:變更國家 → 重設 tax_id 查詢狀態;更新電話國碼預設(見 SEC-REG-1c)
- 鎖定限制:若該公司
tax_id_locked=true(BR-024),禁止變更country_code;後端拒絕並提示聯繫客服
SEC-REG-1 註冊精靈:統編 / 公司登記號碼
- 僅
country_code = tw時:- 使用者輸入 8 碼統編 → 按「檢查可用性」→ 前端 checksum → BE 瀑布查詢(D1):① GCIS live → ② 稅籍資料集 → ③ 皆無則
found=false - 可用性檢查(D3):「檢查可用性」沿用
validate-uniform-number(is_available);僅當該統編已被已認證公司占用時拒絕並引導加入既有公司;未認證前多帳號可共存,公司認證通過時確立唯一性 - 查詢成功:Step2 inline「✓ 查詢成功,資料將帶入公司頁」;derived 於 Step3 帶入
- 雙源皆無:允許手動填寫並進入 Step 1 建立 draft;
tax_id_verified = false
- 使用者輸入 8 碼統編 → 按「檢查可用性」→ 前端 checksum → BE 瀑布查詢(D1):① GCIS live → ② 稅籍資料集 → ③ 皆無則
- 非 TW(
vn/th)(D23):- 必填;label 依 §4.4.4(VN「稅籍編號(MST)」;TH「法人登記號碼」)
- blur 與提交時 FE 執行 §4.4.4 checksum;BE
POST /companies重驗,非法回422 - 不顯示 GCIS 查詢 UI;不呼叫政府 API;
tax_id_verified = false;不鎖定 - TH tooltip 須說明:泰國商業發展部(DBD)核發的法人登記號碼(MOA),通常也作為法人稅籍號(TIN)使用;範例
0994000617721 - VN 範例:
0100233488(10 碼總公司)、0314409058-002(13 碼分公司)
SEC-REG-1c 註冊精靈:聯絡電話
- 國碼:
+886(TW)、+84(VN)、+66(TH);不開全球 ITU 表 - 預設:跟隨
country_code自動帶入對應國碼 - 類型:
mobile/landline(沿用既有);預設landline(市話)(D15) - 驗證:依
country_code+ 國碼 + 類型的 BE 規則表;FE 顯示對應 placeholder
SEC-REG-1d 註冊精靈:Step 1 建立 draft
- 觸發:Step 1(國家 + 統編/登記號 + 聯絡電話 + 公司名稱等基本欄位)按「下一步」
- API:
POST /companies(見 HINT-MUTATION-1a) - 必填:
country_code、name、phone、tax_id(三國,§4.4.4 格式驗證);可帶 derived overrides - 回傳:
201+enc_id+lifecycle_status=draft - 後端:依
country_code驗證tax_id格式;僅 TW 執行 D1 瀑布重查(GCIS → 稅籍)→ 命中則tax_id_verified=true並鎖定 - FE:取得
enc_id後後續步驟改走PATCH /companies/{id};使用者可離開後由公司列表續填
SEC-REG-2 註冊精靈:Logo 步
- 驗證:不禁用「下一步」;未上傳時顯示黃色提示條:「尚未上傳 Logo——完成後才可被求職者於公司搜尋找到」
- 上傳:走既有 upload →
PATCH寫入logo_url - 與 BR-006 關係:Logo 為 BR-014 /
profile_complete必要條件;BE 搜尋 API 硬擋,FE 以完成度 checklist 引導
SEC-EDIT-1 公司基本資料區(incremental)
- 顯示:統編欄位若
tax_id_locked=true→ 唯讀(無徽章,D20);旁邊「重新拉取最新登記資料」按鈕(更新 derived 欄位但不解鎖統編) - 資料需求:當前 Company 全部欄位 + visibility flags
SEC-EDIT-2 自訂 Banner 區
- 互動:拖曳 / 點選上傳 → 顯示預覽(4.8:1 框)→ 「儲存」or「移除」
- 若失敗:顯示錯誤(容量超標、格式錯誤)
- 空狀態:「點此上傳 Banner,建議尺寸 1920×400」CTA
SEC-EDIT-3 介紹影片區
- 互動:最多 3 個 URL 輸入(0–3 彈性,按「+ 新增連結」);每個輸入框失焦時即時驗證 URL pattern
- YouTube:
youtube.com/watch?v=/youtu.be/ - Vimeo:
vimeo.com/{id}
- YouTube:
- 錯誤:URL 格式錯誤或非白名單時,輸入框紅框 + 提示「目前僅支援 YouTube 與 Vimeo」
- 儲存:URL 解析後存
{url, provider, video_id}
SEC-EDIT-4 欄位顯示偏好區
- 元件:4 個 checkbox(資本額 / 設立日期 / 負責人 / 董監事)
- 預設(D15):資本額未勾選(對外隱藏);設立日期、負責人、董監事已勾選(對外顯示)
- 無開關(D15):聯絡電話、公司地址、員工人數——延續既有 WPort,恆常公開,mockup 不得出現隱藏 checkbox
- 副標:「以下欄位可控制是否於公開頁顯示;電話、地址、員工人數恆常公開。」
SEC-EDIT-5/6/7 痛點 / 得獎 / 里程碑
- 元件:可摺疊區塊,內含「新增」按鈕
- 項目卡:每項可拖曳排序(得獎/里程碑依年份預設排序)
- 儲存:批次儲存於公司編輯頁「儲存」按鈕觸發
SEC-EDIT-8 預覽(以求職者視角)
- 入口:公司編輯頁標題列「預覽(以求職者視角)」按鈕。
- 行為:開啟與 SEC-PUB-* 公開頁同一渲染,套用
field_visibility——勾選「不顯示」的資本額 / 負責人 / 設立日期 / 董監事在預覽中不出現(電話、地址、員工恆常顯示,D15) - 預覽橫幅:頂部顯示「預覽模式 — 這是求職者看到的公司頁;隱藏的欄位不會顯示」,並提供「結束預覽,回到編輯」。
- Why:企業設定可見性後最常見的疑問是「對外到底長怎樣」;提供 WYSIWYG 預覽降低誤設風險、提升敏感欄位開關的填寫信心。對標 LinkedIn /104 公司頁「預覽公開頁」。
- 與 pm_41 連結:公司 API 金鑰「公司資訊」scope(僅 Owner/Admin,pm_41 BR-API-CLI-006)讀寫的即本頁欄位與
field_visibility;CLIcompany view對外輸出亦須同樣依 visibility 過濾(pm_41 §6.4)。
SEC-PUB-2 公司公開頁:統編顯示
- 顯示:
統一編號:12345678(僅顯示號碼,不掛「經濟部已驗證」等徽章,D20) - 信任訊號:求職者端以 BR-005 公司認證為準;上架職缺之公司皆須通過認證
tax_id_verified:後端/鎖定用旗標,不對 C 端呈現徽章
7. 使用者動作與後端需求(User Actions & Backend Needs)
| 動作 ID | 動作名稱 | 類型 | 需要後端 | 涉及實體 | 說明 |
|---|---|---|---|---|---|
| ACT-1 | 輸入統編並查詢 | 讀取(Read) | ✅ 是 | TaxIdLookupResult | 串接商工登記公示資料 API(建議由 BE 代理避免 CORS、可加 cache) |
| ACT-2 | 上傳 Logo | 寫入(Write) | ✅ 是 | Company.logo_url | 走既有 upload;註冊精靈或編輯頁 PATCH;為 BR-014 必要欄位 |
| ACT-3 | 上傳 Banner | 寫入(Write) | ✅ 是 | Company.banner_url | 走既有 upload;新增 banner_url 欄位 |
| ACT-4a | Step 1 建立 draft 公司 | 寫入(Write) | ✅ 是 | Company | POST /companies;lifecycle_status=draft;D1 瀑布重查統編 |
| ACT-4b | 註冊精靈/編輯頁更新公司 | 寫入(Write) | ✅ 是 | Company | PATCH /companies/{id};滿足 BR-014 時 BE 設 profile_complete |
| ACT-4c | 查詢資料完成度 | 讀取(Read) | ✅ 是 | ProfileCompleteness | 回傳 missing_fields[] 供 checklist/上架職缺 gate |
| ACT-5 | 儲存欄位顯示偏好 | 寫入(Write) | ✅ 是 | CompanyFieldVisibility | 4 個 boolean(資本額、設立、負責人、董監事) |
| ACT-6 | 新增/刪除/排序 影片 URL | 寫入(Write) | ✅ 是 | CompanyVideoLink[] | 批次取代陣列 |
| ACT-7 | 新增/刪除/排序 痛點 | 寫入(Write) | ✅ 是 | CompanyPainPoint[] | 批次取代陣列 |
| ACT-8 | 新增/刪除/排序 得獎 | 寫入(Write) | ✅ 是 | CompanyAward[] | 批次取代陣列 |
| ACT-9 | 新增/刪除/排序 里程碑 | 寫入(Write) | ✅ 是 | CompanyMilestone[] | 批次取代陣列 |
| ACT-9b | 新增/刪除/排序 QA | 寫入(Write) | ✅ 是 | CompanyQaItem[] | 批次取代陣列 |
| ACT-10 | 重新拉取商工登記資料 | 讀取(Read) + 寫入(Write) | ✅ 是 | TaxIdLookupResult → Company derived | 不解鎖統編;只更新 derived |
| ACT-11 | 查看公司公開頁 | 讀取(Read) | ✅ 是 | Company(依 visibility 過濾) | BE 需依 visibility flags 對外過濾敏感欄位 |
真正的 API path/method 由 backend-api-spec-generator 產出,此表僅標示「是否需要後端」。
8. API Hints(提示用,非最終 API 設計)
8.1 資料讀取需求(Read)
-
HINT-GET-4:平台已支援市場清單
- 對應區塊:SEC-REG-1b、SEC-EDIT-1
- Path 範例:
GET /v2/api/countries/supported - 輸出:
[{ code, name, dial_code }](v1:tw/vn/th) - 用途:註冊與編輯下拉選項;不回傳全球國家表
-
HINT-GET-1:統編查詢(TW)
- 對應區塊:SEC-REG-1, SEC-EDIT-1
- 輸入:
tax_id(8 碼);前置:country_code = tw - 行為(D1):① GCIS live(§12 endpoint,BE 代理+≥24h cache)→ ② 查無則稅籍資料集本地查 → ③ 皆無回
found=false - 輸出:
TaxIdLookupResult(含raw_source) - 限流:單 IP/帳號每分鐘 ≤ 10 次
-
HINT-GET-2:公司公開頁資料
- 對應區塊:SEC-PUB-*
- 輸入:
enc_company_id - 輸出:Company 但需依
field_visibility過濾 capital_amount / establishment_date / representative_name / directors(不過濾 phone / address / employee_count) - Gate:
lifecycle_status != profile_complete或 BR-014 未滿足 → 404(與搜尋顯示條件一致)
-
HINT-GET-3:公司編輯頁資料(管理端)
- 輸入:
enc_company_id - 輸出:Company 全欄位(含敏感欄位、
lifecycle_status、profile_complete);權限:Owner / Admin
- 輸入:
-
HINT-GET-5:公司資料完成度(BR-014 checklist)
- 輸入:
enc_company_id - 輸出:
{ profile_complete, missing_fields: string[], lifecycle_status } - 用途:註冊精靈完成度條、公司編輯頁、發布職缺前 gate
- 輸入:
8.2 資料寫入需求(Write)
以下僅為「需要支援的寫入動作」,欄位命名與 path 由 OpenAPI Spec 決定。
-
HINT-MUTATION-1a:建立公司 draft(Step 1)
- 輸入:
country_code+name+phone+tax_id(三國必填,§4.4.4) + derived overrides(選填) - 行為:建立
lifecycle_status=draft;BE 先驗證tax_id格式(VN/TH checksum;TW 8 碼 checksum)→ 非法回422;僅 TW 接續 D1 瀑布重查 → 命中則tax_id_verified=true並鎖定 - 不要求
logo_url
- 輸入:
-
HINT-POST-validate-tax-id(格式驗證;可獨立 endpoint 或併入 MUTATION-1a)
- 輸入:
country_code+tax_id - 輸出:
{ valid: boolean, normalized?: string, error_code?: string } - 用途:FE blur 時可選呼叫;BE 寫入時必須重驗(不可僅信 FE)
- 輸入:
-
HINT-MUTATION-1b:更新公司(註冊後續步驟/編輯頁)
- 輸入:可變欄位(含
logo_url、intro、產業等) - 行為:每次 PATCH 後 BE 重算 BR-014;全滿足 →
lifecycle_status=profile_complete、profile_complete=true
- 輸入:可變欄位(含
-
HINT-MUTATION-2:更新公司基本資料 + visibility
- 輸入:可變欄位 +
field_visibility(4 個 boolean) - 行為:合併更新;統編欄位若已鎖定則拒絕變更
- 輸入:可變欄位 +
-
HINT-MUTATION-3:上傳 Banner
- 輸入:image binary
- 行為:回傳
banner_url;前端再呼叫 MUTATION-2 將 banner_url 寫入 Company
-
HINT-MUTATION-4:批次取代痛點 / 得獎 / 里程碑 / QA / 影片
- 輸入:陣列(含排序)
- 行為:先驗證每項上限與字數 → 替換整段陣列
-
HINT-MUTATION-5:重新拉取登記資料
- 輸入:
enc_company_id - 行為:D1 瀑布(GCIS → 稅籍)→ 更新 derived(保留
tax_id_locked)→ 失敗保留舊資料
- 輸入:
9. 導航 / Storybook Map
- Storybook 標題:
Mockups/Company/CompanyEditRegisterV2 - Stories 路徑:
storybook/src/stories/mockups/company/CompanyEditRegisterV2.stories.ts - 交付 story:僅 一個
互動預覽(Default);禁止為各步驟另建書籤 story,一律用 Controls 切換 - Storybook 連結:https://storybook.wport.me/?path=/story/mockups-company-companyeditregisterv2—default
- 情境控制(Controls,僅流程切換):
scenario:register-step-tax-id|register-step-logo|register-step-page|register-step-verify|register-done|public-profilecompanyPageContext(僅register-step-page):register-wizard|backend-editregisterCountry/taxIdApiBehavior(僅統編步)
- 畫面內互動(不提供 Controls):Banner 上傳、介紹影片 URL、公開頁欄位顯示勾選等,直接在 mock UI 操作
- 求職者視角預覽(SEC-EDIT-8):
scenario=register-step-page+companyPageContext=backend-edit時,編輯頁標題列「預覽(以求職者視角)」→ 切至public-profile並顯示預覽橫幅;亦可直接選scenario=public-profile檢視公開頁本身 - 對應 production 路由(僅供參考):
- 註冊:
/company/register - 編輯:
/company/{enc_id}/edit - 公開:
/company/{enc_id}
- 註冊:
10. Flowcharts(User / System / Navigation)
10.1 User Flow(使用者操作流程)
flowchart TD
A[使用者進入註冊精靈] --> A1[選擇公司註冊國家/地區]
A1 --> B[輸入統一編號 + 聯絡電話等]
B --> C{checksum<br/>通過?}
C -- 否 --> C1[紅框提示<br/>格式錯誤]
C1 --> B
C -- 是 --> D[① GCIS live 查詢]
D --> E{GCIS 結果}
E -- 命中 --> F[自動帶入 derived]
E -- 查無/失敗 --> E2{② 稅籍資料集}
E2 -- 命中 --> F
E2 -- 皆無 --> G[允許手動填寫]
F --> H[Step 1 下一步]
G --> H
H --> I[POST /companies<br/>lifecycle=draft]
I --> J[上傳 Logo<br/>強提示可跳過]
J --> K[填寫其餘公司欄位<br/>PATCH 更新]
K --> L{BR-014<br/>全滿足?}
L -- 否 --> K
L -- 是 --> M[profile_complete=true<br/>可出現於公司搜尋]
M --> N[跳轉公司管理頁]
N --> O[補 Banner / 影片 / 四區塊]
O --> P[上傳驗證文件 BR-005]
P --> Q[職缺可上架]
10.2 System Flow(前端狀態與資料流)
sequenceDiagram
participant U as User
participant FE as Frontend
participant BE as Backend (代理)
participant GCIS as GCIS live API
participant TAX as 稅籍資料集(本地)
U->>FE: 輸入統編 12345678
FE->>FE: checksum 驗證
FE->>BE: GET /companies/tax-id/lookup?tax_id=12345678
BE->>BE: 檢查 cache (24h TTL)
alt cache hit
BE-->>FE: 200 + 帶入欄位 + raw_source
else cache miss
BE->>GCIS: ① 查詢
alt GCIS 命中
GCIS-->>BE: 公司資料
BE->>BE: 寫 cache (raw_source=gcis)
BE-->>FE: 200 + 帶入欄位
else GCIS 查無
BE->>TAX: ② 稅籍資料集
alt 稅籍命中
TAX-->>BE: 公司資料
BE->>BE: 寫 cache (raw_source=tax_registry)
BE-->>FE: 200 + 帶入欄位
else 雙源皆無
BE-->>FE: 404 NOT_FOUND(可手動註冊)
end
else GCIS 失敗/逾時
BE->>TAX: ② fallback 稅籍
TAX-->>BE: 命中或空
BE-->>FE: 200 / 404 / 503
end
end
FE->>U: 顯示帶入欄位 / 錯誤提示
U->>FE: Step 1 下一步
FE->>BE: POST /companies (country + tax_id + phone + name + derived)
BE->>BE: checksum + D1 瀑布重查
BE-->>FE: 201 + company (lifecycle_status=draft)
U->>FE: 上傳 Logo(可選)/填寫其餘欄位
FE->>BE: POST /upload (logo) + PATCH /companies/{id}
BE->>BE: 重算 BR-014 → profile_complete
BE-->>FE: 200 + company
10.3 Navigation / Story Flow
flowchart LR
A[註冊精靈<br/>Step 1: 基本資料<br/>POST draft] --> B[註冊精靈<br/>Step 2: Logo + 公司頁]
B --> C[註冊精靈<br/>Step 3: 補齊 BR-014]
C --> D[profile_complete<br/>可搜尋]
D --> E[公司管理頁]
E --> F[BR-005 驗證]
F --> G[職缺可上架]
10.4 Edge Case Coverage
| 類別 | 情境 | 系統行為 | UI 回饋 | 可重試 | 資料一致性策略 | 備註 |
|---|---|---|---|---|---|---|
| Network & Performance | 統編 API Timeout > 5s | BE 取消請求並回傳 503 | 顯示「服務暫時無法使用,可重試或手動填寫」+ 重試按鈕 | Yes | 不寫入 tax_id_verified,允許 tax_id 存字串 | |
| Network & Performance | 重複點擊「查詢統編」 | FE disable 按鈕直至前一請求結束;BE 對同一 tax_id 設定 in-flight dedup | 按鈕灰化 + Loading icon | N/A | N/A | |
| Network & Performance | 影片 URL 抓取(v2 oEmbed)失敗 | iframe 仍嵌入;縮圖 fallback 預設灰底 | 顯示影片標題位置改為「影片」 | Yes(重整頁面) | N/A | v2 才實作 |
| Data & Input | 統編格式錯誤(TW 非 8 碼/checksum) | FE 直接拒絕,不打 API | 紅框 + 「統一編號需為 8 碼數字」或 checksum 文案 | N/A | N/A | §4.4.4 |
| Data & Input | VN MST 格式錯誤(非 10/13 碼/checksum) | FE blur + BE POST 雙重驗證 | 紅框 + §4.4.4 錯誤文案 | N/A | 不寫入 | D23 |
| Data & Input | TH MOA 格式錯誤(非 13 碼/第 1 碼非 0/checksum) | FE blur + BE POST 雙重驗證 | 紅框 + 「法人登記號碼需為 13 碼」等 | N/A | 不寫入 | 拒絕 PIN 誤填 |
| Data & Input | TH 誤填自然人身分證 13 碼 | FE/BE 拒絕 | 「請輸入法人登記號碼,不可使用自然人身分證字號」 | N/A | N/A | TAX_ID_PERSONAL_ID_REJECTED |
| Data & Input | VN 分公司 MST 含連字號 | FE 接受 0314409058-002;儲存 0314409058002 | 顯示可還原為 XXXXXXXXXX-NNN | N/A | compact 儲存 | |
| Data & Input | 統編查無資料 | API 回 404 | 提示「查無公示資料,可手動填寫並送出申請」 | Yes | tax_id_verified=false,保留 tax_id 字串 | 對應新設立公司 |
| Data & Input | Banner 上傳超過 5MB | FE 先驗 size 並拒絕;BE 同步驗 | 顯示「Banner 大小限制 5MB」+ 顯示實際大小 | N/A | N/A | |
| Data & Input | 影片 URL 非 YouTube/Vimeo | FE pattern 驗證拒絕 | 紅框 + 「目前僅支援 YouTube 與 Vimeo」 | N/A | N/A | |
| Data & Input | 痛點/得獎/里程碑超過上限 | FE 新增按鈕禁用 | 「已達 X 筆上限」 | N/A | N/A | |
| Data & Input | 統編 derived 欄位特殊字元(公司名含 全形 / emoji) | 正常儲存 UTF-8 | 顯示無亂碼 | N/A | DB UTF-8mb4 | |
| User Interruption | 註冊精靈 Step 1 後離開 | draft 已寫入 BE;可從公司列表續填 | 公司列表顯示「資料未完成」badge | Yes | lifecycle_status=draft 保留 | 取代原 sessionStorage-only |
| User Interruption | 註冊精靈 Step 2+ 未 PATCH 即離開 | 已 PATCH 欄位保留;當步未儲存欄位遺失 | beforeunload「有未儲存變更」 | Yes | 以最後成功 PATCH 為準 | |
| Auth & Lifecycle | draft 超過 30 天未更新 | BE 排程硬刪除(無職缺草稿時) | 列表不再顯示;Owner 收 email 提醒([可選]) | N/A | 見 §4.2 Lifecycle | |
| Auth & Lifecycle | 發布職缺時未 profile_complete | BE 拒絕 publish | 403 + 導向公司編輯;顯示 missing_fields | Yes | 補齊後重試 | 疊加 BR-005 gate |
| User Interruption | 編輯頁未儲存即關閉 | 草稿不自動保存 | beforeunload 提示「有未儲存變更」 | Yes | N/A | 既有行為一致 |
| Auth & Lifecycle | 編輯中 session 過期 | BE 回 401 | 跳轉登入 + 保留 return_to=current_page | Yes | 重新登入後重新讀公司資料 | |
| Auth & Lifecycle | Owner 編輯時被改為 Admin(並發) | BE 仍依當時權限通過 | N/A(角色變更刷新後才會生效) | N/A | 以最終儲存時的角色為準 | |
| Auth & Lifecycle | 統編已驗證後嘗試手動改 | BE 拒絕(403 / 422) | 「統一編號驗證後不可變更,如需協助請聯繫客服」 | No | N/A | 對應 BR-024 |
| Logical Inconsistency | 商工登記 API 部分欄位空(如董監事資料未公示) | 帶入存在欄位,缺漏欄位以空陣列/null 表示 | 帶入欄位顯示綠色勾號;空欄位顯示 placeholder | Yes(重新拉取) | partial_success;不影響 verified 旗標 | |
| Logical Inconsistency | 「重新拉取」後 derived 欄位與企業手改內容衝突 | 一律覆蓋全部 derived 欄位(D12);不顯示 diff modal | 提示「已更新為最新登記資料」 | Yes | v1 全覆蓋;diff 裁決視窗延 v2 |
11. Mock Data Schema(Mock 資料結構)
- 資料來源:僅 mock,不呼叫真實 API(含商工登記 API 由 Storybook 內以 sleep + 預設 fixture 模擬)
- CRUD 行為:mock 內所有新增/修改/刪除僅存在元件狀態,重新整理後還原
- 情境切換:
scenario=register-step-tax-id:Step 2 公司基本資料(統編 / 國家 / 電話)scenario=register-step-logo:Step 3 上傳公司 Logo(強提示,可跳過)scenario=register-step-page:公司頁(Step3CompanyPage + v2 注入);以companyPageContext切換註冊精靈或後台編輯外殼scenario=register-step-verify:Step 5 公司審核(對齊 Step4CompanyVerify)scenario=register-done:Step 6 完成scenario=public-profile:顯示公開頁(Banner / 影片 / 統編 / 三個底部區塊)
- Mock Fixtures(建議):
- 已驗證公司:tax_id=
89121689→ 「熱火數碼資訊股份有限公司」(經濟部公示資料見 §13.6.1) - API 失敗示例:tax_id=99999999 → 503 API_DOWN
- 查無資料示例:tax_id=11111111 → 404 NOT_FOUND
- 已驗證公司:tax_id=
12. 實作備註(Implementation Notes)
-
禁止事項:
- ❌ 本文件不直接定義最終 API path/method/JSON schema,僅提供 Hints
- ❌ 不直接修改
prd/business-rules.md;BR-024 / BR-025 建議由 PM 於 PRD 確認後另開 PR 更新 - ❌ 統編 API 不直接從 FE 呼叫(CORS + rate-limit + cache 集中管理)
-
注意事項:
- 欄位命名與 Storybook/TS interface 一致(Storybook mockup 完成後以其為 SoT)
- 商工登記公示資料 API 為經濟部商業司公開資料(具體 endpoint 由 RD 確認;建議於
https://data.gcis.nat.gov.tw/開放資料平台尋找最新 endpoint) - 權限對齊 BR-016:公司編輯頁所有寫入動作需 Owner / Admin
- 既有 logo 規則延續 BR-006:Logo 為 BR-014 /
profile_complete必要條件;draft 不進搜尋(D17/D22) - Lifecycle(D22):Step 1
POST建立 draft;C 端曝光看profile_complete;職缺上架看 BR-005 - 欄位顯示偏好與公司搜尋顯示條件 (BR-014) 為獨立邏輯:visibility 控制公開頁顯示,與搜尋曝光資格無關
- 統編 checksum 演算法:TW 見 §4.4.4;VN
vn.mst;THth.moa(BE 須與 FE 同規則,參考storybook/src/utils/company-tax-id.ts) - 統編唯一性(沿用既有,非 v2 新規):註冊「檢查可用性」→
validate-uniform-number(僅擋已認證占用);認證前可共存 → 公司認證通過時防重複統編 →company-approval-process-flowchart.md§統編驗證規則
-
🟢 TW 統編查詢 — 雙軌(D1,2026-06-29 定案):
- ① GCIS live(優先) — 已實測可行(2026-06-23):
- 公司基本資料:
GET https://data.gcis.nat.gov.tw/od/data/api/5F64D864-61CB-4D0D-8AD9-492047CC1EA6?$format=json&$filter=Business_Accounting_NO eq <統編>;公開、無金鑰。實測台積電22099131→ HTTP 200 / 160ms,回Company_Name、Capital_Stock_Amount(資本額)、Paid_In_Capital_Amount(實收)、Responsible_Name(負責人)、Company_Location(地址)、Company_Setup_Date(設立日期)、Company_Status_Desc(現況)。 - 董監事(另一支 API):
GET https://data.gcis.nat.gov.tw/od/data/api/4E5F7653-1B91-4DDC-99D5-468530FAE396?$format=json&$filter=Business_Accounting_NO eq <統編>;實測 HTTP 200 / 137ms,回Person_Position_Name(職稱)、Person_Name/Juristic_Person_Name、Person_Shareholding(持股)。→ PRD §5 的directors[]要接這支(與基本資料分開查)。 - ⚠️ 日期是民國格式:
Company_Setup_Date=0760221(民國76年→1987-02-21),BE 須 ROC→西元轉換後再存。 - ⚠️ 正式上線:應用一可直接打,但系統介接需填表報備+IP 白名單(opendata.gcis@gmail.com)、有流量限制 → 維持 PRD 既定「BE 代理+≥24h cache」。
- 結論:GCIS 技術可行;正式上線走 BE 代理+cache+IP 白名單(§14 #4 已完成)
- ② 稅籍資料集(fallback):財政部全國營業稅籍登記資料集,離線/批次匯入本地庫;GCIS 查無或失敗時接續查詢;
raw_source=tax_registry_dataset - ③ 雙源皆無:允許手動註冊,
tax_id_verified=false
13. 一致性審計(Stage 5 / 6 產出)
13.1 Field Mapping Table(SoT:本 PRD §5)
| 欄位 | PRD | Storybook | business-rules.md | SoT | Version |
|---|---|---|---|---|---|
tax_id | ✅ | 待產 | 對應 BR-005 文件「統一編號編配通知書」 | PRD | v1 |
country_code | ✅ | ✅ | supported markets;統編後可搜尋下拉 | PRD §4.4 | v1 |
phone_dial_code | ✅ | ✅ | +886/+84/+66;連動 country | PRD §4.4.3 | v1 |
tax_id_verified | ✅ | 待產 | BR-024(建議新增) | PRD | v1 |
tax_id_locked | ✅ | 待產 | BR-024(建議新增) | PRD | v1 |
lifecycle_status | ✅ | 待產 | D22 draft / profile_complete | PRD §4.2 | v1 |
profile_complete | ✅ | 待產 | BR-014 計算欄位 | PRD §4.2 | v1 |
logo_url | ✅ | 既有 | BR-006;profile_complete 時必填;draft 可空 | PRD + BR-006 | v1 |
banner_url | ✅ | 待產 | 無相關 BR | PRD | v1 |
video_links[](≤3) | ✅ | 待產 | 無相關 BR | PRD | v1 |
field_visibility.* | ✅ | 待產 | BR-025(建議新增) | PRD | v1 |
pain_points[](≤5) | ✅ | 待產 | 無相關 BR | PRD | v1 |
qa_items[](≤20) | ✅ | 待產 | 無相關 BR | PRD | v1 |
awards[](≤20) | ✅ | 待產 | 無相關 BR | PRD | v1 |
milestones[](≤20) | ✅ | 待產 | 無相關 BR | PRD | v1 |
capital_amount/representative_name/registered_address/establishment_date/directors[] | ✅ derived | 待產 | 無相關 BR | PRD | v1 |
13.2 Constants Table
| 常數 | 值 | 位置 | SoT | Version |
|---|---|---|---|---|
| Supported markets (v1) | tw, vn, th | BE /countries/supported | PRD §4.4 | v1 |
| 統編位數(TW) | 8 | §4.4.4 | 國家標準 | v1 |
| MST 位數(VN) | 10 或 13 | §4.4.4 | 稅務總局 Circular 105/2020 | v1 |
| MOA 位數(TH) | 13 | §4.4.4 | DBD 法人登記 | v1 |
| 電話國碼(v1) | +886, +84, +66 | PRD §4.4.3 | PRD | v1 |
| GCIS API cache TTL | 24h | BE | PRD §8 | v1 |
| Banner max size | 5 MB | PRD §5.3 | PRD | v1 |
| Logo max size | 2 MB | PRD §5.3 + BR-006 | PRD | v1 |
| Video links max | 3 | PRD §5.3 | PRD | v1 |
| Pain points max | 5 | PRD §5.3 | PRD | v1 |
| Awards max | 20 | PRD §5.3 | PRD | v1 |
| Milestones max | 20 | PRD §5.3 | PRD | v1 |
| Statement query rate limit | 10/min/IP | PRD §8.1 | PRD | v1 |
| API timeout | 5s | PRD §10.4 | PRD | v1 |
13.3 Event Dictionary
| 事件名稱 | 觸發點 | Payload 重點 | SoT |
|---|---|---|---|
company.tax_id.lookup_succeeded | SEC-REG-1 / SEC-EDIT-1 重新拉取 | tax_id, fetched_at | PRD |
company.tax_id.lookup_failed | 同上失敗 | tax_id, error_code | PRD |
company.banner.uploaded | SEC-EDIT-2 上傳成功 | enc_company_id | PRD |
company.created_v2 | Step 1 POST draft 成功 | enc_company_id, tax_id_verified, lifecycle_status | PRD |
company.profile_completed | BR-014 全滿足 | enc_company_id | PRD |
company.visibility_updated | SEC-EDIT-4 儲存 | enc_company_id, flags | PRD |
13.4 Terminology Dictionary
| 中文 | 英文 | 定義 |
|---|---|---|
| 統一編號 | Tax ID (tw) | 台灣 8 碼公司編號 |
| 稅籍編號(MST) | MST (vn) | 越南企業識別/稅籍號;10 碼總公司或 13 碼分公司(如 0314409058-002) |
| 法人登記號碼 | DBD MOA / TIN (th) | 泰國商業發展部(DBD)核發的法人登記號碼(MOA),通常也作為法人稅籍號(TIN);固定 13 碼;範例 0994000617721 |
| 公司登記號碼 | Company Registration Number | 三國共用 tax_id 欄位之泛稱;UI label 依 country_code 切換 |
| 公司註冊國家/地區 | Company Registration Country | ISO code;v1 僅 supported markets(TW/VN/TH) |
| 統編已驗證 | Tax ID Verified | 透過商工登記公示資料 API 比對通過;後端旗標,C 端不顯示徽章(D20) |
| 公司認證 | Company Verified | 對應 BR-005,WPort 人工審核通過(與統編驗證獨立) |
| 公司 Lifecycle | Company Lifecycle | draft(已建立、C 端不可見)→ profile_complete(BR-014 滿足、可搜尋)→ BR-005(可上架職缺) |
| 資料完成度 | Profile Completeness | BE 依 BR-014 計算;missing_fields[] 供 FE checklist |
| 自訂 Banner | Custom Banner | 公司頁面頂部橫幅圖 |
| 欄位顯示偏好 | Field Visibility | BR-025;4 欄可切換;電話/地址/員工恆常公開(D15) |
| 解決的痛點 | Pain Points | 公司產品/服務解決的問題 |
| 得獎資訊 | Awards | 企業所獲獎項 |
| 里程碑 | Milestones | 企業重要時間軸節點 |
13.5 版本凍結表
| 項目 | v1/v2 | Blocking? | 理由 | Decision maker | Date |
|---|---|---|---|---|---|
| 統編 API 整合 + 帶入 derived | v1 | ✅ | 核心 | Eric | 2026-05-15 |
| Logo profile_complete 必填 | v1 | ✅ | BR-006/014 gate(D17 修訂) | Eric | 2026-07-07 |
| 公司 Lifecycle(draft 早建立) | v1 | ✅ | D22 | Eric | 2026-07-07 |
| Banner 上傳 | v1 | ✅ | 描述明確 | Eric | 2026-05-15 |
| 影片 3 個 URL | v1 | ✅ | 描述明確 | Eric | 2026-05-15 |
| 統編顯示於公司頁 | v1 | ✅ | 描述明確 | Eric | 2026-05-15 |
| 欄位顯示偏好(4 個) | v1 | ✅ | D15 | Eric | 2026-06-29 |
| 4 個底部選填區塊(痛點/得獎/里程碑/QA) | v1 | ✅ | D18 | Eric | 2026-06-29 |
| 影片 oEmbed 預覽 | v2 | ❌ | 體驗加分 | Eric | 2026-05-15 |
| 員工心聲、福利圖示化 | v2 | ❌ | 非本次範圍 | Eric | 2026-05-15 |
| VN/TH tax_id 必填 + 格式驗證 | v1 | ✅ | D23 | Eric | 2026-07-08 |
13.6 Storybook 區塊對照表(PRD ↔ Mockup)
對應 Story:
storybook/src/stories/mockups/company/CompanyEditRegisterV2.stories.ts
最後更新:2026/06/22
| PRD 區塊 ID | 區塊名稱 | MVP | Storybook scenario | 主要元件 | 備註 |
|---|---|---|---|---|---|
| SEC-REG-1 | 統編查詢(TW GCIS) | ✅ | register-step-tax-id | MockupStep2CompanyBasicV2.vue | 驗證成功後 Step2 僅 inline 提示;derived 於 Step4 帶入 |
| SEC-REG-1b | 公司註冊國家/地區 | ✅ | register-step-tax-id | MockupStep2CompanyBasicV2.vue、CompanyCountryFieldInject.vue | 可搜尋下拉;TW/VN/TH |
| SEC-REG-1c | 聯絡電話 | ✅ | register-step-tax-id | MockupStep2CompanyBasicV2.vue | 國碼連動 country |
| SEC-REG-1d | Step 1 建立 draft | ✅ | register-step-tax-id | MockupStep2CompanyBasicV2.vue | POST 後取得 enc_id |
| SEC-REG-2 | Logo 步 | ✅ | register-step-logo | MockupCompanyEditRegisterV2.vue(內嵌) | 強提示;可跳過進下一步 |
| — | 公司頁(既有區塊) | ✅ | register-step-page | Step3CompanyPage.vue(production 快照) | 介紹/服務/福利 |
| SEC-EDIT-1 | 公司基本資料增量 | ✅ | register-step-page(companyPageContext 皆可) | CompanyRegisterGcisFieldInject.vue | 統編唯讀;derived 預填 |
| SEC-EDIT-2 | 自訂 Banner | ✅ | register-step-page | CompanyPageV2Inject.vue | 橫幅 +「上傳圖片」 |
| SEC-EDIT-3 | 介紹影片 / 照片+YouTube URL | ✅ | register-step-page | CompanyPageV2Inject.vue | 最多 3 組;YouTube/Vimeo |
| SEC-EDIT-4 | 欄位顯示偏好 | ✅ | register-step-page | CompanyPageVisibilityFieldInject.vue | 資本額/設立/負責人/董監事;無電話/地址/員工開關(D15) |
| SEC-EDIT-5 | 解決的痛點 | ✅ 選填 | register-step-page | CompanyPageV2BenefitsExtraInject.vue | 最多 5 筆 |
| SEC-EDIT-6 | 得獎資訊 | ✅ 選填 | 同上 | CompanyPageV2BenefitsExtraInject.vue | 最多 20 筆 |
| SEC-EDIT-7 | 里程碑 | ✅ 選填 | 同上 | CompanyPageV2BenefitsExtraInject.vue | 最多 20 筆 |
| — | QA(可折疊) | ✅ 選填 | 同上 | CompanyPageV2BenefitsExtraInject.vue | PRD §3.2 四區塊之一 |
| — | 公司審核 | ✅ | register-step-verify | Step4CompanyVerify.vue | 上傳統編編配通知書等 |
| — | 註冊完成 | ✅ | register-done | Step5CompanyDone.vue | — |
| SEC-PUB-1~4 | 公司公開頁 | ✅ | public-profile | CompanyEditRegisterV2Delta.vue(mode=public) | Banner/統編(無徽章)/影片/底部區塊 |
register-step-page 欄位狀態(統編已驗證)
| 欄位 | 來源 | 預填 | 可編輯 | 備註 |
|---|---|---|---|---|
| 統一編號 | GCIS | ✅ | ❌ 鎖定 | BR-024;唯讀,不顯示徽章(D20) |
| 公司註冊國家/地區 | Step2 | ✅ | ✅ | 必填 |
| 公司名稱 | GCIS | ✅ | ✅ | 標示「經濟部帶入,可修正」 |
| 資本額、登記地址 | GCIS | ✅ | ✅ | 同上 |
| 負責人、設立日期、董監事 | GCIS | ✅ | ✅ | v2 增量欄位 |
| 產業、電話 | Step2 使用者填寫 | ✅ | ✅ | 模擬已完成 Step2 |
| 員工人數、網站 | — | ❌ | ✅ | Step4 待填 |
| 公司介紹、服務項目、福利 | — | ❌ | ✅ | Step4 待填 |
| Logo | Step3 | ✅ | ✅ 可更換 | 模擬已上傳 |
| Banner、影片 URL、痛點/得獎/里程碑/QA | — | ❌ | ✅ | v2 選填增量 |
13.6.1 經濟部 GCIS 欄位對照(Mock Fixture:89121689)
| 經濟部公示欄位 | Storybook / 系統欄位 | 寫入公司資訊方式 | 可編輯 |
|---|---|---|---|
| 統一編號 | tax_id / uniform_number | 唯讀顯示;驗證後鎖定 | ❌ |
| 公司名稱 | company.name | Step4 基本資料「公司名稱」預填 | ✅ 可修正 |
| 登記人/負責人 | representative_name | 預覽區展示;編輯表單預填(無標籤) | ✅ |
| 公司登記狀況 | registration_status | 公司頁預覽區唯讀展示 | ❌ |
| 組織別 | organization_type | 公司頁預覽區唯讀展示 | ❌ |
| 公司登記營業項目 | registered_business_items | 公司頁預覽區唯讀展示;≠ 平台產業類別 | ❌ |
| 公司登記營業地址 | registered_address → address | 基本資料表單預填 | ✅ |
| 公司登記機關 | registration_authority | 公司頁預覽區唯讀展示 | ❌ |
| 設立日期 | establishment_date | 預覽區展示;編輯表單預填 | ✅ |
| 資本額 | capital_amount | 基本資料表單預填 | ✅ |
| 董監事 | directors[] | API 有資料時注入 | ✅ |
| 公司註冊國家/地區 | country_code | Step2 已填;公司頁不重複 | — |
| 產業類別、電話 | Step2 | 公司頁預覽/編輯表單預填 | ✅ |
注意:GCIS「營業項目」為政府登記項目清單;WPORT「產業類別」為平台搜尋分類(BR-014),兩者分開維護。
13.7 PRD 問題清單
| # | PRD 段落 | 問題 | 建議修正 | 類別 | 影響 | SoT |
|---|---|---|---|---|---|---|
| 1 | §4.2 | BR-024 / BR-025 為新規則建議,需另開 PR 寫入 business-rules.md | 後續由 Eric 確認後一次性更新 BR 文件 | 規則同步 | 低 | business-rules.md |
| 2 | §8.1 HINT-GET-1 | ✅ 已驗證(2026-06-23):公開 API、無金鑰;基本資料 OID 5F64D864、董監事 OID 4E5F7653,實測皆 HTTP 200(詳見 §12) | 落地注意:設立日期民國需轉換、董監事另支 API、正式上線需 IP 白名單 | 整合(已解除) | 低 | RD |
| 3 | §10.4 / §5.3 | 影片 URL 白名單目前限 YouTube + Vimeo;Bilibili / Facebook 不支援 | 若日後需擴增,於 v2 評估 oEmbed-only 模式 | 範圍 | 低 | PRD |
| 4 | §5.2 | 「重新拉取商工登記」是否需要保留前版 derived 快照供回滾 | 建議 v1 不做版本歷史;異常時手動重填 | 範圍 | 低 | PRD |
| 5 | §4.1 BR-014 | 電話/地址 visibility | 電話、地址、員工不納入 BR-025,恆常公開(D15) | 一致性 | — | PRD |
若上述項目於開發前皆達成共識,無 blocking 阻擋。
13.8 PRD Gap 補丁(2026-06-23 盤點;2026-06-29 決策收斂)
站在「能否直接餵 spec generator」角度盤點的缺口與冗餘。🔴 = 不補會讓 RD 產 spec 時亂猜;🟡 = 一致性/狀態機缺角;🟢 = 建議交代。 決策以 §1.5 D9–D22 為準;下表保留盤點脈絡,已決項標 ✅。
A. 缺少的決策(會卡 spec)
| # | 狀態 | 嚴重度 | 缺口(白話) | 裁決(§1.5) |
|---|---|---|---|---|
| G1 | ✅ | 🔴 | 重新拉取時,企業手改過的 derived 欄位要不要保留? | D12:v1 不做覆寫旗標;重新拉取一律覆蓋全部 derived 欄位;diff modal 延 v2 |
| G2 | ✅ 取消 | — | (已移除)統編驗證徽章與 derived 手改語意衝突 | D20:v1 不顯示統編驗證徽章;C 端信任以 BR-005 公司認證為準 |
| G3 | ✅ | 🔴 | 影片幾欄?有沒有照片? | D11:最多 3 影片 URL(0–3 彈性);v1 無獨立照片欄 |
| G4 | ✅ | 🟡 | verified 與 locked 關係不清 | D10:狀態表見 §4.4.2;TW 查詢成功 → verified+locked;其餘 → 皆 false |
| G5 | ✅ | 🟡 | 痛點/得獎/里程碑要不要拖曳? | D13:v1 做拖曳 + display_order;mockup 待補 |
| G6 | ✅ | 🟡 | 既有公司 visibility migration? | D14:已勾不顯示者不動;負責人/設立/董監事無歷史值 → 顯示;資本額無歷史值 → 不顯示;電話/地址/員工不適用 |
| G7 | ✅ | 🟡 | tw vs TW 大小寫 | D19:統一小寫 tw/vn/th |
| G8 | ✅ | — | 多語系 | D9(先前已裁決) |
| G9 | ✅ | 🟡 | 公司建立時機與 draft lifecycle | D22:Step 1 POST draft;profile_complete 綁 BR-014;30 天清理 |
B. 多餘 / 噪音(建議刪或標示,避免污染 SoT)
| # | 段落 | 處置建議 |
|---|---|---|
| R1 | §5.2 整段欄位定義(TypeScript) | 欄位名稱寫得很細,但文件又說「以 Storybook 為準」→ 兩個版本互打。建議縮成「概念欄位清單」,或段首註明「名稱只是示意、非最終 API」 |
| R2 | §13.6 前端元件檔名 / 元件選型 | 前端實作筆記,對產 API 規格沒幫助、是雜訊;移到前端實作 issue,不留在 PRD |
| R3 | 影片預覽縮圖等「v2 才做」散在多處 | v1 不做;從 v1 欄位定義拿掉或標清「v2 才有」,免得規格生出 v1 用不到的欄位 |
| R4 | §4.4.3 電話格式表 與 SEC-REG-1c 重複 | 同內容兩處;留一處、另一處改為「見上」 |
C. Storybook ↔ PRD 落差(線上版比對,2026-06-23)
對線上
mockups-company-companyeditregisterv2--default的來源元件逐一比對。「對齊方向」= 該改 PRD、改 mockup、還是先決策。D4↔G3、D5↔G4、D6↔G1、D8↔G5 同源(補丁缺口在 mockup 已現形);D1/D2/D3/D7 為 mockup 與 PRD 直接對不上的新項。 📷 D2/D4/D8 已於 2026-06-23 用 Playwright 對線上版實際截圖確認(非僅讀碼):D2 logo 步畫面寫「JPG/PNG/GIF/WEBP,5 MB 以內」;D4 「照片以及youtube url」欄底下是純文字 URL 框+「+ 新增連結」、無照片上傳;D8 痛點區只有 標題/描述/移除/新增,draggable=0、無任何拖曳元件。
| # | 嚴重度 | 項目 | PRD 怎麼說 | Storybook 實際 | 對齊方向 |
|---|---|---|---|---|---|
| D1 | ✅ | 顯示偏好涵蓋範圍 | D15:僅 4 欄可控;電話/地址/員工恆常公開 | mockup 移除 phone/address/employee_count 的 checkbox | |
| D2 | 🟡 | Logo 規格 | §5.3:≤ 2MB、JPG/PNG | 兩個上傳器不一致:Step3 = 5MB+JPG/PNG/GIF/WEBP;公司頁提示 = 2MB+JPG/PNG | 改 mockup:Step3 對齊 2MB/JPG·PNG,與公司頁一致 |
| D3 | 🟡 | Mock 公司名 | §13.6.1 fixture:統編 89121689 → 熱火數碼資訊 | 同統編兩個名:GCIS 帶入「熱火數碼資訊」、公司頁顯示「三宏科技 Trident」 | 改 mockup:MOCK_COMPANY_PAGE_DISPLAY.name 對齊 GCIS fixture |
| D4 | ✅ | 影片欄位 | 見 D11 | page-inject 已為「最多 3」;Delta 改彈性 + 移除「照片以及」label | |
| D5 | 🟡 | 統編鎖定→國家鎖定 | D10 已定 | 改 mockup:tax_id_locked 時國家下拉 :disabled | |
| D6 | ✅ | 帶入資料覆寫 | D12 全覆蓋 | 無需覆寫旗標 | |
| D7 | 🟡 | 底部區塊數 / KPI | D18 保留 4 區塊 | PRD §6.1 補 QA、§3.3 KPI 改「4 個」 | |
| D8 | 🟡 | 拖曳排序 | D13 要做 | 改 mockup:補拖曳 UI + display_order |
詞彙表(白話對照)
| 術語 | 白話 |
|---|---|
| derived 欄位 | 政府(GCIS/商工登記)自動帶入的公司資料:公司名、資本額、負責人、地址、設立日期、董監事 |
| verified(已驗證) | 統一編號已通過經濟部商工登記查詢(後端旗標;C 端不掛徽章,D20) |
| locked(鎖定) | 驗證後該欄位變唯讀、不能自行修改 |
| field visibility(顯示偏好) | 控制某欄位要不要在「公司公開頁」對外顯示 |
| migration / backfill | 對「上線前既有資料」補設定預設值 |
| SoT(單一事實來源) | 以哪份文件/系統為唯一準據 |
| enum | 後端欄位允許值的固定清單 |
| oEmbed | 自動抓影片標題/縮圖的機制(v2 才做) |
補丁狀態:§1.5 D9–D22 已拍板。待 mockup 對齊:D15 移除電話/地址/員工開關、D2 Logo、D3 公司名、D5 國家 disabled、D8 拖曳 UI、D20 移除統編徽章、D22 Logo 步可跳過 + 完成度 checklist。
13.9 PRD 產品/UX 合理性審查(2026-06-23;2026-06-29 PM 裁決)
與 §13.8 不同視角:本節質疑 PRD 本身是否合理,與 mockup 一致性無關。 裁決結果已回寫 §1.5;本表保留審查意見 → PM 回應脈絡,並補 為何採納/拒絕 供日後覆盤。
🔴 站不住腳 / 該重想
| # | PRD 決定 | 審查意見(為何可議) | 裁決 | 為何採納/拒絕 | §1.5 |
|---|---|---|---|---|---|
| P1 | 統編驗證後鎖定(BR-024) | 後端 mutation 可「改了就重驗」,已防規避;鎖定不可逆、國家連帶鎖死、增加客服量 | 拒絕 P1 | 統編是法人身分錨點,誤改/偷換的復原與審核成本高於一般欄位;國家連動統編格式,允許自助改國家會製造 uq 與審核邊界 case。「重驗」擋得住格式錯誤,擋不住驗證通過後刻意換身分的動機。真實統編變更極罕見,客服+審計是合理路徑 | D10 |
| P2 | 電話預設顯示;負責人/設立/董監事預設隱藏 | ① 電話比姓名更敏感 ② 政府公開資料使「隱藏」非真隱私 | 部分採納後修正(D14/D15) | 不對電話做 visibility(延續 WPort 恆常公開);僅資本額預設隱藏;負責人/設立/董監事預設顯示 | D14、D15 |
| P3 | v1 開 TW/VN/TH 三市場 | 主賣點是統編自動帶入,VN/TH 無 GCIS → 更長表單、零核心價值,實質 TW 獨做 | 拒絕 P3 | 平台已對外承諾三市場(BR-023、pm_34);撤回 VN/TH 是商業與工程 scope 倒退。本期價值主軸 = TW 帶入 + 全體品牌強化(Banner/影片/里程碑);VN/TH 以文件審核路徑交付,待 RD 確認各國資料源後再加自動帶入 | D18 |
| P4 | 公開頁顯示統一編號 | 求職者不需要統編;公開便利冒名/爬蟲,看不出 C 端價值 | 拒絕 P4 | 台灣招募脈絡下,公開統編號碼仍是辨識公司身分的慣用資訊(對齊 104)。信任門檻以 BR-005 公司認證為準,不需另掛統編驗證徽章(D20)。爬蟲風險不足以否定整欄 | D16、D20 |
| P5 | Logo 硬性必填、擋住註冊下一步 | KPI「上傳率 100%」是必然;真正該看註冊完成率是否下降;軟性提示較顧轉換 | 部分採納(2026-07-07 修訂 D17/D22) | 原裁決拒絕 P5;後續產品討論確認:C 端信任應綁 BR-014 曝光 gate 而非註冊尾端一次擋死。改為 Step 1 早建 draft + profile_complete 硬 gate;獨立追蹤 Step1 建立率、profile_complete 率、首職缺上架率 | D17、D22 |
🟡 可議 / 建議調整
| # | PRD 決定 | 審查意見(為何可議) | 裁決 | 為何採納/拒絕 | §1.5 |
|---|---|---|---|---|---|
| P6 | 底部 4 個 free-text 區塊 | 一次加 4 區塊偏重;「痛點」是 pitch 語言;KPI 25% 填寫率顯示團隊也沒把握 | 拒絕 P6 | 痛點語言確實偏 B2B pitch,但 4 區塊已進 mockup、§3.3 KPI 與競品 benchmark(104/LinkedIn milestones+awards)。v1 砍半需重寫驗收、收益不明。若上線後填寫率低迷,v2 再收斂呈現或合併區塊,而非動工前縮 scope | D18 |
| P7 | 影片「固定 3 組」 | 有公司 0 支有公司 5 支;固定 3 逼空欄或截斷 | 採納 | 審查正確。改為「最多 3、0–3 彈性」對 0/1/2 支影片的公司都友善,schema 不變(仍是陣列上限 3),mockup 已部分如此 | D11 |
| P8 | 重新拉取 + 差異對照視窗 | 政府資料變動極低,卻配高成本 diff UX;低頻事件過度設計 | 採納 | 「重新拉取」= 以官方公示為準(D12),故 v1 全覆蓋合理;不另做 diff modal 是因登記資料變更頻率極低、建置/測試/維護成本高。v1「全覆蓋 + toast」足夠;若上線後出現覆寫被蓋客訴,v2 再評估 is_*_overridden + diff | D12 |
| P9 | KPI 帶入成功率 ≥85%,兜底放 v2 | 約 1/7 TW 註冊者可能撞查詢失敗且無順暢退路 | 延後觀察 | D1 雙源瀑布 + 雙源皆無仍可註冊,已覆蓋兜底;上線後監控 GCIS/稅籍各自命中率再調 KPI | D1 |
| P10 | 非支援國家無出口 | 非三國使用者進註冊是死路 | 採納(限三國) | 本期無力服務三國以外,自然不處理非支援國家註冊;v1 不做 waitlist。入口由 /countries/supported 白名單限三國即可 | D21 |
14. 同步修正清單(Sync-Fix List)
| # | 動作 | 負責人 | Blocking? | 截止 |
|---|---|---|---|---|
| 1 | 完成 CompanyEditRegisterV2.stories.ts mockup | FE / Eric | ✅ | 本次任務內 |
| 2 | 部署 Storybook 並回填 §1 連結 | 自動 / sb-deployed | ✅ | 本次任務內 |
| 3 | business-rules.md 新增 BR-024 / BR-025 | Eric | ❌ | 開發前 |
| 4 | ✅【已驗證 2026-06-23】 GCIS endpoint 可行(基本 5F64D864+董監事 4E5F7653,公開無金鑰,詳見 §12);限流走 BE 代理+cache+IP 白名單 | RD | ✅ | 已完成 |
| 5 | Coda backlog PRD 欄位回寫 pm_38 | Eric / 自動 | ✅ | 本次任務內(Stage 9) |
| 6 | RD 實作 lifecycle_status / profile_complete / draft 清理排程 | RD | ✅ | 開發前 |
15. 下一步(Next Steps)
- 以本 PRD 為輸入跑
storybook-mockup-gen→ 產出CompanyEditRegisterV2.stories.ts+ 對應 mockup 元件 sb-deployed部署 Storybook → 取得實際 Story URL → 回填本 PRD §1 + Coda- RD 依本 PRD §5 / §7 / §8 產 OpenAPI Spec(含
POST /companiesdraft、PATCH /companies/{id}、GET .../profile-completeness;GCIS 整合方案於該階段落地) - PM 將 BR-024 / BR-025 / Lifecycle(§4.2)寫入
business-rules.md(獨立 PR)
文件結束