bindbox-game/CLAUDE.md
2026-03-21 16:37:24 +08:00

567 lines
25 KiB
Markdown
Executable File
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.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Bindbox Game is a Go-based web application built with Gin framework for managing game activities, products, and user interactions. The project includes an admin panel (Vue 3) and integrates with WeChat Mini Program, WeChat Pay, Tencent COS, Douyin (TikTok), and Aliyun SMS services.
**Module Name**: `bindbox-game` (as defined in go.mod)
**Note**: This is part of a multi-project repository. Other related projects include `bindbox-mini`, `douyin_game`, and `game`. This CLAUDE.md file focuses on the `bindbox_game` directory.
## Development Commands
**Working Directory**: Always work in `/path/to/bindbox/bindbox_game/` directory. This is part of a monorepo that includes other projects (`bindbox-mini`, `douyin_game`, `game`).
### Backend (Go)
```bash
# Run tests
make test # Run all tests
go test -v ./internal/service/... # Test specific package
go test -v -run TestFunctionName ./... # Run single test
# Format code
make fmt # Format all Go files
go run cmd/mfmt/main.go # Format with import grouping
# Run linter
make lint
# Build for different platforms
make build-win # Windows executable
make build-mac # MacOS executable
make build-linux # Linux executable
# Start the application
go run main.go # Development mode
ENV=dev go run main.go # Explicit environment
ENV=pro go run main.go # Production mode
# Generate Swagger documentation
make gen-swagger
# Serve Swagger UI locally
make serve-swagger # Opens at http://localhost:36666
```
### Frontend (Vue 3 Admin Panel)
```bash
cd web/admin
# Install dependencies
pnpm install
# Start dev server (usually runs on http://localhost:5173)
pnpm dev
# Build for production
pnpm build
# Preview production build
pnpm preview
# Lint and fix
pnpm fix
# Format code
pnpm lint:prettier
# Type check
pnpm type-check
```
### Database
```bash
# Run code generation for GORM models
go run cmd/gormgen/main.go
# Migrations are in migrations/ directory (SQL files)
# Apply them manually to your database
# Format Go code with import grouping (standard library, local module, third-party)
go run cmd/mfmt/main.go
```
### Docker
```bash
# Build docker image
docker build -t zfc931912343/bindbox-game:v1.10 .
# Run with docker
docker run -d --name bindbox-game -p 9991:9991 zfc931912343/bindbox-game:v1.10
```
## Architecture
### Backend Structure
The backend follows a layered architecture pattern:
- **`main.go`**: Application entry point. Initializes config, OpenTelemetry, MySQL, Redis, logger, HTTP server, and background tasks (scheduled settlement, order sync, expiration checks).
- **`configs/`**: Configuration management using Viper. Environment-specific TOML files (dev, fat, uat, pro). Configuration includes MySQL (read/write), Redis, JWT secrets, WeChat, WeChat Pay, Tencent COS, Aliyun SMS, Douyin integration, and OpenTelemetry settings.
- **`internal/api/`**: HTTP request handlers organized by domain (admin, user, game, activity, pay, wechat, etc.). Handlers parse requests, call services, and return responses.
- **`internal/service/`**: Business logic layer. Services contain domain logic and orchestrate repository calls. Key services: admin, user, game, activity, title, order, banner, sysconfig, douyin, task_center.
- **`internal/repository/mysql/`**: Data access layer using GORM. Contains generated DAO and model files (via gormgen). Supports read/write splitting with master-slave database configuration.
- **`internal/router/`**: HTTP routing setup with Gin. Defines routes and applies middleware/interceptors.
- **`internal/router/interceptor/`**: Middleware for authentication and authorization:
- `admin_auth.go`: JWT token verification for admin users
- `admin_rbac.go`: Role-based access control (RBAC) checking for admin actions
- **`internal/pkg/`**: Shared utilities and helpers:
- `core/`: Custom Gin context wrapper with enhanced features (trace, logger, session info)
- `logger/`: Custom logger implementation (Zap-based) with file rotation
- `jwtoken/`: JWT token generation and parsing
- `redis/`: Redis client initialization and management
- `otel/`: OpenTelemetry integration for distributed tracing
- `wechat/`: WeChat Mini Program integration (phone number, decryption)
- `miniprogram/`: WeChat Mini Program access token and subscribe message
- Other utilities: validation, httpclient, timeutil, idgen, errors, etc.
- **`internal/proposal/`**: Shared types and interfaces (session info, metrics, alerts, request logging).
- **`internal/code/`**: Error code definitions for API responses. Follows a 5-digit pattern: `[service level (1)][module level (2)][specific error (2)]`. Example: `10101` = service error (1) + user module (01) + invalid phone (01).
- **`cmd/`**: Command-line tools:
- `gormgen/`: Code generator for GORM models and DAOs from database schema
- `mfmt/`: Code formatter that organizes imports into three groups (standard library, local module, third-party packages)
- `diagnose_ledger/`: Diagnostic tool for ledger operations
### Frontend Structure (Vue 3 Admin Panel)
Located in `web/admin/`:
- Vue 3 + TypeScript + Vite
- Element Plus UI framework
- Pinia for state management
- Vue Router for navigation
- Axios for HTTP requests
- Tailwind CSS for styling
### Database
- MySQL with master-slave (read-write splitting) support
- GORM ORM with code generation (`gormgen`)
- Migrations in `migrations/` directory (SQL files with date prefixes)
- Generated models and DAOs in `internal/repository/mysql/`
### Authentication & Authorization
- **Admin JWT**: Separate secret for admin users. Token includes user ID, role, and session info. Token verification checks:
1. JWT signature validity
2. User exists and is active
3. Token hash matches stored hash (prevents concurrent sessions)
4. User login status is enabled
- **RBAC**: Role-based access control for admin users. Two middleware patterns:
- `RequireAdminRole()`: Checks if user has any role assigned
- `RequireAdminAction(mark)`: Checks if user's roles have permission for specific action mark
### Background Tasks
Scheduled tasks initialized in `main.go`:
- **Activity Settlement**: `activitysvc.StartScheduledSettlement()` - handles scheduled activity settlements
- **User Expiration Check**: `usersvc.StartExpirationCheck()` - checks and handles user data expirations
- **Douyin Order Sync**: `douyinsvc.StartDouyinOrderSync()` - syncs orders from Douyin platform
- **Dynamic Config**: `syscfgsvc.InitGlobalDynamicConfig()` - loads dynamic system configuration
### External Integrations
- **WeChat Mini Program**: User authentication, phone number retrieval, subscribe messages
- **WeChat Pay**: Payment processing (API v3)
- **Tencent COS**: Object storage for file uploads
- **Aliyun SMS**: SMS notifications
- **Douyin (TikTok)**: Order synchronization and product rewards
- **OpenTelemetry**: Distributed tracing and observability
## Testing
- Tests located alongside source files (e.g., `foo_test.go` next to `foo.go`)
- Run all tests: `make test` or `go test -v --cover ./internal/...`
- Uses `testify` for assertions
- Some tests use `go-sqlmock` for database mocking
- Test database support: In-memory SQLite via `testrepo_sqlite.go`
## Configuration
Configuration is managed by environment via TOML files:
- `dev_configs.toml`: Development
- `fat_configs.toml`: Feature testing
- `uat_configs.toml`: User acceptance testing
- `pro_configs.toml`: Production
Set environment with `ENV` environment variable (defaults to `dev`).
JWT secrets can be overridden with environment variables:
- `ADMIN_JWT_SECRET`: Overrides admin JWT secret from config
## API Documentation
- Swagger annotations in code (see `main.go` for base config)
- Generate: `make gen-swagger`
- View locally: `make serve-swagger` (http://localhost:36666)
- Production: http://127.0.0.1:9991/swagger/index.html (when running)
- Health check: http://127.0.0.1:9991/system/health
## Code Generation
### GORM Models
Run `cmd/gormgen/main.go` to generate GORM models and DAOs from database schema:
```bash
go run cmd/gormgen/main.go
```
This generates:
- `internal/repository/mysql/model/*.gen.go`: Model structs
- `internal/repository/mysql/dao/*.gen.go`: DAO query builders
Do not manually edit `.gen.go` files - they will be overwritten on next generation.
## Important Patterns
### Custom Context
The codebase uses `core.Context` (wrapper around `gin.Context`) throughout handlers. This provides:
- Enhanced request/response handling
- Integrated tracing and logging
- Session user info management
- Standardized error handling via `AbortWithError()`
Always use `core.Context` in handlers, not `gin.Context` directly.
### Error Handling
Use `core.Error()` to create business errors with HTTP status code, error code, and message:
```go
err := core.Error(http.StatusBadRequest, code.ParamBindError, "Invalid parameters")
ctx.AbortWithError(err)
```
Error codes defined in `internal/code/`.
### Response Patterns
Successful responses use `ctx.Payload(data)` to set response data. The framework handles JSON serialization and wrapping.
### Service Layer Pattern
Services are initialized with logger and database repository:
```go
svc := service.New(logger, dbRepo)
```
Services should contain business logic and call DAOs for data access. Keep handlers thin - move logic to services.
## Working with This Codebase
1. **Adding new API endpoints**: Create handler in appropriate `internal/api/` subdirectory, register route in `internal/router/`, and add business logic in corresponding service.
2. **Database changes**: Create SQL migration file in `migrations/` with date prefix (e.g., `20260207_description.sql`), then regenerate GORM models with `go run cmd/gormgen/main.go`.
3. **Adding dependencies**: Use `go get` for backend packages, `pnpm add` for frontend packages (in `web/admin/`).
4. **Debugging**: Check logs in `logs/` directory. Enable debug logging in logger initialization (see `main.go`).
5. **Environment-specific config**: Modify appropriate TOML file in `configs/` directory based on target environment.
6. **Code formatting**: After making changes, run `make fmt` to format code. For import organization, use `go run cmd/mfmt/main.go` to group imports properly.
7. **Error codes**: When defining new error codes in `internal/code/`, follow the 5-digit pattern: service level (1) + module level (2) + specific error (2). Service level: 1=system error, 2=user error.
## Common Issues \u0026 Troubleshooting
- **Port already in use**: Default port is 9991. Check if another instance is running: `lsof -i :9991`
- **Database connection errors**: Verify MySQL is running and credentials in `configs/` are correct
- **Redis connection errors**: Ensure Redis is running on configured host/port
- **GORM generation fails**: Check database connectivity and ensure `cmd/gormgen/main.go` has correct DB credentials
- **Frontend build errors**: Clear node_modules and reinstall: `cd web/admin && rm -rf node_modules && pnpm install`
- **JWT token issues**: If admin tokens are invalid, check `ADMIN_JWT_SECRET` environment variable matches config
<!-- GSD:project-start source:PROJECT.md -->
## Project
**Bindbox Game 盈亏统计函数**
为 Bindbox Game 平台新增两个 Service 层通用盈亏统计函数,支持按用户维度和活动维度查询平台盈亏情况。函数接收资产类型、维度 ID、时间范围等参数返回汇总数据和按资产类型拆分的明细。
**Core Value:** 提供可复用的盈亏统计方法,使平台运营能从用户和活动两个维度快速了解各类资产的收支状况。
### Constraints
- **Tech Stack**: Go, GORM, MySQL — 遵循现有项目架构
- **Performance**: 统计查询走从库 (DbR),避免影响写库性能
- **Compatibility**: 新函数放在 `internal/service/finance/` 下,不修改现有接口
<!-- GSD:project-end -->
<!-- GSD:stack-start source:codebase/STACK.md -->
## Technology Stack
## Languages
- Go 1.24.0 - Backend server, all business logic, API handlers
- TypeScript ~5.6.3 - Frontend admin panel (`web/admin/src/`)
- SQL - Database migrations (`migrations/` directory)
- TOML - Configuration files (`configs/*.toml`)
- SCSS - Frontend styles (`web/admin/src/assets/styles/`)
## Runtime
- Go runtime 1.24.0 (toolchain go1.24.2)
- Docker: `golang:1.24-alpine` build stage, `alpine:latest` final stage
- Node.js >= 18.0.0
- Go modules (`go.mod` / `go.sum`) - lockfile present
- pnpm >= 8.8.0 - frontend (`web/admin/pnpm-lock.yaml`) - lockfile present
## Frameworks
- `github.com/gin-gonic/gin v1.9.1` - HTTP web framework
- `gorm.io/gorm v1.25.9` - ORM for MySQL
- `gorm.io/gen v0.3.26` - GORM code generation from schema
- `gorm.io/plugin/dbresolver v1.5.0` - Read/write split support
- Vue 3 `^3.5.21` - UI framework (`web/admin/src/`)
- Vite `^5.4.10` - Build tool and dev server
- Element Plus `^2.11.2` - UI component library
- Pinia `^3.0.3` - State management
- Vue Router `^4.5.1` - Client-side routing
- Tailwind CSS `^4.1.14` - Utility-first CSS
- `github.com/stretchr/testify v1.11.1` - Assertions
- `github.com/DATA-DOG/go-sqlmock v1.5.2` - MySQL mock
- `github.com/alicebob/miniredis/v2 v2.36.1` - In-memory Redis for tests
- `gorm.io/driver/sqlite v1.4.3` - SQLite for in-memory test DB (`internal/repository/mysql/testrepo_sqlite.go`)
- Vitest `^1.0.0` - Unit test runner
- `@vue/test-utils ^2.4.0` - Vue component testing
- Makefile - Task runner (`Makefile`)
- `golangci-lint` - Linter (install via `make tools`)
- `go-swagger` - Swagger generation (install via `make tools`)
- `cmd/mfmt/main.go` - Custom import formatter (groups: stdlib, local, third-party)
- `cmd/gormgen/main.go` - GORM model/DAO code generator
- ESLint `^9.9.1` + TypeScript ESLint `^8.3.0` - Linting
- Prettier `^3.5.3` - Code formatting
- Stylelint `^16.20.0` - CSS/SCSS linting
- Husky `^9.1.5` + lint-staged - Pre-commit hooks
- Terser `^5.36.0` - Minification
- `vite-plugin-compression ^0.5.1` - Gzip compression for production
## Key Dependencies
- `github.com/spf13/viper v1.17.0` - Configuration management (TOML, env var overrides)
- `go.uber.org/zap v1.26.0` - Structured logging
- `gopkg.in/natefinch/lumberjack.v2 v2.2.1` - Log file rotation
- `github.com/golang-jwt/jwt/v5 v5.2.0` - JWT auth tokens
- `github.com/redis/go-redis/v9 v9.17.2` - Redis client (singleton)
- `github.com/go-sql-driver/mysql v1.7.1` - MySQL driver
- `github.com/bytedance/sonic v1.13.2` - High-performance JSON encoder/decoder
- `github.com/bwmarrin/snowflake v0.3.0` - Distributed ID generation
- `github.com/go-resty/resty/v2 v2.10.0` - HTTP client for external API calls
- `github.com/prometheus/client_golang v1.17.0` - Prometheus metrics
- `golang.org/x/crypto v0.44.0` - Cryptographic utilities
- Axios `^1.12.2` - HTTP client for API calls
- Echarts `^6.0.0` - Charts and data visualization
- `@vueuse/core ^13.9.0` - Vue composition utilities
- `pinia-plugin-persistedstate ^4.3.0` - Persistent state storage
- `dayjs ^1.11.19` - Date/time manipulation
- `crypto-js ^4.2.0` - Client-side cryptography
- `xlsx ^0.18.5` - Excel file generation/parsing
- `@wangeditor/editor ^5.1.23` - Rich text editor
- `go.opentelemetry.io/otel v1.39.0` - Distributed tracing (OTLP HTTP exporter)
- `github.com/gin-contrib/pprof v1.4.0` - Go profiling endpoint
- `github.com/swaggo/gin-swagger v1.6.0` - Swagger UI embedded in Gin
- `github.com/tealeg/xlsx v1.0.5` - Excel file generation (server-side)
- `github.com/rs/cors/wrapper/gin v0.0.0-20231013084403-73f81b45a644` - CORS middleware
## Configuration
- Set via `ENV` environment variable: `dev` | `fat` | `uat` | `pro` (default: `fat`)
- Config files embedded into binary at build time via `//go:embed` directives
- Config files: `configs/dev_configs.toml`, `configs/fat_configs.toml`, `configs/uat_configs.toml`, `configs/pro_configs.toml`
- TOML format parsed via Viper (`github.com/spf13/viper`)
- `MYSQL_ADDR`, `MYSQL_READ_ADDR`, `MYSQL_WRITE_ADDR`, `MYSQL_USER`, `MYSQL_PASS`, `MYSQL_NAME`
- `REDIS_ADDR`, `REDIS_PASS`
- `WECHAT_MCHID`, `WECHAT_SERIAL_NO`, `WECHAT_PRIVATE_KEY_PATH`, `WECHAT_API_V3_KEY`, `WECHAT_NOTIFY_URL`, `WECHAT_PUBLIC_KEY_ID`, `WECHAT_PUBLIC_KEY_PATH`
- `ALIYUN_SMS_ACCESS_KEY_ID`, `ALIYUN_SMS_ACCESS_KEY_SECRET`, `ALIYUN_SMS_SIGN_NAME`, `ALIYUN_SMS_TEMPLATE_CODE`
- `ADMIN_JWT_SECRET` - Admin JWT signing secret override
- Vite env vars: `VITE_VERSION`, `VITE_PORT`, `VITE_BASE_URL`, `VITE_API_URL`, `VITE_API_PROXY_URL`
- Dev proxy: `/api` requests forwarded to `VITE_API_PROXY_URL`
- Backend: `Dockerfile` (multi-stage, `golang:1.24-alpine``alpine:latest`)
- Server port: `9991` (constant in `configs/constants.go`)
- Container exposes port `9991`
## Platform Requirements
- Go 1.24+
- Node.js >= 18.0.0, pnpm >= 8.8.0
- MySQL instance (read/write addresses)
- Redis instance
- `golangci-lint` and `go-swagger` for linting/docs
- Docker (Linux/amd64 binary, CGO_ENABLED=0)
- Alpine Linux container
- MySQL with optional read replica (master-slave)
- Redis single-node
- Optional: OpenTelemetry-compatible collector (Tempo) at configured OTLP endpoint
<!-- GSD:stack-end -->
<!-- GSD:conventions-start source:CONVENTIONS.md -->
## Conventions
## Naming Patterns
- snake_case for all Go source files: `activity_order_service.go`, `draw_config_save.go`
- Test files co-located with source: `reward_snapshot_test.go` next to `rewards_create.go`
- Generated files suffixed with `.gen.go`: never edited manually
- Package names match directory name: `package activity` in `internal/service/activity/`
- kebab-case for TypeScript API files: `pay-orders.ts`, `order-snapshots.ts`
- kebab-case for view directories: `player-manage/`, `shipping-orders/`
- PascalCase for Vue component filenames where applicable
- PascalCase for exported: `NewActivityOrderService`, `CreateActivityOrder`, `ListProductsForApp`
- camelCase for unexported: `newRewardSnapshotTestService`, `shouldTriggerInstantDraw`, `assertAttribution`
- Constructor functions named `New<Type>` for service constructors: `NewProduct(...)`, `NewStore(...)`
- Handler methods return `core.HandlerFunc` (closure pattern): `func (h *productHandler) ListProductsForApp() core.HandlerFunc`
- `fetch` prefix for API functions: `fetchGetActivities`, `fetchGetActivityDetail`
- camelCase for all functions
- camelCase in Go: `userID`, `activityID`, `testLogger`
- Named ID variables use int64 type consistently: `userID int64`, `activityID int64`
- PascalCase for exported: `CreateActivityOrderRequest`, `ActivityOrderService`
- Unexported structs for implementation: `activityOrderService`, `productHandler`, `context`
- Request structs named `<verb><Domain>Request`: `listAppProductsRequest`, `CreateActivityOrderRequest`
- Response structs named `<verb><Domain>Response`: `listAppProductsResponse`, `getAppProductDetailResponse`
- Interface types use verb-noun: `ActivityOrderService`, `Service`, `Repo`
- 5-digit pattern: service level (1) + module level (2) + specific error (2)
- All-caps with CamelCase words: `ServerError = 10101`, `ParamBindError = 10102`
- Grouped by domain in `internal/code/code.go`
## Code Style
- `gofmt -s` via `make fmt` (uses standard gofmt)
- Import grouping via `go run cmd/mfmt/main.go`: stdlib → local module (`bindbox-game/...`) → third-party
- Line length not strictly enforced but long lines occur in handler code
- `golangci-lint run -D staticcheck` via `make lint`
- staticcheck disabled; other default golangci-lint checks active
- Prettier for all file types, configured via lint-staged hooks
- ESLint with `eslint-plugin-prettier/recommended`
- Single quotes enforced: `quotes: ['error', 'single']`
- No semicolons: `semi: ['error', 'never']`
- No `var`: `'no-var': 'error'` — use `let` or `const`
- `@typescript-eslint/no-explicit-any` disabled (any is allowed)
- Vue multi-word component name rule disabled
## Import Organization
- `import request from '@/utils/http'`
- `import { getActivityDetail } from './adminActivities'` (relative for same-level)
## Error Handling
## Logging
- Logger injected into handlers and services via constructor
- Handler structs hold `logger logger.CustomLogger` field
- Service structs hold `logger logger.CustomLogger` field
- Use structured fields: `zap.Field` variadic args
- Exported methods: `Info`, `Error`, `Warn`, `Debug`
- In tests, use `logger.NewCustomLogger(nil, logger.WithOutputInConsole())`
## Comments
## Function Design
## Module Design
- `internal/api/` → handlers only, thin, call services
- `internal/service/` → business logic, call DAOs and other services
- `internal/repository/mysql/` → data access via GORM DAOs (generated)
- `internal/pkg/` → shared utilities, no business logic
<!-- GSD:conventions-end -->
<!-- GSD:architecture-start source:ARCHITECTURE.md -->
## Architecture
## Overview
## Architectural Pattern
```
```
## Key Layers
### 1. Router Layer (`internal/router/`)
- `router.go` — Single file defining all routes via `NewHTTPMux()`
- Routes organized into groups:
### 2. Interceptor / Middleware Layer (`internal/router/interceptor/`)
- `admin_auth.go` — JWT token verification for admin users
- `admin_rbac.go` — Role-based access control with action-level permissions
- `app_auth.go` — App user token verification
- `blacklist.go` — Douyin user blacklist checking
- `interceptor.go` — Base interceptor struct with shared dependencies
### 3. API Handler Layer (`internal/api/`)
- `admin/` — Admin panel handlers (largest, ~30+ files)
- `activity/` — Lottery/game activity handlers
- `app/` — Store, product, banner, category handlers
- `game/` — Game ticket and minesweeper handlers
- `pay/` — Payment handlers
- `user/` — User management, orders, addresses
- `task_center/` — Task center handlers
- `common/` — Shared utilities (upload, openid)
- `public/` — Public livestream handlers
- `internal/` — Internal API handlers (Nakama integration)
### 4. Service Layer (`internal/service/`)
- `activity/` — Activity CRUD, lottery processing, matching game, settlements, strategy pattern for draw types
- `admin/` — Admin user management, login
- `user/` — User management, orders, points, coupons, inventory, shipping, synthesis
- `order/` — Order processing
- `game/` — Game ticket management, minesweeper
- `douyin/` — Douyin order sync, reward dispatching
- `task_center/` — Task definitions, progress tracking, worker
- `product/` — Product management
- `finance/` — Financial operations, ledger
- `channel/` — Marketing channel management
- `title/` — User title/badge system
- `banner/`, `sysconfig/`, `common/`, `snapshot/`, `recycle/`, `synthesis/`, `livestream/`
### 5. Repository Layer (`internal/repository/mysql/`)
- `mysql.go` — Database connection management (read/write split via `Repo` interface)
- `plugin.go` — GORM plugins
- `model/*.gen.go` — Generated GORM models (do not edit)
- `dao/*.gen.go` — Generated GORM DAOs (do not edit)
- `task_center/models.go` — Task center specific models
- `test_helper.go`, `testrepo_sqlite.go` — Test infrastructure
## Entry Point
## Data Flow
### Typical API Request Flow
```
```
### Background Task Flow
```
```
### Payment Flow
```
```
## Key Design Decisions
| Decision | Rationale |
|----------|-----------|
| Read/write DB split | Performance: heavy reads go to slave, writes to master |
| GORM code generation | Consistency: models and DAOs auto-generated from schema |
| Custom `core.Context` wrapper | Standardized error handling, tracing, session management across all handlers |
| Strategy pattern for lottery | Different draw types (standard, ichiban) share interface but have different logic |
| Background workers in main process | Simplicity: no separate worker binary, uses goroutines |
| JWT with hash verification | Security: stored token hash prevents concurrent sessions |
## Cross-Cutting Concerns
- **Logging**: Zap-based with file rotation (`internal/pkg/logger/`)
- **Tracing**: OpenTelemetry integration (`internal/pkg/otel/`)
- **Error Codes**: 5-digit system in `internal/code/` (service level + module + specific)
- **Alerts**: Alert notification system (`internal/alert/`)
- **Metrics**: Prometheus metrics (`internal/metrics/`)
## External Service Boundaries
- WeChat Mini Program API (`wechat/`, `miniprogram/`)
- WeChat Pay v3 API (`pay/`)
- Douyin/TikTok API (`douyin/`)
- Aliyun SMS (`sms/`)
- Tencent COS (object storage)
- OpenTelemetry collector
<!-- GSD:architecture-end -->
<!-- GSD:workflow-start source:GSD defaults -->
## GSD Workflow Enforcement
Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.
Use these entry points:
- `/gsd:quick` for small fixes, doc updates, and ad-hoc tasks
- `/gsd:debug` for investigation and bug fixing
- `/gsd:execute-phase` for planned phase work
Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.
<!-- GSD:workflow-end -->
<!-- GSD:profile-start -->
## Developer Profile
> Profile not yet configured. Run `/gsd:profile-user` to generate your developer profile.
> This section is managed by `generate-claude-profile` -- do not edit manually.
<!-- GSD:profile-end -->