前端(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 |
建議流程:
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 清單(凍結)
listTrends / refreshTrends
listElements / saveElement / removeElement
getSession / saveSession / clearSession
chat({ message, pinnedIds, mode: chat|generate })
明確 Remove(後端不實作、不進 §9)
inspiration: list, saveIdea, generate, bookmarkTrend, listViral,
sparkAngles, sparkAnglesForTopic, sparkFromTrend, searchTrends
ownPosts: generateFromFormula
scout: listTopics, saveTopic, removeTopic
outbox: simulate*(live 完成定義)
accounts: createMock(live 主路徑;mock 模式可留)
媒體上傳(凍結 · 決策 #4)
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. 批准欄