# Thread-Master / 巡樓後端 — 架構導覽

這份文件幫助你**快速理解整個 monorepo 在幹什麼**，以及程式碼該從哪裡讀。

更細的 agent 規則見根目錄 `AGENTS.md`；產品方向（文案流重做）見 `docs/post-project-plan.md`。

---

## 1. 這是什麼專案？

**巡樓 Console + 後端**：給 Threads 經營者用的工作台。

| 能力 | 白話 |
|------|------|
| 帳號 / OAuth | 綁 Threads 帳號、token 刷新、連線診斷 |
| 人設 (Persona) | 風格分析（8D）、語調、知識素材 |
| 文案 / 任務 (Missions) | 主題發想、矩陣產稿、草稿排程（過渡期實作） |
| 海巡 (Patrol) | 依品牌／主題找貼文、知識圖譜、外展草稿 |
| 發布 (Publish) | 排程 queue、護欄、成效、提及回覆 |
| Job 系統 | 所有長任務：爬蟲、AI 產稿、token 刷新等 |

技術主幹：

```text
Go (go-zero) API + Mongo + Redis
  + Go workers（吃 Redis job queue）
  + Node/Playwright workers（8D 風格分析、關鍵字搜尋工具）
  + React 正式前端（backend/web）
  + Chrome extension（Threads session，目前前端同步刻意關閉）
```

---

## 2. 目錄地圖

```text
thread-master/
├── AGENTS.md                 # 寫碼／分層／時間／錯誤碼規範
├── Makefile                  # 全 repo 指令入口
├── docs/                     # 產品與架構文件（本檔）
├── scripts/dev-all.sh        # 一鍵起本機完整 stack
├── infra/                    # Mongo/Redis、nginx、systemd
├── deploy/                   # 正式 compose、env 範本
├── extension/                # Chrome 擴充
└── backend/                  # ★ 主產品（模組名 haixun-backend）
    ├── gateway.go            # API 程序入口
    ├── cmd/worker/           # Go worker 程序入口
    ├── cmd/tool/             # init（索引、admin）
    ├── generate/api/*.api    # API 契約（goctl）
    ├── etc/*.yaml            # 設定
    ├── internal/
    │   ├── handler/          # HTTP 進出口
    │   ├── logic/            # API 編排（不碰 Mongo 直接存取）
    │   ├── model/            # domain + usecase + repository
    │   ├── worker/job/       # step handler、scheduler、reaper
    │   ├── library/          # 共用能力（threads、placement、viral…）
    │   ├── middleware/       # JWT、RBAC、worker secret
    │   ├── svc/              # DI 組裝 ServiceContext
    │   └── response/         # JSON envelope
    ├── web/                  # 正式 React Console
    ├── worker/               # Node/Playwright
    └── docs/                 # job-system、gap 等後端計劃
```

> 文件裡有時寫 `haixun-backend/`，在 monorepo 裡就是 **`backend/`**。

---

## 3. 怎麼跑起來

```bash
# 1. 環境
cp deploy/.env.dev.example deploy/.env.dev   # 填 Mongo/Redis/JWT/Worker secret

# 2. 資料庫
make dev-infra

# 3. 一鍵：API + Go workers + Node tools/worker + 前端
make dev-all

# 或拆開
make run          # API :8890
make web-dev      # Vite :5173，proxy 到 API
```

| 服務 | 埠 |
|------|-----|
| API gateway | 8890 |
| 前端 Vite | 5173–5199 |
| keyword-search tool | 9101 |
| resolve-media tool | 9102 |

健康檢查：`curl http://127.0.0.1:8890/api/v1/health`

首次帳號：`make init`（建索引、權限、admin）。註冊一般會員需 **admin JWT**（封閉註冊）。

---

## 4. 請求怎麼走

```text
Browser / Worker
    → (nginx 可選)
    → go-zero Server (gateway.go)
    → middleware（JWT / MemberAuth / WorkerSecret）
    → handler（parse + validate）
    → logic（讀 actor、組 request）
    → model/usecase（業務）
    → repository（Mongo / Redis）或 library adapter
    → response.Write  { code, message, data, error }
```

### 分層規則（必守）

| 層 | 可以做 | 不可以做 |
|----|--------|----------|
| handler | parse、validate、呼叫 logic | 業務判斷、直接 Mongo |
| logic | 編排 usecase、組 payload | import `model/*/repository` |
| model/usecase | 可重用業務 | 知道 HTTP |
| AI provider adapter | 呼叫外部 AI | 讀 setting、Mongo、HTTP context |
| worker step | 透過 job usecase 更新進度 | 裸 Update 蓋 job 狀態 |

### Auth 重點

| 路由類型 | Header |
|----------|--------|
| 一般保護 API | `Authorization: Bearer <會員 JWT>` |
| AI（provider key 占 Authorization） | `X-Member-Authorization` + `Authorization: <provider key>` |
| 內部 worker | `X-Worker-Secret` |

Access token 由 `/api/v1/auth/login|refresh` 簽發。AI key **每次 request 帶入**，不寫進 config。

### 時間與列表

- 儲存／API 時間欄位：**unix nanoseconds（UTC）**
- 列表：`?page=&pageSize=`，回傳 `data.pagination` + `data.list`（部分舊 API 仍用 `limit`，屬技術債）

---

## 5. Job 系統（最重要的背景機制）

長任務一律走 job，不要在 HTTP request 裡跑 Playwright / 長 LLM。

```text
CreateRun（API 或內部）
  → Mongo 寫 run（pending）
  → Redis 佇列 jobs:queue:<workerType>
Worker ClaimNext
  → BRPOP → TryLock(jobID, workerID)
  → status → running
  → 依 template steps 執行 handler
  → Heartbeat 續 lock
  → CompleteRun / FailRun / AcknowledgeCancel
```

| 元件 | 檔案 |
|------|------|
| 建立 / claim / 完成 | `internal/model/job/usecase/usecase.go` |
| Redis queue/lock | `internal/model/job/repository/redis_queue.go` |
| Go runner | `internal/worker/job/runner.go` |
| 排程 / reaper | `scheduler.go` / `reaper.go` |
| 設計文件 | `backend/docs/job-system-plan.md` |

**規則：** 狀態轉移用 guarded update；lock value = `workerID`；release 必須檢查 owner。

### 程序角色

| 程序 | 職責 |
|------|------|
| Gateway | HTTP；可跑 scheduler/reaper/token/publish sweeper；**通常不 claim job** |
| Go worker（一 type 一 process） | 消費對應 queue、跑 step handler |
| Node style-8d | 經 **HTTP internal API** claim，Playwright 爬公開頁 |
| Node keyword/media | 被 Go 呼叫的 HTTP 工具，不是 job consumer |

Gateway 在 `JobWorker.Enabled=false` 時，仍可能 **inline** 起 topic/formula/rewrite 三個 copy worker（見 `internal/svc/job_workers.go`）。

---

## 6. 產品功能地圖（前端 ↔ 後端）

前端是 **hash 路由**（`App.tsx`），沒有 React Router。

| Hash | 頁面 | 主要後端域 |
|------|------|------------|
| `#dashboard` | 總覽 | accounts、jobs、publish summary |
| `#accounts` | Threads 帳號 | threads_account、OAuth、guard |
| `#brands` | 品牌 / 產品 | brand |
| `#personas` | 人設 / 8D | persona、style_preset、style-8d job |
| `#missions` | 文案工作台 | inspire、content_ops、copy_draft、matrix/formula/rewrite jobs |
| `#patrol` | 海巡獲客 | placement_topic、knowledge_graph、scan_post、outreach |
| `#publish` | 發布 / 回覆 / 自家貼 | publish_queue、mention_inbox、own_post_formula |
| `#jobs` | 任務監控 | job runs / schedules / events |
| `#settings` | 會員 / AI | member、placement settings |
| `#gaps` | 靜態路線圖 | **無 API** |
| `#register` | 管理員建會員 | auth register（需 admin） |

API client：`backend/web/src/api/haixun.ts` + `client.ts`（envelope、refresh、502 retry）。

### 兩條產品流

```text
Flow A  文案營運（過渡）
  MissionsPage → inspire / content plans / matrix / drafts → publish_queue
  舊 copy_mission 完整 pipeline 已半拆（見 post-project-plan）

Flow B  海巡獲客
  Brands + PatrolPage → 主題 → 圖譜 → 掃描貼文 → outreach 草稿 → 發布
```

`docs/post-project-plan.md` 計劃用 **Post Project** 取代 Flow A 舊 pipeline。

---

## 7. 後端 model 一覽（讀碼用）

| model | 用途 | 前端是否主用 |
|-------|------|----------------|
| auth / member / permission | 登入與 RBAC | 是 |
| setting | 通用 KV | 弱（多半用 typed settings） |
| ai | provider 抽象 + SSE | 設定頁 / AI 路由 |
| job | 模板 / run / schedule / event | Jobs + 各頁輪詢 |
| threads_account | 帳號、OAuth、token | 是 |
| persona / style_preset | 人設 | 是 |
| content_ops | 主題候補、content plan、知識、feedback | Missions |
| content_formula / own_post_formula | 公式 / 自家貼分析 | Publish / Missions |
| copy_draft | 文案草稿 | Missions |
| copy_mission | 舊文案任務實體 | **幾乎不用**（僅邊角耦合） |
| brand / placement_topic | 品牌與海巡主題 | Brands / Patrol |
| knowledge_graph | 知識圖譜 | Patrol |
| scan_post / outreach_draft | 掃描貼文與外展 | Patrol |
| publish_* | queue / guard / inventory / analytics / events | Publish / Dashboard |
| mention_inbox | 提及收件 | Publish |
| （已移除）crm_contact / publish_draft scaffold | 見 `docs/cleanup-log.md` | — |

業務重邏輯常在 `internal/library/`（`placement`、`viral`、`threadsapi`、`prompt`…），不是 `model/`。

---

## 8. 建議閱讀順序

1. 本文件 + `AGENTS.md` 核心原則  
2. `backend/gateway.go` → `internal/svc/service_context.go`（DI 全貌）  
3. `internal/handler/routes.go`（有哪些 API）  
4. 挑一條線跟到底，例如：  
   - 登入：`logic/auth` → `model/auth`  
   - 建 job：`logic/job` → `model/job/usecase` → Redis  
   - 海巡掃描：`logic/placement_topic` → worker `scan_placement.go`  
5. 前端：`web/src/App.tsx` → 某一頁 → `api/haixun.ts`  
6. Job 細節：`backend/docs/job-system-plan.md`

---

## 9. 常見陷阱

1. **路徑名**：repo 是 `backend/`，文件可能寫 `haixun-backend/`。  
2. **假成功**：歷史上部分 goctl stub 會 `return nil` → HTTP 200；清理後不應再有。  
3. **兩個 token**：會員 JWT ≠ AI provider key，header 用途不同。  
4. **worker 與 gateway**：gateway 不一定 claim job；少起 worker 時長任務會卡 queued。  
5. **inline workers**：本機 gateway 可能偷偷起 3 個 copy worker，prod compose 要自己對齊。  
6. **時間**：nano 不是毫秒；Node 端有時是 ms 精度假 ns。  
7. **DevHeaderFallback**：本機 yaml 可用 `X-Tenant-ID`/`X-UID` 跳過 JWT，prod 必須關。

---

## 10. 相關文件

| 文件 | 內容 |
|------|------|
| `docs/architecture.md` | 本導覽 |
| `docs/improvement-notes.md` | 前後端可改進處 |
| `docs/cleanup-log.md` | 已清除的死碼紀錄 |
| `docs/post-project-plan.md` | 文案流（Flow A）重做計劃 |
| `backend/docs/job-system-plan.md` | Job 系統設計 |
| `backend/docs/threads-automation-gap-plan.md` | 自動營運 gap（部分已落地） |
| `backend/README.md` | 後端 README / API 慣例 |
| `AGENTS.md` | Agent / 開發規範 |
