thread-master/apps/backend
王性驊 e41c1f96a2 fix frontend 2026-07-13 01:15:30 +00:00
..
cmd/worker fix frontend 2026-07-13 01:15:30 +00:00
etc fix frontend 2026-07-13 01:15:30 +00:00
generate fix frontend 2026-07-13 01:15:30 +00:00
internal fix frontend 2026-07-13 01:15:30 +00:00
scripts/threads-profile fix frontend 2026-07-13 01:15:30 +00:00
.gitignore fix frontend 2026-07-10 12:54:45 +00:00
MIGRATION.md fix frontend 2026-07-10 12:54:45 +00:00
Makefile fix frontend 2026-07-13 01:15:30 +00:00
README.md fix frontend 2026-07-10 12:54:45 +00:00
gateway.go fix frontend 2026-07-13 01:15:30 +00:00
go.mod fix frontend 2026-07-10 12:54:45 +00:00
go.sum fix frontend 2026-07-10 12:54:45 +00:00

README.md

apps/backend

Harbor Desk Phase Cgo-zero

原則

不做
generate/api + make gen-api 手寫 handlerroutes
generate/database/mongo + make migrate-up cmd/initcmd/seeder 程式遷移
monc + CacheRedis 自己半套 mongo cache
internal/logic + `module/*/domain repository

指令

cd apps/backend
make build       # gateway + worker
make test
make gen-api     # 改 .api 後
make migrate-up  # 改 generate/database 後
make tidy
# 需要 Mongo + Redisgo-zero monc / redis
# Mongo 若有帳密(本機 infra 常見),一定要帶進 URI
export MONGO_URI='mongodb://USER:PASS@127.0.0.1:27017/?authSource=admin'
export MONGO_URL="$MONGO_URI"   # migrate 用
make migrate-up
go run . -f etc/gateway.yaml
# admin@haixun.local / admin123seeduid=1000000 → 顯示 01000000

日誌與密碼(安全)

禁止出現在 log 說明
password / new_password / current_password / temporary_password 明碼
password_hash bcrypt 也不可打 log
access/refresh token、api_key 憑證

實作:

  • 啟動時 securelog.SilenceMongo() → 關閉 go-zero mon 文件 dump否則 ReplaceOne 會印出整份 member
  • RestConf.Verbose = false → 不印 request body
  • 自寫 log 請用 securelog.RedactAny(v) / 勿 logx.Infof("%+v", req)

HTTP access log 只記 method/path/status/duration不含 body。

物件儲存(頭像)— 僅 MinIO/S3

不落本機磁碟(無 localstore / /files)。未設定 Endpoint 時 upload 直接失敗。

項目 說明
API POST /api/v1/media/upload(需 JWT{ content: dataURL, kind: "avatar" }
回傳 { url, key } — Mongo member 只存 url
後端 MinIOdev或 S3prodS3 API + path-style
env HAIXUN_STORAGE_S3_*MINIO_ROOT_USER / MINIO_ROOT_PASSWORD
ObjectStorage:
  Endpoint: "http://127.0.0.1:9000"   # 必填
  Bucket: "haixun-assets"
  AccessKey: "haixun"
  SecretKey: "..."
  UsePathStyle: true
  PublicBaseURL: ""                   # 或 CDN / 反向代理公開前綴

FE選頭像 → upload → URL → PATCH profile(禁止 data URL

密碼政策(前後端一致)

規則 說明
長度 ≥ 12 字元
組成 大寫 + 小寫 + 數字 + 符號 皆須至少一個
後端 ValidatePasswordPolicy → 不符回 400003 + domain.PasswordPolicyEN
前端 passwordPolicy.ts + 語言包 password.policy.hint / api.err.400003

同一句說明:

  • EN: Password must be at least 12 characters with upper, lower, digit, and symbol
  • ZH: 密碼須至少 12 碼,且含大寫、小寫、數字與符號

前端依 code 400003 顯示語系文案placeholderhint錯誤都用同一 key勿另寫一句。

寄信(信箱驗證 / 重設密碼)

業務在 internal/logic/auth/*:產碼 → Notification.RenderVerifySendEmail
寄送實作在 internal/module/notificationSMTPMailgun 相容)。

模板與多語

  • 引擎與 stand-alone 相同:hermesgithub.com/matcornic/hermes/v2
  • 語系:zh-TW(預設)/en;來源為會員 preferred_language,忘記密碼則用請求 languageFE 當前 locale
  • LogoBrand.LogoURL 或預設 {PublicWebBase}/brand-mark.jpgapps/web/public/brand-mark.jpg
PublicWebBase: "http://127.0.0.1:5173"
Brand:
  Name: "Harbor Desk"
  LogoURL: ""   # 空 = PublicWebBase/brand-mark.jpg
  Copyright: "© Harbor Desk"

本機Mailpit推薦

# 已含在 old/infra docker-composemongo/redis/mailpit
cd old/infra && docker compose --env-file ../deploy/.env.dev up -d mailpit

# UI 看信
open http://127.0.0.1:8025
項目
SMTP 127.0.0.1:1025(無密碼也可;可開 AUTH accept-any 模擬 Mailgun
Web UI http://127.0.0.1:8025
gateway 預設 Mail.SMTP.Host=127.0.0.1 Port=1025

呼叫 POST /api/v1/auth/email/send-codepassword/request-reset 後,到 Mailpit UI 看 HTML 信。

正式Mailgun SMTP

Mail:
  Sender: "Harbor Desk <noreply@your-domain.com>"
  SMTP:
    Host: "smtp.mailgun.org"
    Port: 587
    User: "postmaster@YOUR_DOMAIN"
    Password: "<Mailgun SMTP password>"
  DevExposeCode: false

同一套 Mail.SMTP 設定;本機指 Mailpit、上線指 Mailguncode 不用改

env 覆寫:MAIL_SMTP_*HAIXUN_SMTP_*(與 old/deploy/.env.dev 相容)。

SMTP Host 行為
log-only不真寄
Mailpit / Mailgun 真走 SMTP 投遞

前後端串不起來?檢查這幾項

  1. gateway 有在跑 ss -tlnp | grep 8888;沒有就 go run . -f etc/gateway.yaml
  2. Mongo URI 有帳密export MONGO_URI=...;沒帶會查不到 seed
  3. Redis 有密碼export REDIS_PASSWORD=...;沒帶 monc 回 NOAUTH → API 500
  4. 已跑 migratemake migrate-upseed admin@haixun.local
  5. FE 切到 live:設定 → 資料來源 → Live預設是 mock,根本不會打後端)
  6. API baseapps/web/.env 建議 VITE_API_BASE=(空),走 Vite proxy /api:8888
    遠端開 *.30cm.net不要寫死 http://127.0.0.1:8888(那會打到使用者自己電腦)
  7. 切 live 後重新登入 seedadmin@haixun.local / admin123
資料 存哪 關機
會員 / settings Mongomonc 保留
refresh token / 驗證碼 MongoTTL index 保留(過期自動清)
monc 實體快取 RedisCacheRedis 可丟,會從 Mongo 回填

目錄

generate/api/           # goctl 契約
generate/database/mongo # golang-migrate JSON
generate/goctl/         # handler 模板102000
cmd/worker/             # 獨立 worker
internal/handler|logic  # goctl 產 / 薄邏輯
internal/module/        # domain · repository · usecase
internal/lib/mongo      # monc URI 小工具
etc/gateway.yaml        # 唯一設定

設定摘要

CacheRedis:           # monc Redis 快取
  - Host: 127.0.0.1:6379
    Type: node
Mongo:
  URI: "mongodb://127.0.0.1:27017"   # 有 auth 用 MONGO_URI 覆寫
  Database: "haixun"

會員 uid

  • 1_000_000seed admin = 1000000
  • 顯示補成 8 位01000000%08d / FE padStart(8,"0")
  • 新註冊:1000001, 1000002, …