diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..d526b230 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,148 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +This project uses GoFrame (GF) framework and includes a custom Makefile that delegates to `hack/hack.mk`: + +### Building and Running + +- `make build` - Build binary using GoFrame CLI (`gf build -ew`) +- `go run main.go` - Run the application directly +- `make up` - Update GoFrame and CLI to latest version (`gf up -a`) + +### Code Quality & Linting + +- `go fmt ./...` - Format all Go files +- `go vet ./...` - Run Go vet for potential issues +- `go mod tidy` - Clean up module dependencies + +### Code Generation (GoFrame CLI) + +**Using Make Commands (Recommended)**: +- `make ctrl` - Generate controllers from API definitions (`gf gen ctrl`) +- `make dao` - Generate DAO/DO/Entity files from database schema (`gf gen dao`) +- `make service` - Generate service interfaces (`gf gen service`) +- `make enums` - Generate enum files from Go code (`gf gen enums`) +- `make pb` - Generate protobuf files (`gf gen pb`) +- `make pbentity` - Generate protobuf files for database tables (`gf gen pbentity`) + +**Using Direct GF Commands**: +- `gf gen dao` - Generate DAO/DO/Entity files from database schema +- `gf gen service` - Generate service interfaces from logic files +- `gf gen ctrl` - Generate controllers from API definitions +- `gf gen enums` - Generate enum files from Go code + +**Important**: After database schema changes, run code generation in order: `make dao` → `make service` → `make ctrl` + +### Testing + +- `go test ./...` - Run all tests +- `go test -v ./internal/logic/...` - Run tests for specific packages +- `go test ./internal/logic/card_apple_account -v` - Run tests for specific module +- `go test -run TestName` - Run specific test +- `go test -race ./...` - Run tests with race detection +- `go test -cover ./...` - Run tests with coverage report + +### Docker & Deployment + +- `make image` - Build Docker image with auto-generated git-based tag +- `make image.push` - Build and push Docker image +- `make deploy` - Deploy to kubernetes environment using kustomize +- **Environment Variables**: Set `serverName` env var for service identification in OpenTelemetry +- **Deployment Config**: Uses `manifest/deploy/kustomize/overlays/${_ENV}` for environment-specific configs + +**Configuration Files**: +- `hack/config.yaml`: Code generation configuration with database connections and paths +- `manifest/config/config.yaml`: Application runtime configuration + +## Architecture Overview + +This is a Go-based backend service for a card redemption platform (卡密兑换平台) using the GoFrame framework: + +### Application Entry & Flow + +- **main.go**: Entry point with OpenTelemetry initialization, sets service name from `serverName` env var, starts + `cmd.Main` +- **internal/cmd/cmd.go**: HTTP server setup, binds controllers under `/api` with middleware stack, registers monitoring + and cron tasks + +### Database Architecture (Dual Database Setup) + +The system uses two MySQL databases configured in `manifest/config/config.yaml`: + +- **default** (`kami_v2`): Primary database +- **v1** (`kami`): Legacy database with `v1` prefix for generated models + +Code generation configuration in `hack/config.yaml` defines separate DAO generation for each database with appropriate +prefixes. Current generation uses the `kami` database with `v1` prefix for backward compatibility. + +### Business Domain Structure + +**Card Platform Management**: + +- Apple cards (`card_apple_*`): Account management, order processing, steal rules +- T-Mall cards (`card_t_mall_*`): Account management, order processing, shop management +- JD cards (`card_jd_*`, `card_original_jd_*`): JD card variants +- Walmart cards (`card_walmart_*`): Walmart card management +- C-Trip cards (`card_c_trip_*`): Travel card management +- Redeem cards (`card_redeem_*`): Generic redemption system + +**Core Business Systems**: + +- **Order Processing**: Complete lifecycle with callbacks, status tracking, summaries +- **Merchant Management**: Configurations, deployments, hidden settings, steal rules +- **Channel & Road Management**: Business routing with road pools and entrance management +- **User Management**: Authentication (JWT + TOTP), roles, Casbin authorization +- **Payment Processing**: Payment methods, deductions, statistics +- **Restriction Management**: IP/device tracking for access control +- **JDCookie Management**: Cookie rotation, order processing, account management + +### Technology Stack Details + +- **Framework**: GoFrame v2 with heavy code generation usage +- **Language**: Go 1.25+ (see go.mod) +- **Database**: MySQL with GoFrame ORM (DAO/DO/Entity pattern), dual database support +- **Cache**: Redis for caching, sessions, rate limiting +- **Tracing**: OpenTelemetry with custom headers (`x-service-token`) +- **Monitoring**: Built-in metrics, health checks, monitor tasks +- **Task Scheduling**: Cron jobs with graceful shutdown +- **Authentication**: JWT with TOTP support, multi-login capability +- **Authorization**: Casbin RBAC with model/policy files +- **Rate Limiting**: Redis-based with configurable rules + +### External Integrations + +All external platform integrations are abstracted in `utility/integration/`: + +- **T-Mall**: OAuth gateway integration with eco.taobao.com +- **JD**: JD API integration with cookie management +- **Walmart**: Walmart API integration +- **C-Trip**: Travel platform API integration +- **Agiso**: App authentication service + +### Configuration System + +- **Primary Config**: `manifest/config/config.yaml` +- **Code Gen Config**: `hack/config.yaml` (database connections, generation paths) +- **Environment Support**: `serverName` variable for service identification +- **Secret Management**: Encryption keys for frontend/backend, token configuration + +### Critical Development Patterns + +- **Code Generation Workflow**: Database changes → `make dao` → `make service` → `make ctrl` +- **API-First**: Controllers generated from `api/` definitions in `/api` folder +- **Domain Separation**: Each business domain has its own logic folder with clear boundaries +- **Middleware Stack**: CORS, response handling, error handling, gzip, and context management +- **Graceful Shutdown**: Implemented for cron jobs and connection pools in `cmd.go:83-92` +- **Security**: Built-in rate limiting, IP/device restrictions, authentication middleware + +### Testing Strategy + +Focused test coverage in critical business logic areas: + +- Apple account management (`internal/logic/card_apple_account/`) +- T-Mall order processing (`internal/logic/card_t_mall_order/`) +- Rate limiting (`internal/logic/limiter/`) +- Business logic validation with comprehensive test coverage \ No newline at end of file diff --git a/internal/logic/card_apple_account/schdule.go b/internal/logic/card_apple_account/schdule.go index 030b1e27..61197994 100644 --- a/internal/logic/card_apple_account/schdule.go +++ b/internal/logic/card_apple_account/schdule.go @@ -56,7 +56,9 @@ func (a *sAppleAccount) GetAccordingAccount(ctx context.Context, amount decimal. // 从当前用户开始,循环遍历所有用户 currentUser := users[(currentUserIndex+i)%len(users)] m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()). - Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, currentUser.Id) + Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, currentUser.Id). + Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountNormal). + OrderAsc(dao.V1CardAppleAccountInfo.Columns().CreatedAt) if len(excludeAccountIds) > 0 { m = m.WhereNotIn(dao.V1CardAppleAccountInfo.Columns().Id, excludeAccountIds) @@ -64,7 +66,6 @@ func (a *sAppleAccount) GetAccordingAccount(ctx context.Context, amount decimal. if len(excludeAccountList) > 0 { m = m.WhereNotIn(dao.V1CardAppleAccountInfo.Columns().Account, excludeAccountList) } - m = m.Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountNormal).OrderAsc(dao.V1CardAppleAccountInfo.Columns().CreatedAt) // 查找当前用户的所有订单 err = m.Scan(&accountInfo)