# 前端(apps/web)↔ Spec(haixun-backend)全量對照 > Status: **decisions locked(部分)** · 2026-07-10 > 目的:在 **重切 task 之前** 確認「前端已有/在用的能力」是否被後端 spec **完整擁有**(可 live 交付),並標出雙向缺口。 > 輸入:`apps/web` **現在 UI 實際呼叫**(**以 UI 為主**);`repos.ts`;`spec.md` §4–§5–§9。 > **範圍原則(2026-07-10 使用者):以現在 UI 為準;舊靈感捨棄;死 API remove。** ## 0. 總結(先讀這) | 結論 | 說明 | |------|------| | **頁面級大致有對** | Login/Admin/Crew/Studio/Outbox/Jobs/Settings/Scout/Brands/Invite/Usage 在 spec §5.3 都有域 | | **方法級不夠完整** | Spec §5.2 是域摘要;§9 約 184 ID **未逐一對到** 前端每個在用 API。有一批 **UI 正在用** 的方法在 §9 **沒有獨立驗收** | | **前端也還沒對齊已批 BYOK** | `UsageEvent` **無** `key_mode`;`UsageMonthSummary` **無** platform/byok 分欄 → 與 spec §4.7 衝突,live 前 FE 必須改契約型別 | | **OAuth 前端契約缺** | Crew 用 `accounts.createMock`;repo **無** `oauthStart`/callback 消費路徑 | | **live 未接線** | `createRepos('live')` 仍回 mock(僅 `dataSource: 'live'` 旗標) | | **刻意不做(P2/mock 專用)** | Insights 真管線、simulate 當 live 完成、公開註冊頁、真金流 | **因此:以「全部功能完整擁有」標準,目前 spec + 既有 57 tasks 仍不足以保證前端每一條主路徑都有後端+驗收。** 應先凍結本對照表 → 補 spec 能力清單/§9 → 再重切 task。 --- ## 1. 畫面/導覽 → 後端域 | 前端路由/區塊 | 主要 Repos | Spec 域 | P0/P1/P2 | 對齊 | |----------------|------------|---------|----------|------| | `/login` | auth.login | Auth | P0 | ✅ | | `/forgot-password` `/reset-password` | request/reset password | Auth | P0 | ✅ | | `/verify-email` | send/verify email | Auth | P0 | ✅ | | `/app/profile` | updateProfile | Auth | P0 | ✅ | | `/app/users` | adminUsers.* + usage prefs | Admin + Usage | P0 | ✅ | | `/app/crew` 帳號 | accounts.* | Threads Accounts | P0 | ⚠️ UI 仍 createMock,缺 OAuth 契約 | | `/app/crew` 人設 | personas.* | Personas | P1 | ✅ | | `/app/studio` 方案/Wizard | plays.* | Plays + Outbox | P1 | ⚠️ listByPost/listByExternalUrl 未入 §9 | | `/app/studio` 單篇 Compose | compose.* + research + media | Compose + Research + Media | P1 | ⚠️ **mimic/analyzeViral** 未入 §9 | | `/app/studio` 已發 | ownPosts.*(**無** generateFromFormula) | OwnPosts | P1 | ⚠️ **analyzePost** 未入 §9;formula **Remove** | | `/app/studio` 提及 | mentions.* | Mentions | P1 | ⚠️ **generateReply** 未獨立驗收 | | `/app/studio` 靈感 | **現 UI 版 only**(session/elements/trends/chat) | Inspiration | P1 | ✅ 範圍鎖定;舊 list/viral/spark **Remove** | | `/app/outbox` | outbox.* | Outbox + Worker | P1 | ✅(simulate 僅 mock) | | `/app/jobs` | jobs.* + notifications | Jobs + Notifications | P0 | ✅ | | `/app/settings` | settings.* + 擴充 ZIP | Settings | P0 | ⚠️ platform_key_available/BYOK 顯示未全 | | `/app/scout` `/app/brands` | scout.*(**無** topics UI) | Scout | P1 | topics **Remove**;activeBrand 可 CLIENT | | `/app/invite` | invite.* | Invite | P1 | ✅ | | `/app/usage` plans checkout | usage.* | Usage | P1 | ⚠️ **分計分顯未進 FE 型別** | | `/app/today` | trends + ownPosts 摘要 | Inspiration + OwnPosts | P1 輕 | ⚠️ 聚合頁,依賴子域 | | `/app/insights` | ownPosts + **local** accountInsights | — | **P2** | ⭕ 需求已列 P2;不進 Phase C 後端必做 | | 公開註冊/三方頁 | — | Auth API 要、頁不做 | 決策 | ✅ 故意 | --- ## 2. Repository 方法全量分類 圖例: - **MUST** = UI 有呼叫或 live 主路徑必需 → 後端 **必須**有等價 API + 驗收 - **API-OK** = 後端要有、前端可不開 UI(register/三方) - **MOCK** = 僅 mock/除錯;live **不得**當完成定義 - **CLIENT** = 可前端 state 或本機;後端可選 - **P2** = 本階段不做後端 - **DEPRECATED** = 註解已 deprecated,可相容可不做新驗收 ### 2.1 Auth(8 UI + 缺口) | 方法 | 用途 | 分類 | Spec/§9 | 缺口 | |------|------|------|----------|------| | login / logout / me | 登入會話 | MUST | AU-01~09 | — | | updateProfile | 個人資料/改密 | MUST | AP-04~07 | — | | requestPasswordReset / resetPassword | 忘密 | MUST | AP-01~03 | — | | sendEmailVerificationCode / verifyEmail | 驗證 | MUST | AR/AP | — | | **refresh(token)** | 換 access | MUST | AU-07~08 | **FE AuthRepo 無此方法**;live client 必補 | | register / 三方 OAuth | 完整會員 API | API-OK | AR / AO | 頁可不做 ✅ | ### 2.2 AdminUsers(8) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | listUsersPage / getUser / createMember / setSuspended / setEmailVerified / setRoles / resetPassword | MUST | AD-01~14 | — | | listUsers(deprecated 全量) | CLIENT/compat | — | live 可只做 page | ### 2.3 Accounts(4 現有 + OAuth 缺) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list / refreshSession / remove(disconnect) | MUST | TH-05~10 | — | | **createMock** | MOCK | TH-09 禁止旁路過關 | live **改** oauthStart | | **oauthStart**(及 callback 由瀏覽器導向後端) | MUST | TH-01~04 | **FE repo/Crew UI 皆無** | ### 2.4 Plays(8) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list / get / save / remove / submit / resolveExternalLink | MUST | PL-01~05,08~09 | — | | **listByPost** | MUST(PlaysPanel) | **無** | 須補 §5.2 + 驗收 PL-10 類 | | **listByExternalUrl** | MUST(PlaysPanel) | **無** | 同上 PL-11 | ### 2.5 Outbox(6) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list / get / retryStep / remove | MUST | OB-* | — | | simulateSuccess / simulateRootFail | MOCK | OB-12 | live 隱藏或 no-op 失敗 | ### 2.6 Jobs / Notifications(3+4) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | jobs.list/get/startDemo | MUST | JB-01~04,09~10 | startDemo = template demo | | notifications.list/unread/markRead/markAllRead | MUST | JB-05~08 | — | ### 2.7 Settings(7) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | get/save Ai, get/save Placement, listModels | MUST | ST-01~04,14~15 | 應回 platform_key_available/member configured | | get/set DataSource | CLIENT | — | 前端切 mock\|live,非後端 | | 擴充 ZIP 下載 | MUST | ST-16 | T157 | ### 2.8 Personas(8) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list/get/getActiveId/setActiveId/save/remove/analyzeFromText/analyzeFromAccount | MUST | PE-01~06 | — | ### 2.9 OwnPosts(現 UI) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list / lastSyncedAt / sync / generateReply / sendReply | MUST | OP-01~05,07 | — | | **analyzePost** | MUST(OwnPostsPanel 有按鈕) | **無獨立 ID** | 須補 OP-08 + AI 計費 | | **generateFromFormula** | **REMOVE** | — | UI 未用;後端不做;FE repo 日後刪 | ### 2.10 Mentions(4) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | list / markReplied / skip | MUST | OP-06 偏狀態 | list 應明確 | | **generateReply** | MUST(MentionsPanel) | **無** | 須補 OP-09 + 計費 | ### 2.11 Inspiration(**僅現 UI 版** · 舊流 Remove) > 決策 2026-07-10:舊靈感完全捨棄,以 InspirePanel + Today 趨勢為準。 | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | listTrends / refreshTrends | MUST(Today + Inspire) | IN-01~02 | — | | listElements / saveElement / removeElement | MUST | IN-03 | — | | getSession / saveSession / clearSession / chat(mode=chat\|generate) | MUST | IN-04~05 | — | | list / saveIdea / generate / bookmarkTrend / listViral | **REMOVE** | — | 後端不做 | | sparkAngles / sparkAnglesForTopic / sparkFromTrend | **REMOVE** | — | 後端不做 | | searchTrends | **REMOVE**(UI 未呼叫) | — | 後端不做 | ### 2.12 Research / Media(1+2) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | research.search | MUST | IN-06 + ST/USG | — | | media.generateImage | MUST | IN-07 | — | | media.attachLocal | MUST(附圖) | IN-08~09 | **真上傳** → 持久 url;非法失敗;非 data URL 冒充 live | ### 2.13 Compose(3) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | publishSingle(+schedule) | MUST | PL-06~08 | — | | **mimic** | MUST(ComposerPanel) | **無** | 須補 + AI 計費(ai_copy) | | **analyzeViral** | MUST(ComposerPanel) | **無** | 須補 + AI 計費 | ### 2.14 Scout(31) | 方法群 | 分類 | §9 | 缺口 | |--------|------|-----|------| | brands CRUD, products CRUD, importProductFromUrl | MUST | SC-01~02,14 | — | | prepareBrief / runScanFromBrief / listPosts | MUST | SC-03~08 | — | | draftOutreach / skip / markPublished / sendOutreach | MUST | SC-09~11 | — | | removePost / removeTheme | MUST | SC-12 | — | | homework list/save/get/remove | MUST | SC-13 | — | | runScan / getScanContext | compat | 對齊 runScanFromBrief | 可映射 | | getActiveBrandId / setActiveBrandId | CLIENT | — | 前端 local/session 即可 | | **listTopics / saveTopic / removeTopic** | **REMOVE** | — | **無 UI 呼叫**;後端不做 | ### 2.15 Usage(10) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | getSummary / listEvents | MUST | USG-01~08 | **FE 型別缺 key_mode/byok 分欄** | | getPlanId / purchasePlan / listMyPurchases | MUST | USG-11 | listMyPurchases 應補 §9 | | getMemberPrefs / setMemberPrefs | MUST | USG-12~14 | — | | getTenantSummary / getTenantAnalytics | MUST admin | USG-10 | analytics 序列分 platform/byok | | setPlanId | admin/self 語意混 | 與 setMemberPrefs 重疊 | 契約要寫清 | ### 2.16 Invite(5) | 方法 | 分類 | §9 | 缺口 | |------|------|-----|------| | getMyNetwork / applyInviteCode / getTree / moveMember / listParentCandidates | MUST | IV-01~13 | — | ### 2.17 非 Repo 但重要 | 能力 | 分類 | 說明 | |------|------|------| | Insights 頁 | P2 | localStorage 報表;requirements 已列 P2 | | Job templates(persona_analyze、threads_sync、scout_scan、outbox_publish) | MUST | spec §5.4;worker | | 數字 uid | MUST | FE 現 `uid: string`;live 可 number→string 顯示但 JSON number | | BYOK 分顯 | MUST | FE Usage UI 需改;T155 有提但型別未改 | --- ## 3. Spec 有、前端尚未具備的 live 契約 | Spec | 前端現況 | 動作 | |------|----------|------| | oauthStart / OAuth 綁帳 | createMock | **改 AccountsRepo + Crew UI**(可 mock 保留 createMock) | | Auth refresh | 無 repo 方法 | **補 AuthRepo.refresh** | | Usage key_mode / platform vs byok summary | 無欄位 | **改 usageMeter 型別 + Usage 頁** | | Settings platform_key_available | 僅 member configured | **擴 AiSettings/Placement 顯示** | | 成功 envelope 102000 | live 未接 | live HTTP client | | 未實作不回空成功 | live 未接 | 同上 | | register/三方 API | 無頁 | 後端做即可(決策) | --- ## 4. 前端在用、Spec/§9 不足(必須補進「完整擁有」) 下列建議在 **重切 task 前** 寫入 `spec.md` §5.2 與 §9(新 ID): | # | 能力 | 建議驗收 ID | 優先 | |---|------|-------------|------| | 1 | plays.listByPost | PL-10 | P1 | | 2 | plays.listByExternalUrl | PL-11 | P1 | | 3 | compose.mimic | CP-01(或 PL-12)+ 計費 | P1 | | 4 | compose.analyzeViral | CP-02 + 計費 | P1 | | 5 | ownPosts.analyzePost | OP-08 + 計費 | P1 | | 6 | mentions.list + generateReply | OP-09~10 + 計費 | P1 | | 7 | usage.listMyPurchases | USG-15 | P1 | | 8 | usage key_mode/byok 分欄 | FE 型別 + USG | P0 契約 | | 9 | AuthRepo.refresh | 對齊 AU-07 | P0 前端 live | | 10 | accounts.oauthStart | 對齊 TH-01;取代 createMock 主路徑 | P0 前端 live | | — | 舊靈感/topics/generateFromFormula | — | **REMOVE · 不做** | --- ## 5. 與現有 Tasks 的關係(為何先不重切) | 現況 | 問題 | |------|------| | 57 tasks 依域粗切 | 未保證上表 MUST 方法都有 API task + 測試 case | | T171「fe live studio」 | 一行無法覆蓋 PlaysPanel + Compose mimic/viral + OwnPosts analyze + Mentions generate | | T155 usage byok display | FE 型別尚未定義分欄 → task 輸入不足 | | T135 accounts live | 未強制改掉 createMock → OAuth | **建議流程:** ```text 1) ~~開放題 1–6~~ ✅ 已鎖 2) ~~spec / requirements 回寫關鍵決策~~ ✅ 3) 重切 tasks(UI MUST + 測試 + FE live + apps/backend)← 下一步 4) ready-to-implement ``` --- ## 6. 已鎖定決策(2026-07-10) | # | 議題 | 決策 | |---|------|------| | 1 | 舊靈感 API | **完全捨棄**。後端/驗收只做 **現 UI**:trends、elements、session、chat。list/saveIdea/generate/bookmark/listViral/spark*/searchTrends → **Remove** | | 2 | generateFromFormula | **Remove**(UI 未用;後端不做) | | 3 | 範圍原則 | **以現在 UI 為主**:有按鈕/主路徑呼叫 = MUST;僅 mock/死碼 = Remove 或 P2 | | — | Scout topics | **Remove**(無 page 呼叫,跟 UI 原則) | | 4 | attachLocal / 附圖 | **真上傳**(後端收檔 → 持久可取 URL;禁止只靠本機 data URL 當 live 完成) | | 5 | Insights | **維持 P2**(頁面可 local 算;Phase C 後端不做真數據管線) | | 6 | FE uid | **可以**:API JSON **number**;前端顯示/比對用 toString 即可 | ### 靈感:後端 MUST 清單(凍結) ```text listTrends / refreshTrends listElements / saveElement / removeElement getSession / saveSession / clearSession chat({ message, pinnedIds, mode: chat|generate }) ``` ### 明確 Remove(後端不實作、不進 §9) ```text inspiration: list, saveIdea, generate, bookmarkTrend, listViral, sparkAngles, sparkAnglesForTopic, sparkFromTrend, searchTrends ownPosts: generateFromFormula scout: listTopics, saveTopic, removeTopic outbox: simulate*(live 完成定義) accounts: createMock(live 主路徑;mock 模式可留) ``` ### 媒體上傳(凍結 · 決策 #4) ```text media.attach / upload(對齊 FE attachLocal 語意) → 真 multipart(或等價)上傳 → 回可跨裝置使用的 url(及 id) → 非法/過大失敗可讀 → 不可 102000 + 空成功 ``` 儲存介面(本機 disk / S3 / 其他)實作可選,但驗收以「真上傳 + 可取 URL」為準。 ### 實作清潔(不擋定義) - FE 清掉 Remove 方法的 repo 型別(可併 live 接線 task) - Member.uid 型別:live 適配 number → 顯示 string --- ## 7. 統計(粗) | 項目 | 數 | |------|-----| | repos.ts 唯一方法名 | ~119 | | UI 有呼叫(抽樣 grep)的主路徑 MUST | 估計 **75–90** | | §9 現有 ID | 184(含權限/失敗/工程,非 1:1 方法) | | 明確 MUST 但 §9 缺口 | **≥ 8**(§4 表)+ BYOK FE 契約 + OAuth FE | | MOCK/P2/DEPRECATED 可排除 | simulate、createMock、Insights 真管線、spark*、公開註冊頁 | --- ## 8. 批准欄 - [x] 範圍原則:以現在 UI 為主 - [x] 舊靈感捨棄;generateFromFormula/topics Remove - [x] #4 真上傳 · #5 Insights 維持 P2 · #6 uid number + toString 可以 - [x] requirements #16–21、spec §5.2/§6/§9(含 IN-08~09)已回寫 - [x] **tasks v3 approved**(「ok同意」)→ `ready-to-implement`;指定 T### 才寫碼 - [x] 已回寫 requirements 決策 #16–18、spec §5.2/§6/§9 補 PL-10~11、CP-01~02、OP-08~11 - [ ] **授權補齊其餘 §9 細項後重切 tasks**(下一步)