187 lines
8.6 KiB
Markdown
187 lines
8.6 KiB
Markdown
# External Integrations
|
|
|
|
**Analysis Date:** 2026-03-21
|
|
|
|
## APIs & External Services
|
|
|
|
**WeChat Mini Program:**
|
|
- Service: WeChat Mini Program (微信小程序)
|
|
- Purpose: User authentication, phone number retrieval, QR code generation, subscribe messages, short links, URL schemes, shipping queries
|
|
- SDK/Client: Custom HTTP client in `internal/pkg/wechat/` and `internal/pkg/miniprogram/`
|
|
- Key files: `internal/pkg/wechat/code2session.go`, `internal/pkg/wechat/phone_number.go`, `internal/pkg/wechat/decrypt.go`, `internal/pkg/wechat/qrcode.go`, `internal/pkg/miniprogram/access_token.go`, `internal/pkg/miniprogram/subscribe.go`
|
|
- Auth: `configs.Wechat.AppID` / `configs.Wechat.AppSecret` (config keys: `wechat.app_id`, `wechat.app_secret`)
|
|
- Template: `configs.Wechat.LotteryResultTemplateID` for subscribe messages
|
|
|
|
**WeChat Pay:**
|
|
- Service: WeChat Pay API v3 (微信支付)
|
|
- Purpose: Payment processing for game activities
|
|
- SDK/Client: `github.com/wechatpay-apiv3/wechatpay-go v0.2.21`
|
|
- Key files: `internal/pkg/pay/wechat.go`, `internal/pkg/pay/client.go`
|
|
- Auth: Merchant ID (`WECHAT_MCHID`), API v3 key (`WECHAT_API_V3_KEY`), serial number (`WECHAT_SERIAL_NO`), RSA private key (`WECHAT_PRIVATE_KEY_PATH`)
|
|
- Supports dynamic config override from `sysconfig` service (Base64 private key stored in DB)
|
|
- Notify URL: `WECHAT_NOTIFY_URL` (callback for payment results)
|
|
|
|
**Douyin (TikTok) / 抖店:**
|
|
- Service: Douyin Mini Program + 抖店 (TikTok Shop) API
|
|
- Purpose: User auth, order synchronization, product rewards, Douyin access token
|
|
- SDK/Client: Custom HTTP client in `internal/pkg/douyin/`
|
|
- Key files: `internal/pkg/douyin/access_token.go`, `internal/pkg/douyin/code2session.go`, `internal/pkg/douyin/phonenumber.go`
|
|
- External endpoint: `https://developer.toutiao.com/api/apps/v2/token`
|
|
- Auth: `configs.Douyin.AppID` / `configs.Douyin.AppSecret` (read from dynamic sysconfig at runtime)
|
|
- Background task: `douyinsvc.StartDouyinOrderSync()` runs scheduled order sync
|
|
|
|
**Aliyun SMS (阿里云短信):**
|
|
- Service: Alibaba Cloud Dysms (短信服务)
|
|
- Purpose: SMS verification code delivery
|
|
- SDK/Client: `github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.3` + `github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13`
|
|
- Key files: `internal/pkg/sms/aliyun.go`
|
|
- External endpoint: `dysmsapi.aliyuncs.com`
|
|
- Auth: `ALIYUN_SMS_ACCESS_KEY_ID` / `ALIYUN_SMS_ACCESS_KEY_SECRET`
|
|
- Config: `ALIYUN_SMS_SIGN_NAME`, `ALIYUN_SMS_TEMPLATE_CODE`
|
|
|
|
**Tencent COS (腾讯云对象存储):**
|
|
- Service: Tencent Cloud Object Storage
|
|
- Purpose: File uploads (images, game assets, user avatars)
|
|
- SDK/Client: `github.com/tencentyun/cos-go-sdk-v5 v0.7.37`
|
|
- Auth: `configs.COS.SecretID` / `configs.COS.SecretKey`
|
|
- Config: `configs.COS.Bucket` (e.g., `keaiya-1259195914`), `configs.COS.Region` (e.g., `ap-shanghai`), `configs.COS.BaseURL` (optional CDN URL)
|
|
|
|
## Data Storage
|
|
|
|
**Databases:**
|
|
- MySQL (primary)
|
|
- Connection: Read replica via `MYSQL_READ_ADDR` / `MYSQL_ADDR`; Write master via `MYSQL_WRITE_ADDR` / `MYSQL_ADDR`
|
|
- User: `MYSQL_USER`, Password: `MYSQL_PASS`, DB name: `MYSQL_NAME`
|
|
- Client: GORM v1.25.9 (`gorm.io/gorm`) with `gorm.io/driver/mysql v1.5.2`
|
|
- Pool: max 100 open connections, 5 idle, 2 min lifetime
|
|
- Read/write split: manual two-connection pattern (`GetDbR()` / `GetDbW()`) in `internal/repository/mysql/mysql.go`
|
|
- Generated DAOs: `internal/repository/mysql/dao/*.gen.go`
|
|
- Generated models: `internal/repository/mysql/model/*.gen.go`
|
|
- Do NOT edit `.gen.go` files directly
|
|
|
|
- SQLite (test only)
|
|
- Used in test helpers (`internal/repository/mysql/testrepo_sqlite.go`) for in-memory unit tests
|
|
- Driver: `gorm.io/driver/sqlite v1.4.3`
|
|
|
|
**File Storage:**
|
|
- Tencent COS - all uploaded files (see COS section above)
|
|
- Local filesystem for logs (`./logs/mini-chat-access.log`) with rotation via lumberjack
|
|
|
|
**Caching:**
|
|
- Redis (single-node)
|
|
- Connection: `REDIS_ADDR` (default in dev: `127.0.0.1:6379`), `REDIS_PASS`, DB index from `configs.Redis.DB`
|
|
- Client: `github.com/redis/go-redis/v9 v9.17.2`
|
|
- Singleton initialized in `internal/pkg/redis/redis.go` via `redis.Init()`
|
|
- Pool: 20 connections, dial timeout 5s, read/write timeout 3s
|
|
- Used for: activity settlement, task center worker, session management
|
|
- Test: `github.com/alicebob/miniredis/v2 v2.36.1` for in-memory Redis in tests
|
|
|
|
## Authentication & Identity
|
|
|
|
**Admin JWT:**
|
|
- Provider: Custom JWT (HS256)
|
|
- Implementation: `internal/pkg/jwtoken/jwtoken.go`
|
|
- Middleware: `internal/router/interceptor/admin_auth.go`
|
|
- Secret: `ADMIN_JWT_SECRET` env var (falls back to `configs.JWT.AdminSecret`)
|
|
- Token payload: `proposal.SessionUserInfo` (user ID, role, session info)
|
|
- Token verification: signature + user active + token hash match (prevents concurrent sessions)
|
|
|
|
**App User JWT (WeChat/Douyin users):**
|
|
- Provider: Custom JWT (HS256)
|
|
- Middleware: `internal/router/interceptor/app_auth.go`
|
|
- Secret: `configs.JWT.PatientSecret` (config key: `jwt.patient_secret`)
|
|
- Separate secret from admin tokens
|
|
|
|
**RBAC (Admin):**
|
|
- Implementation: `internal/router/interceptor/admin_rbac.go`
|
|
- Pattern: Role-based — `RequireAdminRole()` checks any role assigned; `RequireAdminAction(mark)` checks specific action permission
|
|
|
|
**Internal Service Auth:**
|
|
- Pattern: `X-Internal-Key` header check for internal API endpoints (`/api/internal/*`)
|
|
- Secret: `configs.Internal.ApiKey` (env: hardcoded fallback `bindbox-internal-secret-2024`)
|
|
- Used for Nakama game server communication
|
|
|
|
**Blacklist:**
|
|
- Implementation: `internal/router/interceptor/blacklist.go`
|
|
- Token blacklisting support (likely Redis-backed)
|
|
|
|
## Monitoring & Observability
|
|
|
|
**Distributed Tracing:**
|
|
- Service: OpenTelemetry (OTLP HTTP) — compatible with Grafana Tempo
|
|
- SDK: `go.opentelemetry.io/otel v1.39.0` + `otlptracehttp` exporter
|
|
- Implementation: `internal/pkg/otel/otel.go`, `internal/pkg/otel/middleware.go`
|
|
- Config: `configs.Otel.Enabled` (bool), `configs.Otel.Endpoint` (e.g., `tempo:4318`)
|
|
- Middleware applied in `internal/router/router.go` when enabled
|
|
- Gin middleware traces all HTTP requests
|
|
|
|
**Metrics:**
|
|
- Service: Prometheus
|
|
- SDK: `github.com/prometheus/client_golang v1.17.0`
|
|
- Implementation: `internal/metrics/` package (referenced in proposal)
|
|
|
|
**Logging:**
|
|
- Framework: Uber Zap `go.uber.org/zap v1.26.0`
|
|
- Custom wrapper: `internal/pkg/logger/logger.go`
|
|
- File rotation: `gopkg.in/natefinch/lumberjack.v2 v2.2.1`
|
|
- Log file: `./logs/mini-chat-access.log`
|
|
- Log levels: debug, info, warn, error, fatal
|
|
|
|
**Profiling:**
|
|
- pprof endpoint enabled in dev via `github.com/gin-contrib/pprof v1.4.0`
|
|
- Enabled in router: `core.WithEnablePProf()`
|
|
|
|
**Error Tracking:**
|
|
- Custom alert handler: `internal/alert/` package
|
|
- Registered via `core.WithAlertNotify(alert.NotifyHandler())` in router
|
|
|
|
## CI/CD & Deployment
|
|
|
|
**Containerization:**
|
|
- Docker multi-stage build: `Dockerfile`
|
|
- Build image: `golang:1.24-alpine`
|
|
- Runtime image: `alpine:latest`
|
|
- Port: `9991`
|
|
- Health check: `GET http://localhost:9991/system/health`
|
|
- Example image: `zfc931912343/bindbox-game:v1.10`
|
|
|
|
**Build Targets:**
|
|
- Linux (amd64): `make build-linux` → binary `bindboxgame_api`
|
|
- macOS: `make build-mac`
|
|
- Windows: `make build-win` → `bindboxgame_api.exe`
|
|
|
|
**CI Pipeline:**
|
|
- Not detected in codebase (no GitHub Actions / CI config files found)
|
|
|
|
## Environment Configuration
|
|
|
|
**Required env vars (production):**
|
|
- `ENV` — Environment selector (`dev`/`fat`/`uat`/`pro`)
|
|
- `MYSQL_ADDR` or `MYSQL_READ_ADDR` + `MYSQL_WRITE_ADDR`
|
|
- `MYSQL_USER`, `MYSQL_PASS`, `MYSQL_NAME`
|
|
- `REDIS_ADDR`, `REDIS_PASS`
|
|
- `WECHAT_MCHID`, `WECHAT_SERIAL_NO`, `WECHAT_API_V3_KEY`, `WECHAT_PRIVATE_KEY_PATH`, `WECHAT_NOTIFY_URL`
|
|
- `ALIYUN_SMS_ACCESS_KEY_ID`, `ALIYUN_SMS_ACCESS_KEY_SECRET`, `ALIYUN_SMS_SIGN_NAME`, `ALIYUN_SMS_TEMPLATE_CODE`
|
|
- `ADMIN_JWT_SECRET`
|
|
|
|
**Secrets location:**
|
|
- Primary: TOML config files embedded in binary (`configs/*.toml`) — note dev TOML contains real credentials (security concern)
|
|
- Override: Environment variables at runtime (preferred for production)
|
|
- WeChat Pay private key: file path or Base64 in `sysconfig` DB table (dynamic config)
|
|
|
|
## Webhooks & Callbacks
|
|
|
|
**Incoming:**
|
|
- WeChat Pay payment notification: `configs.WechatPay.NotifyURL` (`WECHAT_NOTIFY_URL`) — called by WeChat servers to deliver payment results; handled in `internal/api/pay/` package
|
|
- Douyin order notification: `configs.Douyin.NotifyURL` — callback for Douyin order events
|
|
|
|
**Outgoing:**
|
|
- Douyin access token refresh: `POST https://developer.toutiao.com/api/apps/v2/token`
|
|
- Aliyun SMS send: `POST https://dysmsapi.aliyuncs.com`
|
|
- WeChat API calls: Various WeChat Mini Program endpoints for auth, phone, subscribe messages
|
|
- Tencent COS: Object upload/download operations
|
|
|
|
---
|
|
|
|
*Integration audit: 2026-03-21*
|