# Requirements: 巡樓後端（依 apps/web 接 live）

> Status: `approved`  
> Status note: 使用者 2026-07-10「需求 OK」  
> Slug: `haixun-backend`  
> Last updated: `2026-07-10`  
> 輸入真相：`apps/web` 現有畫面與 repository 介面；`AGENTS.md`；`old/` 業務參考；`stand-alone-service/` 後端基礎設施骨架

## 1. 一句話

把 **Harbor Desk 前端已能用 mock 完成的操作**，接到可長期維運的真後端與 worker（含 **Threads OAuth、真實發文、海巡、邀請**），讓 `live` 模式可上線使用。

## 2. 誰用、在什麼情境

| 角色 | 目標 |
|------|------|2jo4
| 一般會員（島民） | 登入後經營 Threads：OAuth 連帳、人設、創作串場、**真發送**、海巡、用量、邀請關係 |
| 管理員 | 代建島民、管權限／停權／方案、調邀請歸屬、系統設定 |
| 營運／實作者 | 依 `stand-alone-service` 風格骨架交付可部署的 API＋worker |

## 3. 背景與動機（As-is → 為什麼改）

- **現況問題：** 前端 Phase B mock 完整；`live` 無真後端。  
- **不改的後果：** 無法上線；繼續堆 mock 無法驗證 OAuth／真發文／海巡。  
- **參考（非需求本體）：**  
  - 行為：`apps/web`（repos／pages）  
  - 契約精神：`AGENTS.md`  
  - 業務舊碼：`old/backend`（海巡／Threads 模式可抄，**不整包搬**）  
  - **基礎設施：** `stand-alone-service/` — **直接搬進主線再改造成巡樓 API**（重點保留／改造 model 層；有 bug 或更好寫法可邊做邊修）  
  - 邀請：`docs/product/invite-network/`  

## 4. 目標（To-be）

### 4.1 必須達成（P0）— 身份、帳號 OAuth、地基

1. **會員身份**  
   - 登入／登出／me／refresh；信箱驗證；重設密碼；改個人資料。  
   - **頁面**：現階段不開公開註冊／三方 UI；營運以**管理員代建**為主。  
   - **API**：會員相關（含自助註冊、三方註冊／登入）**功能要完整**，供日後開頁或外部使用。  
2. **管理員島民管理**：分頁搜尋、新增（回傳臨時密碼）、停權／復權、角色、驗證狀態、代重設密碼。  
3. **Threads 經營帳號＝真 OAuth 優先**  
   - 發起授權、callback 換 token、列表、連線狀態、刷新 session、解除綁定。  
   - 禁止「只登記假連線、永遠不 OAuth」當 P0 完成定義。  
4. **Job 與站內通知**：建立／查詢、進度與終態、通知列表／未讀／已讀。  
5. **系統設定**：  
   - **etc 系統級** AI／Exa key（平台代打）。  
   - 會員可填自己的 key → **BYOK**（見 spec 計費）。  
   - AI 單一 provider＋model（xAI｜OpenCode Go）；搜尋 Exa；開發模式；擴充 ZIP。  
6. **統一契約**：UTC nano、envelope、分頁、權限錯誤；**禁止**未實作 API 回成功空資料。  
7. **前端 live**：可打真後端；失敗不亂清 token。  

### 4.2 應該有（P1）— 創作、**真發送**、海巡、邀請

1. **人設**：CRUD、active、文字／帳號分析（可 Job）。  
2. **互回方案 ThreadPlay**：存檔、外部連結解析、提交進 Outbox。  
3. **Outbox 真發送**  
   - 列表／詳情、步驟狀態、重試、刪除。  
   - Worker **真實呼叫 Threads 發文／回覆**（非僅模擬按鈕）；失敗可觀測、可重試；root 失敗不得誤標後續成功。  
4. **已發貼文／提及／單篇發布**：同步、產文、**真送回覆**、略過。  
5. **靈感／研究／媒體**：**僅現 UI 版**（趨勢 list/refresh、元素 CRUD、session、chat 產文）；Exa 研究、生圖／上傳。**不做**舊 list／viral／bookmark／spark 流。  
6. **用量與方案**：本月摘要、事件、三檔方案、admin 代設、購買紀錄（付款可假成功）。  
7. **海巡 Scout（必做，雙路徑）**  
   - 品牌／產品／brief／掃描命中／外展草稿與發送狀態。  
   - 行為對齊前端 mock＋**參考 `old/backend` 海巡／爬蟲／搜尋模式**。  
   - **路徑分流（產品規則）：**  
     - **開發模式關閉（預設）：** 掃描／取樣走 **Threads／官方 API**（或產品既定 API 路徑）。  
     - **開發模式開啟：** 允許／應使用 **Chrome 擴充 session 爬蟲**路徑（對齊前端擴充＋old 爬蟲能力）。  
   - 兩條路徑都要做；以會員設定的 `dev_mode` 決定預設走哪條。  
8. **邀請關係（必做）**  
   - 每人邀請碼；補填綁定（僅無邀請人）；會員看邀請人／直邀／延伸；管理員搜尋＋調歸屬（防環）。  
   - 用語：邀請人／直邀／延伸（不用上線／下線產品文案）。  

### 4.3 以後再說（P2）

1. 真實金流／發票、多租戶帳單。  
2. Insights 真數據管線、Islander agent。  
3. Extension 安全同步硬化、公開自助註冊（若未來要開）。  

## 5. 範圍

### In scope

- 依 `apps/web` 能力交付真 API＋worker。  
- **後端基礎設施：直接搬 `stand-alone-service` 進主線再改造**（非從零新骨架）。  
- **撰寫方式必須走 go-zero 慣例**（見 §6.1），不可自創另一套目錄／設定風格。  
- **Worker 獨立 binary**：Outbox **真發送**、Job（分析、同步、海巡掃描等）。  
- 會員 JWT vs AI／Exa token 分離。  
- **權限（permission）概念**：至少區分一般會員／管理員能力；中介層與模組可對齊 stand-alone 的 auth／admin 模式並收斂到巡樓角色。  
- **初始化與種子分開**：Mongo index 等 init、資料 seeder 各成一包／獨立指令，不塞進 gateway 啟動主路徑胡亂混寫。  

### Out of scope（明確不做）

- 公開自助註冊（本階段）。  
- 重做前端視覺大改。  
- `old/backend` 整包當交付。  
- 未實作卻回成功空資料。  
- 真實金流（P2）。  
- **多份環境 etc 碎檔**（見 §6：etc 只要一份）。  
- **把會員 uid 改成字串 slug**（如 `user_demo`）當主鍵語意——**必須維持可讀的數字 uid**。  

## 6. 已鎖定決策（2026-07-10）

| # | 議題 | 決策 |
|---|------|------|
| 1 | 公開註冊 **UI** | **頁面先不做**；主路徑仍 admin 代建。 |
| 1b | 會員 **API** | **完整提供**（含註冊、三方登入等）；不因無頁而砍 API。 |
| 2 | Threads 綁帳 | **要先 OAuth**（P0）。 |
| 3 | Outbox／回覆 | **真的送出**（P1，非模擬完成）。 |
| 4 | 邀請＋海巡 | **都要做**（P1）。海巡參考 old。 |
| 5 | 後端骨架 | **直接搬 `stand-alone-service`**，改造成巡樓；**重點在 model**；bug／更好寫法邊做邊修或討論。 |
| 6 | Worker | **獨立 binary**（與 gateway 分離）。 |
| 7 | 海巡路徑 | **API＋爬蟲都要**；**未開 dev mode → 預設 API**；**開 dev mode → 可／應走爬蟲**。 |
| 8 | 程式風格 | **一律 go-zero 方式**撰寫／產生（`.api` → generate、handler／logic 分層等）。 |
| 9 | etc 設定 | **只要一份**設定檔（例：`etc/gateway.yaml`）；環境差異用變數或單一檔內區塊，**不要** gateway-dev／prod／nas 多份碎檔為交付常態。 |
| 10 | 會員 uid | **數字 uid**（可讀、可排序、人眼能懂）；**不可**改成隨機字串主識別。前端 mock 的 `user_*` 字串在 live 應對齊後端數字 uid 契約。 |
| 11 | 權限 | **要有權限概念**（member／admin 與後續可擴充）；API 中介層強制。 |
| 12 | 初始化 | **Mongo index 等初始化**寫成**另外一包／獨立 cmd**，不與業務 handler 混在一起。 |
| 13 | Seeder | **插入種子資料**的 seeder **分開一包／獨立 cmd**，與 index init 分離。 |
| 14 | AI／搜尋 key | **etc 系統預設 key**；會員有填＝**BYOK**，該 meter 不扣方案點仍記 event。 |
| 15 | 用量 | platform 扣 credits 並單獨統計；**BYOK 另計次數並分開顯示**，禁止與平台混成同一進度／總次數（見 spec §4.7）。 |
| 16 | 範圍原則 | **以現在 `apps/web` UI 主路徑為準**（有畫面呼叫 = 後端 MUST；僅 mock／死碼 = 不做）。 |
| 17 | 靈感 | **舊靈感流完全捨棄**；只做現 UI：trends／elements／session／chat。 |
| 18 | 死 API | **Remove**：generateFromFormula、ScoutTopic CRUD、舊 inspiration list/viral/bookmark/spark/searchTrends 等。 |
| 19 | 媒體附圖 | **真上傳**（持久可取 URL）；不得以本機-only data URL 當 live 完成。 |
| 20 | Insights | **維持 P2**（本階段不做真 Insights 管線）。 |
| 21 | 前端 uid | API 為數字；FE 顯示／狀態可用字串化，**不得**把 `user_*` 當後端主鍵契約。 |

### 6.1 go-zero 與目錄（需求層約束，非完整實作步驟）

- API 以 **go-zero `.api` 定義** 為源，經 generate 產出路由／types 骨架；業務寫在 logic／module。  
- 分層大致：`generate/api` → `handler` → `logic` → `module`（domain／repository）→ `svc`。  
- **禁止**為圖省事繞過 go-zero、手寫一整套私有 router 風格當主路徑。  
- **etc：交付只維護一份**主設定（開發／正式差異用 env 覆寫或文件說明，不複製多份 yaml 當常態）。  

### 6.2 身份識別（uid）

- 系統內會員主識別為 **數字 uid**（與 stand-alone-service「可產生、可讀」方向一致，禁止難讀隨機字串當主 uid）。  
- 登入帳號仍用 email；對外 API／管理畫面以數字 uid 為準。  
- 前端 live 接線時，mock 的 `user_demo` 類字串 **不得**成為後端契約；spec 階段對齊型別。  

### 6.3 初始化與 Seeder（分開）

| 包／指令（名稱 plan 再定） | 職責 |
|---------------------------|------|
| **init／migrate 類** | Mongo **index**、必要 schema 約束、集合準備 |
| **seeder 類** | 插入示範／管理員種子、選用 demo 資料 |
| **gateway／worker 啟動** | 不負責 bulk seed；至多檢查連線 |

兩者必須可分開執行、可重複跑時行為可預期（idempotent 精神進 spec）。

## 7. 使用者故事（可驗收）

### P0

| ID | 作為… | 我想要… | 以便… | 驗收要點 |
|----|--------|---------|--------|----------|
| US-01 | 島民 | email／密碼登入與會話 | 進／app | live 登入；me 持久；錯誤可讀 |
| US-02 | 島民 | 驗證信箱、重設密碼、改資料 | 帳號可用 | 驗證閘對齊前端；改信箱重驗證 |
| US-03 | 管理員 | 代建與管理島民 | 無公開註冊也能加人 | 臨時密碼一次顯示；停權不可登；保留至少一 admin；**數字 uid** 可見 |
| US-08 | 系統 | 依權限擋 API | 非 admin 不能管島民 | 無 permission 回可讀錯誤 |
| US-04 | 島民 | **OAuth 綁定 Threads** | 真連帳 | 授權完成後列表出現 usable 帳號；token 安全保存；可刷新／解除 |
| US-05 | 系統 | Job＋通知 | 知背景結果 | 狀態機合法；終態有通知 |
| US-06 | 島民 | AI／Exa／開發模式設定 | 後續能力 | key 不回顯；換 provider 有模型清單 |
| US-07 | 前端 | live 打真 API | 離 mock | 未實作＝明確錯誤 |

### P1

| ID | 作為… | 我想要… | 以便… | 驗收要點 |
|----|--------|---------|--------|----------|
| US-10 | 島民 | 人設 CRUD／分析 | 產文像我 | 可落庫；active |
| US-11 | 島民 | 互回方案→Outbox | 排程發串 | 發言池規則對齊前端 |
| US-12 | 島民 | Outbox **真發到 Threads** | 真實上線 | 步驟 published 對應平台成功；失敗可重試；root fail 不誤標 reply |
| US-13 | 島民 | 同步貼文／提及／真回覆 | 日常 | 同步可列表；送出真上平台 |
| US-14 | 島民 | 靈感／研究／媒體 | 開題 | session 可續；研究有來源 |
| US-15 | 島民／admin | 用量與方案 | 控成本 | 點數；admin 代設 |
| US-20 | 島民 | 海巡 brief＋掃描＋外展 | 找機會 | 命中列表；狀態可更新；**關 dev→API；開 dev→爬蟲** 皆可驗收 |
| US-21 | 島民 | 邀請碼＋補填＋直邀 | 關係 | 無邀請人可綁一次；已綁不可自改 |
| US-22 | 管理員 | 調邀請歸屬 | 糾錯 | 防環；路徑正確 |

## 8. 成功標準

- [ ] **無公開註冊**；admin 可代建並登入。  
- [ ] P0：live **OAuth 完成至少一 Threads 帳號** 且 me／Job／通知可用。  
- [ ] P1：至少一條 **方案→Outbox→Threads 平台上可見發文／回覆**（真發送）。  
- [ ] P1：海巡可完成一輪 brief→掃描→命中列表；**dev off＝API、dev on＝爬蟲** 各至少一條可驗收路徑；邀請可補填與管理歸屬。  
- [ ] 未實作能力不得假成功。  
- [ ] 時間 UTC nano；JWT 與 provider key 分離。  
- [ ] 後端以 **搬入並改造的 stand-alone-service** 為骨架；**獨立 worker binary** 存在。  
- [ ] **go-zero 風格**；**etc 僅一份**主設定。  
- [ ] 會員 **數字 uid**；**權限**中介層生效。  
- [ ] **index init** 與 **seeder** 分包裝、可獨立執行。  

## 9. 約束與假設

- **約束：**  
  - `AGENTS.md` 契約精神。  
  - 新交付不在 `old/`。  
  - 基礎設施：**直接搬 `stand-alone-service` 進主線並改造成巡樓**；電商域刪除；**model 優先**；可修 bug／改寫。  
  - **撰寫＝go-zero 方式**（`.api` generate、handler／logic 分層）。  
  - **etc 只要一份**（不維護多份 gateway-*.yaml 為常態）。  
  - **uid＝數字**，可讀；不做字串主鍵改造。  
  - **權限概念**必有（member／admin 起）。  
  - **init（含 mongo index）** 與 **seeder** 分開兩包／兩指令。  
  - **Worker 獨立 binary**。  
  - 海巡／Threads 可參考 `old/backend`，契約以新前端為準。  
  - 前端 mock｜live 同一 repos 介面；live 時 uid 契約對齊數字。  
- **假設：**  
  - 單租戶 `default` 先夠用。  
  - Threads App 金鑰由環境提供。  
  - 購買方案可先假付款；真金流 P2。  
  - stand-alone 的 member／token／permission 模式可重用並裁剪。

## 10. 風險

| 風險 | 影響 | 緩解 |
|------|------|------|
| OAuth＋真發文＋海巡同進 P0/P1 | 工期長 | P0 只鎖 OAuth＋地基；真發文／海巡／邀請在 P1 但仍必做 |
| stand-alone-service 電商殘留 | 噪音、誤用 | **刪除 cart／order／product**；保留 member／token／permission／mongo 模式 |
| etc 多檔環境漂移 | 難維運 | **只留一份**主 yaml＋env |
| 字串 uid 難讀／與前端 mock 混用 | 除錯痛 | **堅持數字 uid**；前端 live 對齊 |
| old 海巡與新前端語意差 | 行為漂移 | spec 以 apps/web 為準，old 只供演算法／爬蟲 |
| Threads API 變更／限流 | 發送失敗 | 錯誤進 Outbox／Job；可重試 |
| 密鑰外洩 | 資安 | 分離儲存；禁止 log 明文 |

## 11. 開放問題（剩餘）

（原 1–3 已鎖定，見 §6。）  

1. 搬入後目錄命名：**已定 `apps/backend`**（由 `stand-alone-service` 遷入改造；非 `services/api`）。  
2. Threads App／爬蟲帳號與金鑰的環境變數清單— **spec／plan 列配置項**。  

## 12. 前端能力對照

| 域 | 前端 | 波次 |
|----|------|------|
| Auth／Profile（無公開註冊） | Login, Profile… | P0 |
| Admin 島民 | AdminUsersPage | P0 |
| Crew 帳號 **OAuth** | CrewPage | P0 |
| Jobs／通知 | Jobs, bell | P0 |
| Settings | SettingsPage | P0 |
| 人設 | Crew personas | P1 |
| Studio／Outbox **真發送** | Studio, Outbox | P1 |
| 已發／提及 | OwnPosts, Mentions | P1 |
| 靈感／研究／媒體 | Inspire… | P1 |
| 用量／方案 | Usage, Plans | P1 |
ji3| **海巡／品牌** | Scout, Brands | **P1** |
| **邀請關係** | InvitePage | **P1** |
| Insights | InsightsPage | P2 |

## 13. 批准

- [x] 需求已批准（2026-07-10 / 使用者「需求 OK」）：

---

**決策 1–7 已全部鎖定。**  
若整體沒問題，請回 **「需求 OK」** → 下一回合寫 **spec.md**（行為契約、狀態機、搬 stand-alone-service 的 Retain-Replace-Remove、海巡 dev 分流）→ 再 plan → 再拆 task。
