335 lines
16 KiB
Markdown
335 lines
16 KiB
Markdown
# 前端(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**(下一步)
|