◆ wport | pm_30

公司快速註冊 Mockup PRD

公司快速註冊

來源 doc/feature/pm_30/company-quick-register-mockup.md

公司快速註冊 Mockup PRD

此範本專門給 30%-feature-gen 產出的 mockup PRD 使用。 backend-api-spec-generator 會讀取這份文件與 Storybook mockups 來產生後端 API 規格。


1. 文件資訊

  • 文件類型:Mockup 需求規格書(前後端共用視圖)
  • 適用對象:前端開發、後端開發、產品、QA
  • 最後更新:2026/03/16
  • 版本:1.2.0
  • 對應 Storybookstorybook/src/stories/mockups/company/CompanyQuickRegister.stories.ts
  • Storybook 連結CompanyQuickRegister
  • 建立日期:2026/03/04

2. 開發進度與設計來源

開發進度

  • 前端 PR #:TBD
  • 後端 PR #:TBD

設計來源

  • Figma 連結:無(組合既有模組)
  • 既有畫面參照
    • 校園活動招募 Step 1 註冊/登入 + OTP 驗證(MockupCampusEventQuickApplySheet.vue + MockMainSiteAuth.vue
    • 既有前端 company-register 頁面

3. 模擬頁面摘要(Mockup Summary)

3.1 功能概述

  • 功能名稱:公司快速註冊(Company Quick Register)
  • 主要使用者角色:企業主 / HR / 被主管指派建立公司頁面的人
  • 核心目標
    • 將「使用者帳號註冊 → email 驗證 → 會員基本資料 → 公司頁面建立」串成一條連貫流程
    • 消除現有流程中「註冊帳號後被導回首頁、找不到建立公司入口」的斷裂體驗
    • 使用 OTP 驗證碼取代驗證連結,使用者始終留在同一畫面
    • OTP 驗證流程與一般網站註冊/登入共用同一套機制,非僅限本流程或校園活動

3.2 範圍界定

  • 包含範圍
    • 獨立頁面(沿用既有 company-register URL)
    • Step 1:註冊/登入 + OTP 驗證(沿用校園活動模組 MockMainSiteAuth + OTP 流程)
    • Step 2:會員基本資料填寫(僅顯示必填欄位,非必填不顯示;僅新註冊用戶需填寫)
    • Step 3:公司基本資料填寫(沿用既有前端 company-register 模組)
    • Google 註冊/登入(既有模組)
    • 多語系(既有模組)
    • 已登入使用者(已有個人資料)跳過 Step 1 與 Step 2,直接進入 Step 3
    • 已登入未驗證使用者補做 OTP 驗證
    • 公司建立上限檢查(每帳號以**擁有者(owner)**身份最多 10 間;僅計算本人為 owner 的公司,被加入為成員的公司不計入)
  • 排除範圍
    • 不做履歷相關流程
    • 不做公司驗證(上傳文件審核,屬後續既有流程)
    • 不做中斷還原的額外處理(公司資料填寫的中斷行為與既有 company-register 一致)
    • 不做公司後續管理流程(建立完成後導向既有公司頁面)

3.3 成功條件

  • 沒有帳號的人經此流程完成公司帳號註冊的比例
  • 有帳號的人經此流程完成新增公司的比例
  • 使用者不再因為「註冊帳號後被導回首頁」而迷路

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

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

規則 ID規則摘要是否關鍵備註
BR-001只有信箱認證後才能登入✅ 是本流程使用 OTP 驗證碼完成 email 驗證
BR-002信箱認證後仍然要完成個人資料✅ 是Step 2 會員資料即為完成個人資料必填欄位
BR-004只有信箱認證的使用者帳號可以新增公司頁面✅ 是驗證完成後才允許進入公司資料填寫
BR-NEW每個帳號以擁有者身份最多建立 10 間公司;被加入為成員不計入✅ 是新規則,需回寫 business-rules.md

4.2 補充說明

  • OTP 驗證碼 API 與一般網站註冊/登入共用同一套端點(校園活動亦沿用),與主站的「驗證連結」方式不同
  • 第三方登入(Google)不需 OTP 驗證碼,直接視為 verified
  • 公司上限 10 間的檢查以本人為 owner 的公司數量為準;僅為成員(被加入)的公司不計入。檢查在登入/驗證完成後立刻執行,達上限則不進入後續步驟
  • Step 2 會員資料僅對新註冊用戶(個人資料尚未填寫)顯示;已登入且個人資料已完成的使用者跳過此步驟

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

5.1 實體列表

實體名稱說明來源頁面/區塊
AuthState使用者認證狀態Step 1 認證流程
MemberProfileForm會員基本資料表單Step 2 會員資料填寫
CompanyRegisterForm公司基本資料表單Step 3(沿用既有 company-register)

5.2 實體欄位定義(TypeScript 介面)

AuthState(前端認證狀態管理)

interface CompanyRegisterAuthState {
  isLoggedIn: boolean
  verified: boolean
  profileFilled: boolean
  companyCount: number
  authMode: 'register' | 'login'
  loginMethod: 'email' | 'google'
  otpSent: boolean
  otpVerified: boolean
}

MemberProfileForm(Step 2 會員基本資料)

interface MemberProfileForm {
  name: string                        // 姓名(必填)
  birthday: string                    // 生日(必填,YYYY-MM-DD)
  email: string                       // Email(必填,自動帶入,唯讀)
  phone: string                       // 手機號碼(必填)
  residence: string                   // 居住地址(必填)
  nationality: string                 // 國籍(必填)
  work_identity_type?: string         // 身份種類(條件必填:居住地=台灣 且 國籍≠台灣 時顯示)
}
  • 僅顯示必填欄位,非必填欄位完全不渲染
  • Email 自動帶入前面註冊/登入時使用的 email,設為唯讀
  • work_identity_type 為條件欄位:僅當 residence 為台灣且 nationality 不是台灣時才顯示並必填

CompanyRegisterForm

沿用既有 company-register 前端模組的表單介面,不另定義。


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

6.1 區塊列表

區塊 ID區塊名稱說明
SEC-1Step 指示器顯示目前步驟(1: 註冊驗證 / 2: 會員資料 / 3: 公司資料)
SEC-2Step 1:註冊/登入 + OTP沿用 MockMainSiteAuth + OTP 驗證碼流程
SEC-2.5Step 2:會員基本資料填寫僅顯示必填欄位,新註冊用戶專用
SEC-3Step 3:公司基本資料填寫沿用既有 company-register 表單模組
SEC-4公司上限提示達 10 間上限時顯示的錯誤提示
SEC-5已登入未驗證提示顯示「email 尚未驗證」+ 發送驗證碼按鈕

6.2 各區塊資料需求

SEC-2 Step 1:註冊/登入 + OTP

  • 組件MockMainSiteAuth(與校園活動完全相同)
  • 功能
    • 註冊/登入 Tab 切換
    • Email 註冊:email + 密碼 + 確認密碼 → 點擊註冊 → 發送 OTP → 輸入驗證碼
    • Email 登入:email + 密碼 → 點擊登入 → 若未驗證則發送 OTP → 輸入驗證碼
    • Google 註冊/登入:OAuth 完成即 verified
    • 「email 已註冊」提示:引導切換到登入
  • OTP 流程:與一般註冊/登入及校園活動共用(輸入驗證碼 → 驗證成功/失敗 → 重發倒數 → 重試直到成功)

SEC-2.5 Step 2:會員基本資料填寫

  • 組件:新建 mockup 表單(僅必填欄位)
  • 顯示條件profileFilled = false(新註冊用戶,個人資料尚未填寫);已登入且已有個人資料者跳過此步驟
  • 表單欄位(僅顯示必填,非必填完全不渲染):
#欄位類型備註
1姓名文字輸入必填
2生日日期選擇器必填
3Email文字輸入(唯讀)自動帶入註冊/登入時的 email
4手機號碼文字輸入必填
5居住地址下拉選擇必填
6國籍下拉選擇必填
7身份種類下拉選擇條件顯示:居住地=台灣 且 國籍≠台灣 時才出現並必填
  • 行為:填寫完成後點擊「下一步」→ 呼叫更新個人資料 API → 進入 Step 3

SEC-3 Step 3:公司基本資料填寫

  • 組件:沿用既有 company-register 前端模組
  • 行為:填寫完成後點擊下一步 → 呼叫建立公司 API → 導向公司頁面

SEC-4 公司上限提示

  • 觸發條件:登入/驗證完成後,查詢**本人為擁有者(owner)**的公司數量 >= 10(僅為成員的公司不計入)
  • 顯示:「您已達公司建立上限(以擁有者身份 10 間),無法再建立新公司。」
  • 操作:提供返回按鈕或導向公司管理頁面

SEC-5 已登入未驗證提示

  • 觸發條件:已登入但 verified = false
  • 顯示:「您的 email 尚未驗證」+ 「發送驗證碼」按鈕
  • 操作:使用者手動點擊按鈕後觸發發送 OTP,進入驗證碼輸入流程

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

動作 ID動作名稱類型需要後端涉及實體說明
ACT-1Email 註冊寫入✅ 是AuthState建立帳號 + 發送 OTP(與一般註冊/登入共用 OTP API)
ACT-2Email 登入查詢✅ 是AuthState驗證帳密 + 回傳 verified 狀態(與一般註冊/登入共用 OTP API)
ACT-3發送 OTP寫入✅ 是AuthState發送驗證碼到 email(與一般註冊/登入共用 OTP API)
ACT-4驗證 OTP寫入✅ 是AuthState驗證碼比對(與一般註冊/登入共用 OTP API)
ACT-5Google OAuth查詢✅ 是AuthState沿用既有 Google OAuth
ACT-6查詢擁有公司數量查詢✅ 是-登入/驗證後查詢該帳號以**擁有者(owner)**身份擁有的公司數量(被加入為成員的公司不計入)
ACT-6.5檢查個人資料是否已填寫查詢✅ 是AuthState判斷是否需要顯示 Step 2(profileFilled?)
ACT-7儲存會員基本資料寫入✅ 是MemberProfileFormStep 2 填寫完成後呼叫更新個人資料 API
ACT-8建立公司寫入✅ 是CompanyRegisterForm沿用既有建立公司 API

場景化動作描述

場景 A:完全新用戶 — Email 註冊

項目描述
進入條件未登入、無帳號
畫面呈現Step 1 顯示註冊/登入 Tab(預設註冊),填寫 email + 密碼 + 確認密碼
操作流程點「註冊」→ 帳號建立 + 發送 OTP → 輸入驗證碼 → 驗證成功 → 查公司數量 → Step 2 填寫會員資料 → Step 3 填寫公司資料 → 導向公司頁面
錯誤處理OTP 錯誤/過期 → 同校園活動(重發倒數、重試直到成功)

場景 B:完全新用戶 — Google 註冊

項目描述
進入條件未登入、無帳號
操作流程Google OAuth 完成 → 跳過 OTP → 查公司數量 → Step 2 填寫會員資料 → Step 3 填寫公司資料 → 導向公司頁面
錯誤處理Google 失敗/取消 → 提示重試或改用 Email

場景 C:有帳號未驗證 — 登入

項目描述
進入條件未登入、有帳號但 verified = false
操作流程登入 Tab → 輸入帳密 → 登入成功 → 發送 OTP → 驗證成功 → 查公司數量 → 檢查個人資料 → 若未填則 Step 2 → Step 3
錯誤處理帳密錯誤 → 錯誤提示;OTP 錯誤 → 同上

場景 D/E:有帳號已驗證 — 登入(個人資料已填寫)

項目描述
進入條件未登入、有帳號、verified = trueprofileFilled = true、公司數量 0~9
操作流程登入 → 不需 OTP → 查公司數量 → 跳過 Step 2 → 直接進入 Step 3

場景 D’/E’:有帳號已驗證 — 登入(個人資料未填寫)

項目描述
進入條件未登入、有帳號、verified = trueprofileFilled = false、公司數量 0~9
操作流程登入 → 不需 OTP → 查公司數量 → Step 2 填寫會員資料 → Step 3

場景 F:有帳號已驗證 — 已達公司上限

項目描述
進入條件登入完成、本人為擁有者的公司數量 = 10(僅為成員不計入)
操作流程登入後立刻顯示「已達公司建立上限(以擁有者身份 10 間)」,不進入後續步驟

場景 G:已登入已驗證直接進入(個人資料已填寫)

項目描述
進入條件已登入、verified = trueprofileFilled = true,直接訪問頁面 URL
操作流程跳過 Step 1 + Step 2 → 查公司數量 → 直接進入 Step 3

場景 G’:已登入已驗證直接進入(個人資料未填寫)

項目描述
進入條件已登入、verified = trueprofileFilled = false,直接訪問頁面 URL
操作流程跳過 Step 1 → 查公司數量 → Step 2 填寫會員資料 → Step 3

場景 H:已登入未驗證直接進入

項目描述
進入條件已登入、verified = false,直接訪問頁面 URL
操作流程顯示「email 尚未驗證」+ 發送驗證碼按鈕 → 使用者手動點擊 → 發送 OTP → 驗證成功 → 查公司數量 → 檢查個人資料 → 若未填則 Step 2 → Step 3

場景 I:註冊時 email 已存在

項目描述
進入條件在註冊 Tab 輸入了已註冊的 email
畫面呈現顯示「此 email 已有人註冊,請改用登入」+ 切換到登入 Tab 的按鈕

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

8.1 資料讀取需求(Read)

  • HINT-GET-1:查詢使用者以**擁有者(owner)**身份擁有的公司數量

    • 對應區塊:公司上限檢查
    • 時機:登入/驗證完成後立即查詢
    • 說明:僅計算該使用者為 owner 的公司,被加入為成員的公司不計入
    • 輸出:{ count: number }
  • HINT-GET-2:取得使用者驗證狀態與個人資料完成狀態

    • 對應區塊:Step 1 / 已登入進入時 / Step 2 判斷
    • 輸出:{ verified: boolean, profileFilled: boolean }

8.2 資料寫入需求(Write)

  • HINT-MUTATION-1:OTP 註冊(與一般註冊/登入及校園活動共用 API)

    • 輸入:{ email, password }
    • 行為:建立帳號 + 發送 OTP 至 email
    • 錯誤:email 已存在 → 回傳已註冊錯誤
  • HINT-MUTATION-2:OTP 登入(與一般註冊/登入及校園活動共用 API)

    • 輸入:{ email, password }
    • 行為:驗證帳密,若未驗證帳號則回傳 verified = false
  • HINT-MUTATION-3:發送 OTP(與一般註冊/登入及校園活動共用 API)

    • 輸入:{ email }
    • 行為:發送 OTP 驗證碼至 email
  • HINT-MUTATION-4:驗證 OTP(與一般註冊/登入及校園活動共用 API)

    • 輸入:{ email, otp_code }
    • 行為:比對驗證碼,成功則將帳號標記為 verified
  • HINT-MUTATION-5:儲存會員基本資料

    • 對應區塊:SEC-2.5(Step 2 會員資料)
    • 輸入:MemberProfileForm(姓名、生日、手機、居住地、國籍、身份種類)
    • 行為:更新使用者個人資料(沿用既有更新個人資料 API)
  • HINT-MUTATION-6:建立公司(沿用既有 API)

    • 輸入:公司基本資料(同既有 company-register)
    • 行為:建立公司頁面,建立者成為 Owner

9. 導航 / Storybook Map

  • Storybook 標題Mockups/Company/CompanyQuickRegister
  • Stories 路徑storybook/src/stories/mockups/company/CompanyQuickRegister.stories.ts
  • Storybook 連結CompanyQuickRegister
  • 情境控制
    • initialLoggedIn:是否已登入
    • initialVerified:是否已驗證
    • initialProfileFilled:個人資料是否已填寫(控制是否顯示 Step 2)
    • initialCompanyCount:目前公司數量(0~10)
    • initialAuthVariantemail_register / google_done / login_otp_pending
    • registerResultsend_otp / already_registered
  • 對應 production 路由/company-register(既有路徑)
  • 入口來源:job-posting 頁面「免費建立公司」按鈕

10. Flowcharts(User / System / Navigation)

10.1 User Flow(使用者操作流程)

flowchart TD
    Start[使用者進入公司註冊頁面] --> AuthCheck{已登入?}

    AuthCheck -->|是| VerifiedCheck{已驗證 email?}
    AuthCheck -->|否| Step1[Step 1:顯示註冊/登入畫面]

    Step1 --> AuthTab{註冊 or 登入?}

    %% === 註冊路線 ===
    AuthTab -->|註冊| RegMethod{Email 註冊 or Google 註冊?}
    RegMethod -->|Email 註冊| RegEmail[輸入 email、密碼、確認密碼]
    RegEmail --> RegSubmit[點擊「註冊」]
    RegSubmit --> RegCheck{此 email 已註冊?}
    RegCheck -->|是| ErrReg[顯示「此 email 已有人註冊,請改用登入」]
    ErrReg --> AuthTab
    RegCheck -->|否| RegOtp[帳號建立 + 發送 OTP 至 Email]
    RegOtp --> InputOtp

    RegMethod -->|Google 註冊| RegGoogle[Google OAuth]
    RegGoogle --> GoogleResult{Google 成功?}
    GoogleResult -->|否| GoogleFail[提示重試或改用 Email]
    GoogleFail --> RegMethod
    GoogleResult -->|是| VerifiedGoogle[verified = true]
    VerifiedGoogle --> CompanyLimitCheck

    %% === 登入路線 ===
    AuthTab -->|登入| LoginMethod{一般登入 or Google 登入?}
    LoginMethod -->|一般登入| LoginEmail[輸入 email、密碼]
    LoginEmail --> LoginSubmit[點擊「登入」]
    LoginSubmit --> LoginResult{登入成功?}
    LoginResult -->|否| LoginFail[顯示帳密錯誤]
    LoginFail --> LoginEmail
    LoginResult -->|是| LoginVerifiedCheck{帳號已 verified?}
    LoginVerifiedCheck -->|是| CompanyLimitCheck
    LoginVerifiedCheck -->|否| LoginOtp[發送 OTP]
    LoginOtp --> InputOtp

    LoginMethod -->|Google 登入| LoginGoogle[Google OAuth]
    LoginGoogle --> GoogleLoginResult{Google 成功?}
    GoogleLoginResult -->|否| GoogleLoginFail[提示重試或改用 Email]
    GoogleLoginFail --> LoginMethod
    GoogleLoginResult -->|是| VerifiedGoogleLogin[verified = true]
    VerifiedGoogleLogin --> CompanyLimitCheck

    %% === 共用 OTP 驗證碼流程 ===
    subgraph OtpFlow [共用 OTP 驗證碼流程]
        InputOtp[輸入驗證碼]
        OtpCheck{驗證成功?}
        OtpFail[顯示錯誤或過期]
        WaitOtp[等待可重發倒數]
        ResendOtp[重新發送驗證碼]
        InputOtp --> OtpCheck
        OtpCheck -->|是| VerifiedOtp[verified = true]
        OtpCheck -->|否| OtpFail
        OtpFail --> WaitOtp
        WaitOtp --> ResendOtp
        ResendOtp --> InputOtp
    end

    VerifiedOtp --> CompanyLimitCheck

    %% === 已登入進入的路線 ===
    VerifiedCheck -->|是| CompanyLimitCheck
    VerifiedCheck -->|否| ShowOtpTrigger[顯示「您的 email 尚未驗證」<br>+ 發送驗證碼按鈕]
    ShowOtpTrigger --> TriggerOtp[使用者點擊發送驗證碼]
    TriggerOtp --> InputOtp

    %% === 公司上限檢查(僅計本人為 owner 的公司)===
    CompanyLimitCheck{本人為擁有者的公司數 < 10?}
    CompanyLimitCheck -->|否| LimitError[顯示「已達公司建立上限(以擁有者身份 10 間)」]
    CompanyLimitCheck -->|是| ProfileCheck{個人資料已填寫?}

    %% === 會員資料檢查 ===
    ProfileCheck -->|是| Step3[Step 3:公司基本資料填寫<br>(沿用既有 company-register 模組)]
    ProfileCheck -->|否| Step2[Step 2:會員基本資料填寫<br>(僅顯示必填欄位)]
    Step2 --> Step2Submit[填寫完成,點擊下一步]
    Step2Submit --> Step2Save[儲存個人資料]
    Step2Save --> Step3

    Step3 --> CompanySubmit[填寫完成,點擊下一步]
    CompanySubmit --> CompanyPage[導向公司頁面<br>(進入既有後續流程)]

10.2 System Flow(前端狀態與 API 互動)

sequenceDiagram
    participant U as 使用者
    participant FE as 前端
    participant API as 後端 API

    U->>FE: 進入公司註冊頁面
    FE->>FE: 檢查 auth state(已登入?)

    alt 已登入 + 已驗證
        FE->>API: GET 查詢擁有公司數量(owner)+ 個人資料狀態
        API-->>FE: { count: N, profileFilled: bool }
        alt N >= 10(僅計 owner)
            FE->>U: 顯示「已達上限」
        else profileFilled = true
            FE->>U: 跳過 Step 2,直接顯示 Step 3(公司資料填寫)
        else profileFilled = false
            FE->>U: 顯示 Step 2(會員基本資料填寫)
            U->>FE: 填寫會員資料並點擊下一步
            FE->>API: POST 儲存個人資料
            API-->>FE: 儲存成功
            FE->>U: 顯示 Step 3(公司資料填寫)
        end
    else 已登入 + 未驗證
        FE->>U: 顯示「email 尚未驗證」+ 發送驗證碼按鈕
        U->>FE: 點擊發送驗證碼
        FE->>API: POST 發送 OTP(與一般註冊/登入共用 API)
        API-->>FE: OTP 已發送
        U->>FE: 輸入驗證碼
        FE->>API: POST 驗證 OTP
        API-->>FE: 驗證成功
        FE->>API: GET 查詢擁有公司數量(owner)+ 個人資料狀態
        API-->>FE: { count: N, profileFilled: bool }
        FE->>U: 依 profileFilled 顯示 Step 2 或 Step 3
    else 未登入
        FE->>U: 顯示 Step 1(註冊/登入)

        alt Email 註冊
            U->>FE: 填寫 email + 密碼 + 確認密碼
            U->>FE: 點擊「註冊」
            FE->>API: POST OTP 註冊(與一般註冊/登入共用 API)
            alt email 已存在
                API-->>FE: 已註冊錯誤
                FE->>U: 「此 email 已有人註冊,請改用登入」
            else 成功
                API-->>FE: 帳號建立 + OTP 已發送
                U->>FE: 輸入驗證碼
                FE->>API: POST 驗證 OTP
                API-->>FE: 驗證成功
            end
        else Email 登入
            U->>FE: 填寫 email + 密碼
            U->>FE: 點擊「登入」
            FE->>API: POST OTP 登入(與一般註冊/登入共用 API)
            API-->>FE: 登入成功 + verified 狀態
            alt 未驗證
                FE->>API: POST 發送 OTP
                U->>FE: 輸入驗證碼
                FE->>API: POST 驗證 OTP
            end
        else Google 登入/註冊
            U->>FE: 點擊 Google 按鈕
            FE->>API: Google OAuth
            API-->>FE: 登入成功(verified = true)
        end

        FE->>API: GET 查詢擁有公司數量(owner)+ 個人資料狀態
        API-->>FE: { count: N, profileFilled: bool }
        alt N >= 10(僅計 owner)
            FE->>U: 顯示「已達上限」
        else profileFilled = false
            FE->>U: 顯示 Step 2(會員資料)
            U->>FE: 填寫會員資料並點擊下一步
            FE->>API: POST 儲存個人資料
            API-->>FE: 儲存成功
            FE->>U: 顯示 Step 3(公司資料)
        else profileFilled = true
            FE->>U: 跳過 Step 2,顯示 Step 3
        end
    end

    U->>FE: 填寫公司基本資料
    U->>FE: 點擊「下一步」
    FE->>API: POST 建立公司(沿用既有 API)
    API-->>FE: 公司建立成功
    FE->>U: 導向公司頁面

11. Mock Data Schema(Mock 資料結構)

  • 資料來源:僅 mock,不呼叫真實 API
  • CRUD 行為:mock 內所有新增/修改/刪除僅存在元件狀態,重新整理後還原
  • 情境切換
    • initialLoggedIn:控制已登入/未登入狀態
    • initialVerified:控制已驗證/未驗證狀態
    • initialProfileFilled:控制個人資料是否已填寫(影響是否顯示 Step 2)
    • initialCompanyCount:控制公司數量(影響上限檢查)
    • initialAuthVariant:控制 Step 1 的初始變體(email_register / google_done / login_otp_pending)
    • registerResult:控制註冊結果(send_otp / already_registered)

12. 實作備註(Implementation Notes)

  • 禁止事項
    • ❌ 本文件不直接定義最終 API path/method,僅提供 Hints
    • ❌ 不直接修改 prd/business-rules.md,新規則先在「商業規則對齊」描述,再由人決定是否回寫
  • 注意事項
    • 欄位命名與 Storybook/TS interface 一致
    • Step 1 完全複用校園活動的 MockMainSiteAuth + OTP 流程,不另建新組件
    • Step 2 會員資料表單僅顯示必填欄位(姓名、生日、Email(唯讀)、手機、居住地、國籍、身份種類(條件顯示)),非必填欄位完全不渲染
    • Step 2 的 Email 欄位自動帶入註冊/登入時的 email,設為唯讀
    • Step 2 的身份種類欄位僅在「居住地=台灣 且 國籍≠台灣」時顯示
    • 已登入且個人資料已填寫(profileFilled = true)的使用者跳過 Step 2
    • Step 3 完全複用既有 company-register 前端模組,以子組件形式嵌入同一頁面
    • OTP API 與一般網站註冊/登入共用同一套端點(校園活動亦沿用;語意上作為「通用 OTP 認證模組」使用)
    • 前端使用單一頁面內的 state 切換 Step 1 / Step 2,不改路由結構
    • 公司上限檢查以本人為 owner 的公司數量為準(被加入為成員不計入),在登入/驗證完成後立刻執行,不等到填完公司資料才報錯

架構決策記錄

決策項目選擇理由
OTP API 端點與一般註冊/登入及校園活動共用同一套 OTP 用於全站註冊/登入與本流程,KISS,未來可統一重命名
已登入未驗證 OTP 觸發方式手動觸發(使用者點按鈕)避免使用者還沒準備好就收到驗證碼
公司上限檢查時機登入/驗證後立刻檢查避免白填公司資料
前端路由單一頁面 state 切換不改既有路由結構,體驗最連貫
Step 2 會員資料顯示條件依 profileFilled 判斷已有個人資料的使用者不需重複填寫
Step 2 非必填欄位完全不渲染保持表單精簡,減少填寫壓力
Step 1→2→3 銜接同一頁面內依序嵌入各步驟組件使用者始終在同一畫面,減少跳轉

入口與狀態約束表

入口狀態verifiedprofileFilled公司數量預期行為
未登入 → 註冊(Email)false → OTP 後 truefalse0註冊 → OTP → Step 2(會員資料) → Step 3
未登入 → 註冊(Google)true(免 OTP)false0Google OAuth → Step 2(會員資料) → Step 3
未登入 → 登入(未驗證)false → OTP 後 true視情況N/A登入 → OTP → 檢查上限 → 依 profileFilled 決定
未登入 → 登入(已驗證、資料已填)truetrue0~9登入 → 檢查上限 → 跳過 Step 2 → Step 3
未登入 → 登入(已驗證、資料未填)truefalse0~9登入 → 檢查上限 → Step 2 → Step 3
未登入 → 登入(已驗證,owner 數=10)trueN/A10登入 → 顯示上限提示(僅計 owner)
未登入 → 登入(Google)true視情況N/AGoogle OAuth → 檢查上限 → 依 profileFilled 決定
已登入 + 已驗證 + 資料已填truetrue0~9跳過 Step 1 + 2 → 直接 Step 3
已登入 + 已驗證 + 資料未填truefalse0~9跳過 Step 1 → Step 2 → Step 3
已登入 + 已驗證(owner 數=10)trueN/A10顯示上限提示(僅計 owner)
已登入 + 未驗證falseN/AN/A顯示驗證提示 → 手動 OTP → 檢查上限 → 依 profileFilled 決定

OTP 驗證碼錯誤與重發規則

沿用校園活動(recruitment-campaign-mockup.md §8.1.1)的完整規則:

失敗情境處理
驗證碼輸入錯誤顯示「驗證碼錯誤,請重新輸入」;不消耗重發次數
驗證碼已過期顯示「驗證碼已過期,請重新取得」;需點重新發送
重發等待時間60 秒倒數後才可再次發送
直到成功為止重複直到驗證成功,通過後進入下一階段

新業務規則建議

  • 建議新增 BR-NEW:每個帳號以**擁有者(owner)**身份最多建立 10 間公司(僅計算本人為 owner 的公司;被加入為成員的公司不計入)。達上限時顯示提示並阻止建立。建議回寫至 business-rules.md

13. 下一步(Next Steps)

  • 使用 storybook-mockup-gen skill 產出 Storybook mockup
  • 產出後將 Storybook 連結回填至本 PRD §1 及 Trello 卡片
  • 與後端確認 OTP API 與一般註冊/登入共用之端點
  • 將 BR-NEW(每帳號以 owner 身份最多 10 間公司,僅為成員不計入)回寫至 business-rules.md

更新記錄

  • 2026-03-16:v1.2.0 — OTP 與一般註冊共用;公司上限僅計 owner
    • 明確 OTP 驗證流程與一般網站註冊/登入共用同一套機制與 API,非僅限本流程或校園活動
    • 公司建立上限改為僅計算**本人為擁有者(owner)**的公司;被加入為成員的公司不計入,達 10 間(owner)才禁止建立新公司
  • 2026-03-13:v1.1.0 — 新增 Step 2 會員基本資料
    • 在 Step 1(註冊/驗證)與 Step 3(公司資料)之間新增 Step 2「會員基本資料」
    • 僅顯示必填欄位(姓名、生日、Email(唯讀)、手機、居住地、國籍、身份種類(條件顯示))
    • 非必填欄位完全不渲染
    • 已登入且個人資料已填寫的使用者跳過 Step 2
    • 新增 profileFilled 狀態判斷與 MemberProfileForm 實體
    • 更新所有場景(A~I)與流程圖
    • 從排除範圍中移除「不做個人基本資料填寫」
    • 新增 BR-002 至商業規則對齊
  • 2026-03-04:初版 PRD
    • 公司快速註冊功能:將使用者註冊 + email OTP 驗證 + 公司建立串成一條連貫流程
    • Step 1 沿用校園活動的 MockMainSiteAuth + OTP 模組
    • Step 2 沿用既有 company-register 前端模組
    • 新增公司建立上限:每帳號最多 10 間
    • 完整場景列舉(A~I)含邊界情境
    • 架構決策記錄:OTP API 沿用、手動觸發驗證、單一頁面 state 切換

文件結束