履歷 AI 複製 Mockup PRD(給後端 API 規格產生器使用)
此文件描述「履歷 AI 複製」在既有
my-resume/edit-resume頁面的增量需求,供前後端、產品、QA 對齊。
1. 文件資訊
- 文件類型:Mockup 需求規格書(前後端共用視圖)
- 適用對象:前端開發、後端開發、產品、QA
- 最後更新:2026/04/15
- 版本:1.0.0
- 對應 Storybook:
TBD(尚未建立對應 story) - Storybook 連結:
TBD - 建立日期:2026/04/15
2. 開發進度與設計來源
開發進度
- 前端 PR #:TBD
- 後端 PR #:TBD
設計來源
- Figma 連結:待補上
- 既有畫面來源(增量基準):
W101-Web/main-web/packages/user/src/views/my-resume/Index.vueW101-Web/main-web/packages/user/src/views/my-resume/edit-resume/index.vueW101-Web/main-web/packages/user/src/router/index.ts
3. 模擬頁面摘要(Mockup Summary)
3.1 功能概述
- 功能名稱:履歷 AI 複製
- 主要使用者角色:求職者(在台僑外生 / 外籍求職者)
- 核心目標:
- 降低求職者從既有履歷搬移到 Wport 的成本,將「貼上文字 / 上傳 PDF(轉 md)/ prompt」轉為可編輯履歷草稿,並一鍵保存。
3.2 範圍界定
- 包含範圍:
- 採用三層處理架構:Parsing -> Processing -> UI/UX Filling。
- 在
my-resume新增「AI 複製建立履歷」入口(沿用新增履歷上限與資格限制)。 - 支援輸入來源:
- plain text 直接貼上。
- PDF 上傳後先轉 md,再由 AI 轉結構化 JSON(非 OCR 深度辨識)。
- prompt 輸入。
- AI 解析後提供欄位映射預覽,使用者可編輯後再保存到既有履歷模型。
- 解析失敗時保留原文,允許在 1 小時內重試。
- 生成流程不覆蓋既有履歷資料,僅建立新草稿/新履歷。
- 排除範圍:
- 不做 OCR 深度辨識與掃描品質修復。
- 不做專業翻譯/潤稿服務。
- 不做與第三方履歷平台雙向同步。
3.3 成功條件
- 使用者可在單次流程內完成:輸入內容 -> AI 生成草稿 -> 編輯 -> 保存。
- 解析後欄位可成功儲存並顯示於既有履歷頁。
- 失敗時顯示明確提示且保留原文,不覆蓋既有履歷。
- 上線後可追蹤「AI 生成履歷使用率」。
4. 商業規則對齊(Business Rules Alignment)
4.1 本功能使用到的業務規則
| 規則 ID | 規則摘要 | 是否關鍵 | 備註 |
|---|---|---|---|
| BR-002 | 信箱驗證後仍需完成個人資料才能新增履歷 | ✅ 是 | AI 複製建立履歷仍屬新增履歷入口 |
| BR-010 | 履歷建立條件與數量上限 | ✅ 是 | 本功能沿用每人最多 6 份履歷上限 |
| BR-017 | 使用者只能編輯自己的履歷 | ✅ 是 | AI 生成結果僅能保存到本人履歷 |
4.2 補充說明
- 「PDF -> md -> JSON」屬於 AI 解析流程,與「OCR 深度辨識」不同,並不違反本功能 out-of-scope。
- 若使用者已達 6 份履歷上限,AI 複製入口顯示禁用與提示文案,不可建立新履歷。
5. 資料實體與欄位(Data Entities & Fields)
5.1 實體列表
| 實體名稱 | 說明 | 來源頁面/區塊 |
|---|---|---|
| ResumeAiDraftInput | 使用者提供給 AI 的原始內容與來源資訊 | my-resume / AI 複製 modal |
| ResumeAiParseJob | 一次 AI 解析任務與狀態 | my-resume / 解析流程狀態 |
| ResumeAiParsedResume | AI 輸出的履歷結構化結果 | edit-resume / 預填草稿 |
| ResumeCreateResult | 建立履歷後回傳結果 | my-resume / 列表更新 |
5.2 實體欄位定義(TypeScript 介面)
ResumeAiDraftInput
interface ResumeAiDraftInput {
source_type: 'plain_text' | 'pdf_to_md' | 'prompt';
raw_content: string;
raw_file_url?: string;
locale?: 'zh-TW' | 'en';
}
ResumeAiParseJob
interface ResumeAiParseJob {
parse_job_id: string;
user_id: string;
status: 'draft' | 'parsing' | 'parsed' | 'user_edited' | 'saved' | 'failed' | 'expired';
started_at: string;
completed_at?: string;
retry_window_ends_at: string; // started_at + 1 hour
error_code?: string;
error_message?: string;
}
ResumeAiParsedResume
interface ResumeAiParsedResume {
parse_job_id: string;
resume_name: string;
personal_background?: Record<string, unknown>;
education?: Array<Record<string, unknown>>;
work_experience?: Array<Record<string, unknown>>;
professional_skill?: Array<Record<string, unknown>>;
languages?: Array<Record<string, unknown>>;
certificates?: Array<Record<string, unknown>>;
portfolio_links?: Array<Record<string, unknown>>;
autobiography?: string;
confidence_score?: number;
warnings?: string[];
}
6. 畫面區塊與資料需求(UI Sections & Data Needs)
6.1 區塊列表
| 區塊 ID | 區塊名稱 | 說明 |
|---|---|---|
| SEC-1 | my-resume AI 複製入口 | 新增按鈕與上限/資格提示 |
| SEC-2 | AI 輸入區 | text / pdf / prompt 輸入 |
| SEC-3 | 解析中與結果預覽區 | 顯示狀態、錯誤、重試、映射結果 |
| SEC-4 | edit-resume 編輯區(沿用) | 解析完成後進入既有編輯頁補修 |
6.2 各區塊資料需求
SEC-1 my-resume AI 複製入口
- 顯示實體:
resumeList,extra.max_resumes_quota,user profile complete state - 資料需求:沿用既有履歷列表 API。
- 約束:
- 已達 6 份履歷:禁用入口並顯示提示。
- 未完成個人資料或信箱驗證:禁用入口並引導至
edit-member。
SEC-2 AI 輸入區
- 顯示實體:
ResumeAiDraftInput - 資料需求:輸入內容長度檢查、PDF 轉 md 前置處理。
- 是否即時打 API:否(按下「開始解析」才送出)。
SEC-3 解析中與結果預覽區
- 顯示實體:
ResumeAiParseJob,ResumeAiParsedResume - 資料需求:輪詢或 webhook 更新
status。 - 錯誤處理:
failed:顯示錯誤訊息,保留輸入內容。- 1 小時內可重試,超過 1 小時狀態改
expired,需重新建立 parse job。
SEC-4 edit-resume 編輯區(沿用)
- 顯示實體:既有履歷 sections + AI 帶入欄位
- 資料需求:將 parsed payload 映射到既有
ResumeSections模型,使用者可修改後保存。
7. 使用者動作與後端需求(User Actions & Backend Needs)
| 動作 ID | 動作名稱 | 類型 | 需要後端 | 涉及實體 | 說明 |
|---|---|---|---|---|---|
| ACT-1 | 開啟 AI 複製入口 | UI | ❌ 否 | - | 僅前端顯示與資格檢查 |
| ACT-2 | 提交輸入給 AI 解析 | 寫入(Write) | ✅ 是 | ResumeAiDraftInput, ResumeAiParseJob | 建立 parse job |
| ACT-3 | 查詢解析狀態 | 查詢(Read) | ✅ 是 | ResumeAiParseJob | 解析中輪詢 |
| ACT-4 | 取得解析結果 | 查詢(Read) | ✅ 是 | ResumeAiParsedResume | 取回可編輯草稿 |
| ACT-5 | 1 小時內重試解析 | 寫入(Write) | ✅ 是 | ResumeAiParseJob | 沿用原輸入重跑 |
| ACT-6 | 保存為新履歷 | 寫入(Write) | ✅ 是 | ResumeCreateResult | 建立新履歷,不覆蓋既有 |
7.1 場景細節(複數場景逐一描述)
- 已登入 + 條件完整 + 未達上限
- 可使用 AI 複製,完成後建立新履歷並跳轉
edit-resume/:resumeId。
- 可使用 AI 複製,完成後建立新履歷並跳轉
- 已登入 + 未完成個人資料/未驗證信箱
- AI 複製入口禁用,提示先完成會員資料,導向
edit-member。
- AI 複製入口禁用,提示先完成會員資料,導向
- 已登入 + 已達 6 份上限
- 禁用 AI 複製與新增履歷,提示刪除後再建立。
- 未登入
- 無法進入
my-resume/edit-resume(沿用 login guard)。
- 無法進入
- 解析失敗(服務錯誤/格式不符)
- 顯示失敗原因、保留原文、提供重試;重試窗口 1 小時。
- 解析結果部分欄位缺漏
- 可進入 edit-resume 由使用者補齊,未補齊欄位遵循既有必填限制。
7.2 入口與狀態約束
| 入口 | 狀態欄位 | 約束 | 預期行為 |
|---|---|---|---|
/my-resume | profile_complete | 必為 true | 才可啟用 AI 複製按鈕 |
/my-resume | resume_count | 必 < 6 | 否則禁用並提示上限 |
| AI parse job | status=failed | within 1 hour | 可重試並保留原文 |
| AI parse job | status=failed | over 1 hour | 狀態轉 expired,需重建任務 |
/edit-resume/:resumeId | parsed payload | 可為部分缺漏 | 允許人工補齊後保存 |
8. API Hints(提示用,非最終 API 設計)
8.1 資料讀取需求(Read)
-
HINT-GET-1:取得 AI parse job 狀態
- 對應區塊:SEC-3
- 輸入:
{ parse_job_id }
-
HINT-GET-2:取得 parse 結果 payload
- 對應區塊:SEC-3 / SEC-4
- 輸入:
{ parse_job_id }
8.2 資料寫入需求(Write)
-
HINT-MUTATION-1:建立 AI parse job
- 輸入:
{ source_type, raw_content | raw_file_url, locale } - 行為:建立解析任務並回傳
parse_job_id;若source_type=pdf_to_md,先執行 PDF->MD 再進入 LLM。
- 輸入:
-
HINT-MUTATION-2:重試 parse job
- 輸入:
{ parse_job_id } - 行為:僅在 1 小時窗口內可重試
- 輸入:
-
HINT-MUTATION-3:以解析結果建立新履歷
- 輸入:
{ parse_job_id, mapped_resume_payload } - 行為:建立新履歷並回傳
encResumeId
- 輸入:
9. 導航 / Storybook Map
- Storybook 標題:
Mockups/Resume/ResumeAiCopy - Stories 路徑:
storybook/src/stories/mockups/resume/ResumeAiCopy.stories.ts(待建立) - Storybook 連結:
TBD - 對應 production 路由:
/my-resume/edit-resume/:resumeId
10. Flowcharts(User / System / Navigation)
10.1 User Flow(使用者操作流程)
flowchart TD
A[進入 my-resume] --> B{已完成會員資料且履歷數<6?}
B -->|否| C[顯示限制提示並引導]
B -->|是| D[開啟 AI 複製輸入]
D --> E[貼文字 / 上傳PDF轉md / 輸入prompt]
E --> F[送出 AI 解析]
F --> G{解析成功?}
G -->|否| H[顯示錯誤 + 保留原文]
H --> I{1小時內?}
I -->|是| F
I -->|否| J[任務過期 需重建]
G -->|是| K[顯示可編輯草稿]
K --> L[進入 edit-resume 補修]
L --> M[保存為新履歷]
10.2 System Flow(前端狀態與資料流)
sequenceDiagram
participant U as User
participant FE as Frontend
participant BE as Backend API
participant AI as LLM Provider
U->>FE: 開啟 AI 複製並送出輸入
FE->>BE: 建立 parse job
BE->>AI: 解析履歷內容
AI-->>BE: 回傳結構化結果(JSON)
BE-->>FE: job status = parsed / failed
alt parsed
FE->>BE: 取得 parsed payload
BE-->>FE: 履歷草稿資料
U->>FE: 編輯後按保存
FE->>BE: 建立新履歷
BE-->>FE: encResumeId
else failed
FE-->>U: 顯示錯誤並保留原文
U->>FE: 1 小時內重試
FE->>BE: retry parse job
end
10.3 Navigation / Story Flow
flowchart LR
N1[/my-resume/] --> N2[AI 複製輸入與解析]
N2 --> N3[/edit-resume/:resumeId/]
N3 --> N4[保存後返回 my-resume 列表]
11. Mock Data Schema(Mock 資料結構)
- 資料來源:以 mock provider 回傳 parse job 與 parsed payload,不呼叫真實模型。
- CRUD 行為:
- parse job 狀態在 Storybook 以 controls 切換:
parsing / parsed / failed / expired。 - 建立與編輯行為僅存在元件狀態,重新整理後還原。
- parse job 狀態在 Storybook 以 controls 切換:
- 情境切換:
scenario=success:可順利帶入 edit-resume。scenario=partial:部分欄位缺漏。scenario=failed_retryable:失敗但在 1 小時內。scenario=failed_expired:失敗超過 1 小時。
12. 實作備註(Implementation Notes)
-
三層技術建議(新增):
- 解析層(Parsing)
- Input:使用者上傳 PDF 或貼上純文字。
- Action:
- 若為 PDF,建議優先使用開源工具將內容轉為 Markdown(推薦
Marker或PyMuPDF),保留段落/標題結構。 - 若為 plain text,直接進入下一層。
- 若為 PDF,建議優先使用開源工具將內容轉為 Markdown(推薦
- 目的:降低 PDF 原始噪訊、保留語意結構,並降低後續 LLM token 消耗。
- 轉換層(Processing)
- Input:Markdown 內容 + Wport 官方標準 JSON Schema(履歷欄位規範)。
- Action:呼叫 LLM,要求「嚴格依 Schema 輸出 JSON」;若欄位缺漏則輸出
null或空陣列,不可輸出 Schema 外欄位。 - 目的:將非結構化語意轉為可落庫資料,提升格式一致性與可驗證性。
- 呈現層(UI/UX Filling)
- Input:Processing 產出的 JSON。
- Action:前端根據欄位映射規則自動 pre-fill 對應 input 元件,使用者僅需補齊缺漏後儲存。
- 目的:提供「快速填入」體驗,縮短建立履歷時間。
- 解析層(Parsing)
-
模型供應商策略(成本/品質):
- 預設建議使用 Gemini 2.5 Flash 做第一層履歷結構化(通常 token 成本與延遲較低)。
- 若解析信心分數低或欄位缺漏高,再 fallback 到 Claude Sonnet 做第二層修復。
- OpenAI 可作為第三層備援或 A/B 評測。
- 所有供應商需統一輸出 schema,避免前端映射分岔。
-
Schema 驗證要求(新增):
- LLM 回傳 JSON 後,後端需做一次 schema validator 驗證;不通過則標記
failed並回傳可重試原因。 - 目標是「格式 100% 可驗證正確」,不是「內容 100% 無需人工修正」;仍保留使用者最終編輯權。
- LLM 回傳 JSON 後,後端需做一次 schema validator 驗證;不通過則標記
-
非功能需求:
- 單次解析請求應記錄
provider,token_usage,latency_ms,status。 - 必須可追蹤「AI 生成履歷使用率」與解析成功率。
- 單次解析請求應記錄
-
禁止事項:
- 不可直接覆蓋使用者既有履歷資料。
- 不可繞過 BR-002 / BR-010 的入口限制。
13. 下一步(Next Steps)
- 與後端確認 parse job 的最終資料表與 API 契約。
- 補齊 Storybook mockup 與故事連結,回填本 PRD 第 1、9 節。
- 定義 AI 生成履歷使用率的儀表板口徑(分母/分子)。
- 規劃 QA 測試矩陣(來源型別、上限、失敗重試、過期場景)。
文件結束