◆ wport | pm_42

應徵紀錄(My Applications)Mockup PRD(給後端 API 規格產生器使用)

應徵紀錄(My Applications)

來源 doc/feature/pm_42/application-records-prd.md

應徵紀錄(My Applications)Mockup PRD(給後端 API 規格產生器使用)

此範本專門給 gen-storybook-mockup-gen 產出的 mockup PRD 使用。 backend-api-spec-generator 會讀取這份文件與 Storybook mockups 來產生後端 API 規格。 產出 persona:CEO with PM Background(SaaS / HR tech lens)。


1. 文件資訊

  • 文件類型:Mockup 需求規格書(前後端共用視圖)
  • 適用對象:前端開發、後端開發、產品、QA
  • 最後更新:2026/07/16
  • 版本:1.3.0
  • 變更摘要(v1.3.0):納入求職信 deep link(跳轉 /user/message-notification?room=);新增 §2.1 實作狀態、§12.5 Delta 增量清單;站內信完整整合仍 out / v1.1+
  • 對應 Storybookstorybook/src/stories/mockups/user/ApplicationRecords.stories.ts(已產出)
  • Storybook 連結https://storybook.wport.me/?path=/docs/mockups-user-applicationrecords—docs
  • 建立日期:2026/06/23
  • Coda backlog應徵紀錄
  • AI / codegen 指引:本文件為累積規格。v1.0–v1.2 已上線(§2.1);僅實作 §12.5 v1.3 Delta。勿重產 v1 既有 API;HINT-GET-1 僅擴充 enc_room_idapplication_message 欄位。

2. 開發進度與設計來源

開發進度

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

設計來源

  • Figma 連結:[待補上]
  • Pixsole / 既有畫面:求職者既有「會員中心」C 端框架(沿用 user app 樣式 profile;見實作備註)

2.1 實作狀態(2026/07/16)

版本狀態說明
v1.0–v1.2✅ 已上線清單、冷卻倒數、終態灰階、再次應徵、求職信靜態顯示
v1.3🔲 待做求職信 deep link 跳轉(§9.1、§12.5)
v1.1📋 backlog卡片最新訊息摘要(靜態 API,非即時)
v2📋 backlog狀態 tab、badge、完整時間軸、pm_44

閱讀指引:v1 已交付部分勿重複實作。AI、RD、FE 請以 §12.5 v1.3 增量清單 為工作範圍;完整語意規格仍見各章,但 codegen 僅產出 Delta。


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

3.1 功能概述

  • 功能名稱:應徵紀錄(My Applications)
  • 主要使用者角色:Job Seeker(求職者,含僑外生 / 外籍)
  • 核心目標
    • 讓求職者在單一頁面掌握「我投過哪些職缺、能不能再投、下次可投時間」。
    • 降低投遞後焦慮與重複投遞無效操作,提升投遞後 7 日回訪與再次應徵品質。
    • BR-011 的 72 小時再投冷卻一致地呈現「下次可投時間」。

3.2 範圍界定

  • 包含範圍(v1.0–v1.2,已上線)
    • 應徵清單(同職缺多次合併一列;顯示公司、職缺、最近應徵日已投 N 次)。
    • 「再次應徵」按鈕(冷卻中 disabled 並倒數;見 BR-011)。
    • 職缺已關閉 / 已刪除:卡片灰階、職缺連結停用、顯示「此職缺已關閉」boundary(見 BR-009)。
    • 求職信區塊靜態顯示application_message 摘要;不含點擊跳轉)。
  • 包含範圍(v1.3 增量,待做)
    • 求職信區塊可點擊,deep link 跳轉至訊息通知頁並開啟對應對話(§9.1、§12.5)。
  • 排除範圍(v1 不做,Storybook 可展示完整願景)
    • 狀態 badge 與狀態篩選 tab(全部 / 審閱中 / 面試邀約 / 婉拒)→ v2(待 HR 流程)。
    • 面試邀約 / 婉拒狀態(HR 端流程尚未實作)→ v2
    • pm_44 封鎖公司互動(再投隱藏 / is_blocked_by_me)→ v2(pm_44 上線後)。
    • 完整多次應徵時間軸(逐次列出)→ v2;v1 僅顯示最近應徵日與 apply_count
    • 站內信完整整合(頁內嵌對話、未讀即時、最新訊息摘要)→ v1.1+ / 另案;v1.3 僅求職信入口 deep link 跳轉(§9.1)。
    • 卡片顯示「最新一則訊息 + 發送者」→ v1.1(靜態 API 摘要,非 WebSocket 即時)。
    • 應徵附加問卷的填寫流程(Coda:投遞附加問卷,另案)。
    • 履歷編輯(另案 edit-resume)。

3.3 成功條件

  • 求職者能在 1 頁看到全部應徵紀錄,且冷卻中職缺明確顯示「下次可投時間」。
  • 已關閉 / 已刪除職缺以灰階呈現,不會破圖或死連結,顯示「此職缺已關閉」。
  • 應徵後 7 日回訪率、再次應徵轉換率可被埋點量測。

前因(Why now)

  • 應徵紀錄卡片右側顯示求職信application_message 靜態快照),使用者投遞後常需繼續與 HR 對話,但目前無法從此入口一鍵進入對話。
  • 訊息通知頁(/user/message-notification)已有 chat 模組與 GET /api/chat/rooms;後端 job_applications.chat_room_id 與 chat list 的 enc_room_id同一 id(一求職者 × 一職缺 = 一 room)。
  • pm-32 email/push deep link 已確立「以 enc_room_id 開啟對話」模式;應徵紀錄頁需對齊同一契約,避免各頁各做一套。

後果(What changes)

  • v1.3 納入:求職信區塊可點擊 → 跳轉 /user/message-notification?room={enc_room_id}
  • v1.3 仍排除:應徵紀錄頁內嵌對話 UI、WebSocket 即時更新、卡片最新訊息摘要(→ v1.1 backlog)。
  • 後端依賴:pm_42 清單 API(HINT-GET-1)每列須回傳 enc_room_id(來源 job_applications.chat_room_id);不需新 chat API
  • 前端依賴:訊息通知頁須支援讀取 ?room= query 並自動開啟對話(若尚未實作,列為聯動項)。

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

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

規則 ID規則摘要是否關鍵備註
BR-011同一職缺再次應徵須距上次滿 72 小時;冷卻中無法投遞,系統回傳冷卻中與下次可投時間✅ 是冷卻不再是獨立狀態/ tab;改由「再次應徵」按鈕承載:冷卻中按鈕 disabled 並倒數(HH:MM:SS / 天·時),到期自動可投
BR-009職缺狀態(上架/下架/已刪除/已關閉);已刪除、已關閉為終態✅ 是已投職缺若進入終態,詳情需 boundary 顯示,不可再投
BR-015職缺搜尋僅顯示上架職缺⬜ 否紀錄頁不受搜尋顯示限制(已投紀錄仍須可查看歷史),但「再次應徵」入口受 BR-009/BR-011 約束
BR-001只有 email 已驗證才能登入✅ 是應徵紀錄為登入後頁面

4.2 補充說明

  • 本功能不新增 business rule,僅在 UI 層忠實呈現 BR-011/BR-009。
  • 與 pm_44(封鎖公司)互動:v2;v1 不實作封鎖相關 boundary 與 is_blocked_by_me

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

描述「需要追蹤什麼資料、為什麼」,不規定 API 欄位命名 / 雜湊 / DB schema(由 OpenAPI Spec 決定)。

5.1 實體列表

實體名稱說明來源頁面/區塊
ApplicationRecord一次應徵的快照與狀態,供清單與詳情顯示SEC-1 主列表、SEC-3 詳情
JobSnapshot應徵當下的職缺顯示資訊(避免職缺被改/下架後顯示空白)SEC-1、SEC-3
CompanySnapshot應徵當下的公司顯示資訊(名稱、logo)SEC-1、SEC-3
ReapplyEligibility是否可再次應徵(含冷卻到期時間)SEC-3、ACT

5.2 實體欄位定義(TypeScript 介面,語意用途;命名待與 Storybook 對齊)

// v1 清單所需欄位(語意用途;命名由 OpenAPI Spec 決定)
interface ApplicationRecord {
  enc_id: string;
  job: JobSnapshot;
  company: CompanySnapshot;
  applied_at: string;             // ISO8601 最近應徵時間
  resume_enc_id: string;
  apply_count: number;            // 同職缺累計有效應徵次數(≥1)
  reapply: ReapplyEligibility;
  enc_room_id: string;            // 對應 job_applications.chat_room_id;供 deep link(與 GET /api/chat/rooms 的 enc_room_id 相同)
  application_message?: string;   // 求職信摘要(投遞時快照,靜態顯示)
  // v2 再納入:
  // status_code: ApplicationStatus;
  // status_name: string;
}

// v2:HR 處理狀態 + tab 篩選(全部 / 審閱中 / 面試邀約 / 婉拒)
type ApplicationStatus =
  | 'submitted'
  | 'reviewing'
  | 'invited'
  | 'rejected';
// 註(Eric 2026/06/24):冷卻不是 status enum,由 reapply.cooldown_until 驅動按鈕倒數。
// 註(Eric 2026/07/03):v1 不顯示狀態 badge / tab;Storybook mock 可保留完整願景供設計參考。

interface JobSnapshot {
  enc_id: string;
  title: string;
  lifecycle_code: 'published' | 'unpublished' | 'closed' | 'deleted'; // 對齊 BR-009
  area_name?: string;
}

interface CompanySnapshot {
  enc_id: string;
  name: string;
  logo_url?: string;
  // is_blocked_by_me: boolean;  // v2 + pm_44
}

interface ReapplyEligibility {
  can_reapply: boolean;
  cooldown_until?: string;        // ISO8601;冷卻中時提供,供按鈕倒數
  reason_code?: 'cooldown' | 'job_closed' | 'job_deleted'; // v2 再加 company_blocked
}

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

6.1 區塊列表

區塊 ID區塊名稱說明
SEC-1應徵清單卡片/列表,一筆一職缺;公司/職缺/最近應徵日/再投/求職信 deep link;終態職缺灰階
SEC-2狀態篩選列v2(Storybook 可展示 tab:全部 / 審閱中 / 面試邀約 / 婉拒)
SEC-3單筆詳情點開抽屜或導職缺頁;v1 顯示最近應徵日 + 再投/冷卻倒數
SEC-4空狀態無應徵時導向「找工作」CTA

6.2 各區塊資料需求

SEC-1 應徵清單

  • 顯示實體ApplicationRecord[]
  • 資料需求:分頁(page, page_size)、排序(預設 applied_at desc)
  • 顯示規則:同職缺多次應徵合併為一列已投 N 次),時間顯示最近應徵日
  • 職缺終態(closed / deleted):整卡灰階opacity 降低或灰階濾鏡);職缺標題連結停用;顯示 boundary「此職缺已關閉」;隱藏「再次應徵」
  • 空狀態:顯示「你還沒有應徵任何職缺」+「去找工作」CTA
  • 求職信區塊(v1.3)
    • 顯示 application_message 摘要(truncate,例如 3 行)。
    • 整區可點擊;cursor/hover 提示「查看對話」。
    • 點擊 → router.push('/user/message-notification?room=' + enc_room_id)(§9.1)。
    • 求職信內容即時更新;對話內容以訊息通知頁為準。

SEC-2 狀態篩選列(v2)

  • v2 實作 tab + 狀態 badge(全部 / 審閱中 / 面試邀約 / 婉拒)。
  • Storybook mock 可保留完整 tab 作為設計願景;production v1 不實作。

SEC-3 單筆詳情

  • 內容(v1):職缺標題(非終態可連結職缺頁)、公司、最近應徵日apply_count再次應徵 按鈕
  • 內容(v2):狀態 badge、完整多次應徵時間軸、pm_44 封鎖 boundary
  • 職缺終態:同 SEC-1 灰階 +「此職缺已關閉」、停用連結、隱藏再投
  • 「再次應徵」按鈕的三態
    • 可投:enabled,文案「再次應徵」→ 導投遞流程。
    • 冷卻中(BR-011):disabled,按鈕本身顯示倒數計時(剩 <1 天用 HH:MM:SS,≥1 天用「N 天 H 時後可再投」);hover/title 顯示「下次可投:{cooldown_until}」;到期自動恢復可投。
    • 終態(BR-009):隱藏按鈕,灰階 + boundary「此職缺已關閉」。
  • 倒數來源:前端依後端 reapply.cooldown_until 換算並每秒 tick,避免時鐘漂移(§12)。

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

動作 ID動作名稱類型需要後端涉及實體說明
ACT-1載入應徵清單查詢(Read)✅ 是ApplicationRecord含分頁、排序;由後端依本 PRD 產 API spec
ACT-2切換狀態 tab查詢(Read)❌ v2ApplicationRecordv2
ACT-3開啟詳情查詢(UI)❌ v1 可選ApplicationRecordv1 清單欄位足夠;v2 再評估明細 API
ACT-4再次應徵寫入(Write)✅ 是ReapplyEligibility沿用既有 apply 流程;受 BR-011/BR-009 檢核
ACT-5撤回應徵(nice)寫入(Write)✅ 是ApplicationRecordMVP 可不做,列入 v2
ACT-6點求職信開啟對話導航(Nav)✅ 清單需 enc_room_idApplicationRecord跳轉 /user/message-notification?room={enc_room_id};訊息載入沿用既有 chat API

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

8.1 資料讀取需求(Read)

  • HINT-GET-1:取得我的應徵清單(分頁 + 排序)→ SEC-1;語意見 §5.2、§12.4 欄位映射(實作由 backend-api-spec-generator 產出

8.2 資料寫入需求(Write)

  • HINT-MUTATION-1:再次應徵 → 沿用既有 apply 端點語意(job_enc_id, resume_enc_id);須能讓 UI 呈現 BR-011 冷卻(清單/詳情之 reapply.cooldown_until)。

9. 導航 / Storybook Map

  • Storybook 標題Mockups/求職者/應徵紀錄
  • Stories 路徑storybook/src/stories/mockups/user/ApplicationRecords.stories.ts
  • Storybook 連結https://storybook.wport.me/?path=/docs/mockups-user-applicationrecords—docs
  • 情境控制(實際 args)scenarioempty / mixed / has-cooldown / job-closed)——封鎖情境併入 mixed,無獨立 company-blocked(對齊實際 Storybook)
  • Storybook 與 v1 關係:Storybook 為完整願景 mock(含 tab、四種狀態);production v1 範圍以 §3.2、§12.2 為準,兩者並存不視為 PRD 不一致。
  • 對應 production 路由:求職者會員中心下(僅參考,不在此新增路由)

9.1 求職信 Deep Link(v1.3.0)

項目規格
觸發應徵紀錄卡片「求職信」區塊點擊
目標 URL/user/message-notification?room={enc_room_id}
Query paramroom = 清單 API 回傳之 enc_room_id(= job_applications.chat_room_id 加密值)
目標頁行為載入 chat list → 依 room 自動選中並開啟對話;載入訊息用既有 GET /api/chat/rooms/:enc_room_id/messages
登入未登入 → 導登入 → 回跳保留 ?room=(對齊 §10.4 Auth)
失敗 fallbackroom 不存在 / 非本人 room → toast「找不到對話」→ 留訊息列表頁
刻意不做不在應徵紀錄 URL 加 ?room=(跳轉後由訊息頁承載)
Chat SoT對話 API / room 語意引用既有 chat 模組;pm-32 resolve 同用 enc_room_id

10. Flowcharts

10.1 User Flow

flowchart TD
    U1[登入後進入會員中心] --> U2[開啟應徵紀錄]
    U2 --> U3{有應徵紀錄?}
    U3 -- 否 --> U4[空狀態 + 去找工作 CTA]
    U3 -- 是 --> U5[顯示清單 + 最近應徵日]
    U5 --> U6[點求職信]
    U6 --> U12[跳轉 message-notification?room=]
    U12 --> U13[自動開啟對話]
    U5 --> U7[開啟單筆詳情]
    U7 --> U8{職缺狀態 / 冷卻?}
    U8 -- 可再投 --> U9[再次應徵 -> 投遞流程]
    U8 -- 冷卻中 --> U10[再次應徵按鈕 disabled + 倒數計時]
    U8 -- 已關閉/已刪除 --> U11[灰階 + 此職缺已關閉, 停用連結]

10.2 System Flow

sequenceDiagram
    participant User
    participant FE as Frontend
    participant BE as Backend
    User->>FE: 開啟應徵紀錄
    FE->>BE: GET 應徵清單(page)
    BE-->>FE: ApplicationRecord[] (含 reapply/cooldown)
    FE-->>User: 渲染清單
    User->>FE: 點「再次應徵」
    FE->>BE: POST 再次應徵(job,resume)
    BE->>BE: 檢核 BR-011 冷卻 + BR-009 狀態
    alt 通過
        BE-->>FE: 成功
        FE-->>User: 導投遞流程/成功提示
    else 冷卻中或終態
        BE-->>FE: 業務錯誤或 reapply 欄位
        FE-->>User: 顯示原因與下次可投時間
    end

10.4 Edge Case Coverage

類別情境系統行為UI 回饋可重試資料一致性策略備註
Network & Performance清單載入逾時 > 15s取消請求顯示逾時 + 重試Yes不寫入
Network & Performance「再次應徵」連點後端去重;前端按鈕 loading 鎖定防連點Noidempotency by (user,job,window)
Data & Input狀態 enum 未知值前端 fallback 顯示「處理中」不破版N/A以後端 status 為準v2(v1 無 status enum)
User Interruption載入清單中離開頁面取消未完成請求Yes無寫入
Auth & LifecycleSession 過期導登入並保留回跳提示登入過期Yes
Auth & Lifecycle點求職信時 session 過期導登入,回跳保留 ?room=登入後自動開對話Yes§9.1
Logical Inconsistency職缺已關閉/已刪除但紀錄存在清單/詳情灰階,再投停用「此職缺已關閉」;連結停用No以 job lifecycle 為準BR-009
Logical Inconsistency冷卻中嘗試再投後端拒絕回 cooldown_until顯示下次可投時間到期後 Yes不建立重複應徵BR-011
Logical Inconsistency清單有紀錄但 room 已失效訊息頁 fallback 列表toast + 不白屏Yes以 chat room 為準§9.1

11. Mock Data Schema

  • 資料來源:僅 mock,不呼叫真實 API。
  • 願景 vs v1:mock 可含 tab 與四種狀態(完整願景);v1 production 範圍見 §3.2。

12. 實作備註(Implementation Notes)

  • 禁止事項:❌ 不在此定義最終 API path/method;❌ 不直接改 business-rules.md。
  • 注意事項
    • 欄位命名與 Storybook/TS interface 一致。
    • C 端頁面 → 走 user CSS profile(見 gen-storybook-mockup-gen 的 Dual CSS Profile Contract)。
    • 冷卻倒數以後端 cooldown_until 為準,前端僅做顯示換算,避免時鐘漂移。

12.1 四致性表(Stage 6)

欄位對照表

欄位語意SoT版本
status_codeHR 處理狀態 enumPRD §5.2v2
apply_count同職缺有效應徵次數PRD §5.2v1
reapply.cooldown_until下次可投時間BR-011 + PRDv1
job.lifecycle_code職缺生命週期BR-009v1
enc_room_id應徵關聯聊天室BE job_applications.chat_room_idv1.3
application_message求職信快照BE job_applications.application_messagev1.3

常數表

常數SoT版本
再投冷卻72 小時BR-011v1
清單分頁 page_size20PRDv1
清單載入 timeout15sPRDv1

事件字典

事件觸發Payload 摘要SoT版本
application_list_viewed開啟頁面{}PRDv1
application_reapply_clicked點再次應徵{job_enc_id, result}PRDv1
application_cover_letter_clicked點求職信{enc_id, enc_room_id, enc_job_id}PRDv1.3

術語字典

術語定義SoT版本
有效應徵通過 BR-011 冷卻後成立的一次投遞BR-011v1
冷卻中距上次應徵未滿 72h 的狀態BR-011v1

12.2 版本凍結表

項目v1/v2Blocking?原因決策者日期
撤回應徵v2MVP 不含Eric2026/06/23
狀態 badge + tab(全部/審閱中/面試邀約/婉拒)v2待 HR 流程Eric2026/07/03
pm_44 封鎖公司互動v2pm_44 未上線Eric2026/07/03
完整多次應徵時間軸v2v1 僅最近應徵日 + apply_countEric2026/07/03
求職信 deep link 跳轉v1.3入口導流,依賴清單 enc_room_idEric2026/07/16
站內信完整整合v1.1+v1 僅跳轉,不做頁內嵌 / 即時Eric2026/07/16
最新訊息摘要(卡片)v1.1需 list API 擴充 last_message 欄位Eric2026/07/16

12.3 PRD 問題清單

#章節/規則問題建議修正類別影響SoT
1§5.2 statuscooldown 是否獨立狀態? 已裁決(Eric 2026/06/24):冷卻不是狀態,移出 enum / tab,改由 reapply.cooldown_until 驅動「再次應徵」按鈕倒數已定案PRD
2§5.2 status面試邀約 / 婉拒 / tab / badge 是否納入 v1? 已裁決(Eric 2026/07/03):皆 v2;Storybook 可展示完整願景已定案PRD
3§6.1多次應徵合併? 已定案:BE job_applications 合併一列已定案BE
4§6 SEC-3完整時間軸? v1 僅最近應徵日;逐次時間軸 v2已定案PRD
5§6 SEC-1職缺終態 UI已定案(Eric 2026/07/03):灰階 +「此職缺已關閉」已定案PRD
6§14.1 Av1 狀態流轉? 已裁決(Eric 2026/07/06):v1 不實作狀態機、不暴露 status enum、不做 tab/badge;頁面 = 全部應徵紀錄 flat list;reviewing / invited / rejected → v2,需另開 HR 流程 PRD已定案PRD
7§14.1 C2SEC-3 時間軸? 已裁決(Eric 2026/07/06):v1 清單欄位已足(最近應徵日 + apply_count);完整多次應徵時間軸 v2;詳情抽屜 v1 可選、不 blocking(對齊 ACT-3)已定案PRD
8§14.1 B1狀態變更通知? 已裁決(Eric 2026/07/06):v1 無狀態變化 → 不做狀態變更通知;v2 HR 流程上線後若需通知,另案已定案PRD
9§14.1 D1「已投遞」篩選 tab? 已裁決(Eric 2026/07/06):不需要;頁面即應徵紀錄,有紀錄即代表已投遞;v2 若有 tab,「全部」已涵蓋已定案PRD
10§14.1 B3pm_44 上線先後? 已裁決(Eric 2026/07/06):pm_42 先上線;pm_44 封鎖互動 v2 接上已定案PRD
11§9.1求職信點擊是否 deep link?跳哪?已定案(Eric 2026/07/16):跳 /user/message-notification?room=;求職信保持靜態;即時最新訊息 → v1.1已定案PRD

12.4 後端參考備忘(W101-TalentSearchHub)

性質:供 RD / backend-api-spec-generator 參考,非 PRD 缺陷清單。PRD 已標「需要後端」之處,由後端依本節產 API。
SoT repoW101-TalentSearchHub(C 端應徵);W101-AMS 非本功能實作主體。
稽核日期:2026/07/03。

可沿用

PRD 需求後端現況路徑
BR-011 72h 冷卻REAPPLICATION_COOLDOWN_HOURS = 72applications.service.ts
同職缺合併job_applications unique (user_id, job_id, status)JobApplications.ts
再次應徵POST /applications/applyapplications.controller.ts
BR-009 終態阻擋再投validateJob()PUBLISHEDapplications.service.ts
開啟對話GET /api/chat/rooms/:enc_room_id/messages(既有)chat.controller.ts
room id 語意GET /api/chat/roomsenc_room_id 相同JobApplications.ts

RD 實作 backlog(不計入 PRD P0)

項目說明
求職者清單 API依 HINT-GET-1 + 下方欄位映射新建
清單含 reapplycooldown_until 供 UI 倒數
錯誤契約 / enum 映射由 OpenAPI spec 決定,PRD 不規定
pm_44 is_blocked_by_mev2 + pm_44 上線後
Legacy applyRecord 遷移工程計畫,不寫入 PRD

欄位映射草案(清單 API)

PRD 欄位後端來源
enc_idjob_applications.id 加密
applied_atlast_applied_at
resume_enc_idresume_id 加密
apply_countreapplication_count + 1
reapply.can_reapplycheckCanReapply(...).allowed ∧ job 可投
reapply.cooldown_untilcheckCanReapply(...).nextAvailableAt
job.lifecycle_codeJobStatus → §5.2 語意
enc_room_idjob_applications.chat_room_id 加密
application_messagejob_applications.application_message

12.5 v1.3 增量清單(Delta — 僅此需新增)

v1.0–v1.2 已上線(§2.1)。本節為 patch 工作範圍;AI / backend-api-spec-generator 請以此為準,勿重產 v1 全量 spec。

#項目規格參照狀態
D1BE清單 API(HINT-GET-1)補 enc_room_id§5.2、§12.4🔲 待做
D2BE清單 API 補 application_message(若卡片已顯示求職信則 blocking)§5.2、§12.4🔲 待做
D3FE應徵紀錄:求職信可點 → 跳 /user/message-notification?room={enc_room_id}§6.2、§9.1、ACT-6🔲 待做
D4FE訊息通知頁:讀 ?room= 自動開啟對話§9.1、§13🔲 待做(聯動)
D5FE埋點 application_cover_letter_clicked§12.1🔲 待做
新 chat API❌ 不做(沿用既有)
應徵紀錄頁內嵌對話 / WebSocket 即時❌ v1.1+

實作優先序:D1 → D4 → D3 → D2(D2 可與 D3 並行,視卡片是否已顯示求職信)→ D5。


13. 下一步(Next Steps)

  • v1.3(本 patch):依 §12.5 Delta 執行;BE 擴充 HINT-GET-1 欄位,勿新建 v1 清單 API。
  • 送 RD:backend-api-spec-generator 依 §12.5 + §12.4 產增量 spec(enc_room_idapplication_message)。
  • 前端 v1.3(應徵紀錄):求職信可點 + 帶 enc_room_id 跳轉訊息通知頁(§9.1、D3)。
  • 前端 v1.3(訊息通知頁,聯動):支援 ?room= 自動開窗(D4)。
  • v1.1 backlog:卡片最新訊息摘要欄位。
  • v2 backlog:狀態 tab、HR 狀態機 PRD、pm_44、完整時間軸、狀態變更通知。
  • 補 i18n key(冷卻提示、「此職缺已關閉」、「查看對話」、「找不到對話」)。
  • Storybook mock 更新(非 blocking):求職信可點擊樣式。
  • Coda:回寫 應徵紀錄 列 PRD 欄=pm_42

14. 待補與決策事項(RD 規格前審查,2026/07/06)

RD 在產出後端 API 規格前,對本 PRD 做了一輪完整性審查。§14.1 PM 裁決已於 2026/07/06 回覆;§14.2 為 RD 自行決定僅知會。Storybook 仍可展示完整願景(§9),production v1 以 §3.2 為準。

14.1 PM 裁決(已定案,Eric 2026/07/06)

以下回覆 RD 審查時提出的五項;多數與 §3.2、§12.2、§12.3 既有裁決一致,此處正式收斂以免重複提問。

A. v1 應徵狀態 / tab(原:狀態流轉未定義)

  • 裁決:v1 不實作應徵狀態機、清單 API 不暴露 status_code / status_name、不做 tab / badge。
  • 頁面語意全部應徵紀錄(flat list);求職者看到的就是「我投過哪些職缺」。
  • v2reviewing / invited / rejected 連同狀態流轉定義 → 另開 HR 流程 PRD,不在本案 v1 scope。
  • 依據:§3.2 L49-51、§12.2 L320、§12.3 #2。
  • Storybook 提醒mixed 情境的狀態卡為靜態願景 mock,≠ production v1 行為。

C2. SEC-3 單筆詳情 / 多次應徵時間軸

  • 裁決:完整多次應徵時間軸 → v2;v1 清單列已含最近應徵日 + apply_count(§6.2 SEC-3、§3.2 L53)。
  • 詳情抽屜:v1 可選、不 blocking(ACT-3:清單欄位已足夠);不強制補 mockup。
  • RD 審查備註:§14.1 原引用「§6.1 SEC-3 描述時間軸」與現行正文不符——§6.2 已明確分列 v1 / v2 內容,時間軸從未列入 v1。

B1. 狀態變更後要不要通知求職者?

  • 裁決:v1 無狀態變化 → 不做狀態變更通知(信件 / 推播皆不含)。
  • v2:待 HR 流程與狀態上線後,若需通知 → 另案(不擴本案 scope)。
  • 依據:§3.2 L54(站內信已排除);狀態單純是紀錄,沒有狀態變化就不需要通知。

D1. 要不要有「已投遞」篩選 tab?

  • 裁決不需要
  • v1:無 tab,不適用。
  • v2:若未來做 tab,不需獨立「已投遞」tab——頁面即應徵紀錄,有紀錄即代表已投遞,「全部」已涵蓋。

B3. pm_44(封鎖公司)與本案的上線先後?

  • 裁決pm_42 先上線;pm_44 封鎖互動 v2 接上。
  • 技術:RD graceful degrade 維持 §14.2 既定(is_blocked_by_me 當 false、不顯示封鎖 boundary)。
  • 依據:§3.2 L52、§12.2 L321。

14.2 RD 自行決定(知會,不需 PM 回覆)

以下屬顯示規則 / 技術契約 / 文件對齊,RD 於 spec 階段自行定案並記錄於此,PM 無需處理:

  • B2 合併列顯示哪一次狀態(v2):v1 清單不含 status,本項不適用;待 v2 狀態上線時 RD 定:合併列顯示最新一次應徵的狀態,與時間一致。
  • D2「再次應徵」端點語意(資格檢查 vs 完整投遞):§8.2 與 §10 流程圖描述不一。RD 定:於 spec 階段對齊既有投遞流程實作決定,不另擴新語意。
  • C1 Storybook 情境與命名不一致:§9 / §11 列 5 情境(含獨立 company-blocked),實際只有 4 個(mixed / has-cooldown / job-closed / empty)且命名為 mixed(非 mixed-status)。RD 定:以實際 Storybook 為準,回頭對齊 §9 / §11 文字與命名。
  • D1-技術面 status 參數合法值RD 定:v1 清單 API 不含 status 參數;v2 若實作 tab 篩選,status query 收 §5.2 四個 enum 值,不需獨立「已投遞」tab(§14.1 D1 已定)。
  • B3-技術面 pm_44 fallbackRD 定:pm_44 未上線時 graceful degrade(is_blocked_by_me 當 false、不顯示封鎖 boundary)。

一句話總結v1 可開工——清單 API + 冷卻(BR-011)+ 終態(BR-009);狀態/tab/通知/封鎖/時間軸均不 blocking。§14.1 五項 PM 裁決已定案;§14.2 僅知會。

文件結束