277 lines
11 KiB
Markdown
277 lines
11 KiB
Markdown
|
|
# 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 / 開發規範 |
|