template-monorepo/etc/README.md

238 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# gateway.yaml 設定說明
Gateway 使用 [go-zero `conf`](https://go-zero.dev/docs/tutorials/go-zero/configuration/overview) 載入 YAML。結構定義在 `internal/config/config.go`,對應各模組的 `Conf` 結構。
## 用哪個檔案?
| 檔案 | 用途 | 啟動方式 |
|------|------|----------|
| **`gateway.yaml`** | 預設:不需 Docker僅 HTTP / health | `make run` |
| **`gateway.dev.yaml`** | 本機完整功能Mongo + Redis + Notification | `make deps-up``make run-dev` |
```bash
# 僅 API最快
make run
# Notification / Member OTP需 Docker
make deps-up
make mongo-index # 首次建議執行
make run-dev
```
---
## go-zero 填寫規則(重要)
1. **欄位名稱必須與 Go struct 一致**(駝峰在 yaml 裡通常照抄,如 `MaxPoolSize`)。**不要**填 struct 裡沒有的欄位(例如以前的 `MaxStaleness`),否則可能觸發奇怪錯誤。
2. **沒標 `optional` 的頂層欄位**:在該區塊出現時需型別正確;我們已在 Mongo / Notification / Member 加上 `json:",optional"`,多數子欄位可省略。
3. **空字串 `""`**:可寫,表示無帳密 / 無 AuthSource。
4. **時間**`30m`、`10s``time.Duration`)。
5. **字串陣列**(如 `Compressors`)必須是 YAML 列表,**不能**寫成單一字串:
```yaml
Compressors:
- zstd
- snappy
```
6. **Mongo 埠號**:用整數 `Port: 27017`,不要 `Port: "27017"`;或直接在 `Host``127.0.0.1:27017`
---
## 頂層HTTP 服務(`rest.RestConf`
| 欄位 | 必填 | 說明 | 範例 |
|------|:----:|------|------|
| `Name` | ✓ | 服務名稱 | `gateway` |
| `Host` | ✓ | 監聽位址 | `0.0.0.0` |
| `Port` | ✓ | HTTP 埠 | `8888` |
其餘 `RestConf` 欄位(`Timeout`、`Log`、`Prometheus` 等)可省略,使用 go-zero 預設。
---
## `Mongo``internal/library/mongo.Conf`
**`Host` 留空或整段註解** → 不連 Mongo`Notifier` / `MemberVerification` 不會注入(仍可跑 health API
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|------|:----:|------|----------------|
| `Schema` | 選 | 連線 scheme預設 `mongodb` | `mongodb` |
| `Host` | 啟用時 ✓ | 主機;可含埠 `127.0.0.1:27017` | `127.0.0.1` |
| `Port` | 選 | `Host` 無埠時附加,**整數** | `27017` |
| `Database` | 啟用時 ✓ | 資料庫名 | `gateway`(與 docker init 一致) |
| `User` | 選 | 帳號 | 本機留空 |
| `Password` | 選 | 密碼 | 本機留空 |
| `AuthSource` | 選 | 驗證用 DB帳號在 `admin` 建則填 `admin` | 本機留空 |
| `ReplicaName` | 選 | replica set 名稱 | 本機單機**留空** |
| `TLS` | 選 | 是否 `tls=true` | `false` |
| `MaxPoolSize` | 選 | 連線池上限 | `30` |
| `MinPoolSize` | 選 | 連線池下限 | `10` |
| `MaxConnIdleTime` | 選 | 閒置連線逾時 | `30m` |
| `Compressors` | 選 | 壓縮演算法陣列 | 省略(程式預設 zstd、snappy |
| `ConnectTimeoutMs` | 選 | 啟動 Ping 逾時(毫秒) | 省略(預設 10s |
**會建立的 collections**(自動,無需手動建表):`notifications`、`notification_dlq`。索引:`make mongo-index` 或 docker init。
**常見錯誤**
| 錯誤訊息 | 原因 |
|----------|------|
| `type mismatch for field "Mongo.Compressors"` | 曾用不存在的 `Port: "27017"``Compressors` 寫成單一字串 |
| `field "Mongo.xxx" is not set` | 舊版未加 `optional`;請更新程式或改用最精簡的 `gateway.dev.yaml` |
| `mongo: ping primary` 失敗 | 有填 `Mongo.Host` 但沒跑 `make deps-up` |
---
## `Redis`go-zero `redis.RedisConf`
**`Host` 留空**`gateway.yaml` 預設)→ 不連 Redis。有 Mongo 時仍可用 memory 冪等/配額,但**無異步重試 worker**、**無 Member OTP**。
`gateway.yaml` 建議保留區塊並設空 Host
```yaml
Redis:
Host: ""
Type: node
```
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|------|:----:|------|----------------|
| `Host` | 啟用時 ✓ | `host:port` | `localhost:6379` |
| `Type` | 啟用時 ✓ | 單機填 `node` | `node` |
| `Pass` | 選 | 密碼 | 省略 |
| `Tls` | 選 | TLS | 省略 |
---
## `Notification``internal/model/notification/config`
僅在 **Mongo 已連線** 時由 `ServiceContext` 組裝 Notifier。子欄位皆可省略有程式預設
### 根層
| 欄位 | 說明 | 預設 / 建議 |
|------|------|-------------|
| `DefaultLocale` | 模板語系 fallback | `zh-tw` |
| `RatePerTenant.Email` | 每租戶每日 Email 上限 | `100` |
| `RatePerTenant.SMS` | 每租戶每日 SMS 上限 | `50` |
### `Notification.Email`
| 欄位 | 說明 |
|------|------|
| `Provider` | 無真實 provider 時填 `mock` |
| `From` | 寄件者Send 時帶入) |
| `APIKey` | 保留,目前未用 |
**SMTP**`Enable: true` 時加入發信鏈,依 `Sort` failover
| 欄位 | 說明 |
|------|------|
| `Enable` / `Sort` | 是否啟用、優先順序(數字小先試) |
| `Host` / `Port` | SMTP 主機與埠MailHog`localhost:1025` |
| `Username` / `Password` | 認證 |
**SES**AWS
| 欄位 | 說明 |
|------|------|
| `Enable` / `Sort` | 同上 |
| `Region` / `AccessKey` / `SecretKey` / `SessionToken` | AWS 憑證 |
### `Notification.SMS`
| 欄位 | 說明 |
|------|------|
| `Provider` | 無真實 provider 時 `mock` |
| `Mitake.Enable` | 三竹簡訊 |
| `Mitake.User` / `Mitake.Password` | 三竹帳密 |
| `Mitake.Sort` | failover 順序 |
### `Notification.Async`
| 欄位 | 說明 |
|------|------|
| `QueueRedisKey` | Redis ZSET key空則用內建 `notif:retry:zset` |
| `Worker` | 背景重試 goroutine 數 |
| `MaxRetry` | 最大重試次數 |
| `BackoffSeconds` | 重試間隔(秒)陣列 |
**Mongo + Redis** 才會啟動 `RetryWorker`
### `Notification.Push` / `Webhook`
保留欄位,目前未接線。
---
## `Member``internal/model/member/config`
僅在 **Mongo + Redis + Notifier** 皆就緒時注入 `MemberVerification`
### `Member.OTP`
| 欄位 | 說明 | 建議 |
|------|------|------|
| `Length` | OTP 位數 | `6` |
| `TTLSeconds` | challenge 存活秒數 | `300` |
| `MaxAttempts` | 驗證嘗試上限 | `5` |
| `ResendCooldownSeconds` | 重發冷卻 | `60` |
| `DailyVerifyLimit` | 每日驗證上限 | `10` |
---
## 功能與依賴對照
```mermaid
flowchart LR
subgraph always [永遠可用]
H[health API]
end
subgraph mongo [Mongo.Host 有值]
N[Notifier Send/Get]
A[Admin DLQ]
end
subgraph redis [Redis.Host 有值]
Q[Enqueue + RetryWorker]
O[Member OTP]
end
H --> always
mongo --> N
mongo --> A
mongo --> redis
redis --> Q
redis --> O
```
| 你想用的功能 | Mongo | Redis |
|--------------|:-----:|:-----:|
| `/api/v1/health` | — | — |
| `Notifier.Send`(同步) | ✓ | 選(冪等/配額建議開) |
| `Notifier.Enqueue` + 重試 | ✓ | ✓ |
| Member 信箱/手機驗證 | ✓ | ✓ |
---
## 疑難排解
```bash
# 1. 只驗證 yaml 能否載入(不啟動服務)
go test ./internal/config/ -run TestLoadGatewayYAML -v
# 2. 看缺什麼欄位(啟動時)
go run gateway.go -f etc/gateway.yaml
# 3. dev 完整栈
make deps-up && make run-dev
curl -s http://127.0.0.1:8888/api/v1/health
```
若你改壞了 yaml可從 repo 內的 `gateway.yaml` / `gateway.dev.yaml` 重新複製,再依本文件逐段打開需要的區塊。
---
## 相關文件
- [deploy/README.md](../deploy/README.md) — Docker Compose
- [internal/model/notification/README.md](../internal/model/notification/README.md) — 通知模組
- [internal/library/mongo/README.md](../internal/library/mongo/README.md) — Mongo 存取層