From 58b1ac1126113b1afbbe276ca17e42e1057eff3a Mon Sep 17 00:00:00 2001 From: ZHENG XIAOYI Date: Thu, 12 Feb 2026 19:27:11 +0800 Subject: [PATCH] add AGENTS.md --- AGENTS.md | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..fa4f0cd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,176 @@ +# AGENTS.md + +This file provides guidance for agentic coding agents working on this repository. + +## Build/Lint/Test Commands + +### Building +```bash +make build # Build executable (trace-backend.exe) +make run # Run development server +go build -o bin/backend.exe . # Build to custom location +``` + +### Testing +```bash +make test # Run all integration tests (./tests/...) +go test -v ./services/... # Run service layer unit tests +go test -v ./tests/... # Run integration tests +go test -v -run TestAuthService_ValidateUser_Success ./services/... # Single test +go test -v ./services/... -run TestSerialsService # Run test prefix +make test-coverage # Generate coverage report +``` + +### Code Quality +```bash +make lint # Run golangci-lint (configured in .golangci.yml) +make fmt # Format code with gofmt +make imports # Format imports with goimports +make quality # fmt + imports + lint (full check) +golangci-lint run ./... # Direct lint check +``` + +### Swagger Documentation +```bash +make swagger # Generate swagger docs to docs/ directory +swag init -g main.go # Alternative command +``` + +## Code Style Guidelines + +### Project Structure +- **controllers/**: HTTP request handlers, use helper functions (GetCurrentUser, BindJSON, ErrorResponse, SuccessResponse) +- **services/**: Business logic layer, return errors to controllers +- **models/**: Data models with JSON and GORM tags, DTOs for API +- **middleware/**: JWT authentication and admin role checks +- **database/**: SQLite/PostgreSQL connection and migrations + +### Import Organization +Standard imports followed by third-party imports, then project imports (sorted alphabetically): +```go +import ( + "errors" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + + "git.beifan.cn/trace-system/backend-go/config" + "git.beifan.cn/trace-system/backend-go/models" +) +``` + +### Naming Conventions +- **Controllers**: `AuthController`, `SerialsController`, `CompaniesController` +- **Services**: `AuthService`, `SerialsService`, `CompaniesService` +- **Models**: `User`, `Company`, `Serial` (use PascalCase for exported structs) +- **DTOs**: `LoginDTO`, `ChangePasswordDTO`, `UpdateProfileDTO` (DTO suffix) +- **Functions**: `ValidateUser`, `Generate`, `Query` (PascalCase for exported) +- **Variables**: camelCase for local variables, PascalCase for exported + +### Struct Tags +- **JSON tags**: lowercase camelCase, `json:"username"`, `json:"accessToken"` +- **GORM tags**: PascalCase, `gorm:"primaryKey"`, `gorm:"uniqueIndex;size:255"` +- **Validate tags**: `validate:"required,min=6"`, `validate:"omitempty,email"` +- **Omit empty**: `json:"omitempty"` for optional fields +- **Ignore in JSON**: `json:"-"` for sensitive fields (Password, DeletedAt) + +### Error Handling +**Services**: Return errors, don't handle them directly: +```go +func (s *AuthService) ValidateUser(username, password string) (models.User, error) { + var user models.User + err := database.DB.Where("username = ?", username).First(&user).Error + if err != nil { + return models.User{}, errors.New("用户名或密码错误") + } + return user, nil +} +``` + +**Controllers**: Use helper functions for consistent responses: +```go +func (c *AuthController) Login(ctx *gin.Context) { + var loginData models.LoginDTO + if !BindJSON(ctx, &loginData) { + return + } + + user, err := c.authService.ValidateUser(loginData.Username, loginData.Password) + if err != nil { + ErrorResponse(ctx, http.StatusUnauthorized, err.Error()) + return + } + + SuccessResponse(ctx, "登录成功", gin.H{"user": user}) +} +``` + +### Response Format +**Success response**: +```json +{ + "message": "操作成功", + "data": { ... } +} +``` + +**Error response**: +```json +{ + "message": "错误描述", + "error": "详细错误信息" +} +``` + +### Logging +Use structured logger from `logger` package: +```go +logger.Info("用户登录", logger.String("username", user.Username)) +logger.Error("数据库错误", logger.Err(err)) +logger.Fatal("致命错误", logger.Err(err)) +``` + +### Database Operations +- Use `database.DB` for GORM operations +- Always check for errors: `if err != nil { ... }` +- Use Unscoped for permanent deletion: `database.DB.Unscoped().Delete(...)` +- Test cleanup: `database.DB.Unscoped().Where("1 = 1").Delete(&models.User{})` + +### Testing +- Use `testify/assert` for assertions +- Use `TestMain` for setup/cleanup (init DB, create test data, cleanup on exit) +- Test naming: `Test{Service}_{Method}_{Scenario}` +- Clean up test data after tests: delete all records +- Use bcrypt for password hashing in tests + +### Swagger Annotations +Add Swagger comments to controller methods: +```go +// @Summary Brief description +// @Description Detailed description +// @Tags Category +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param name body models.DTO true "Description" +// @Success 200 {object} models.ResponseDTO +// @Failure 400 {object} models.ErrorResponse +// @Router /path [method] +``` + +After modifying Swagger annotations, run `make swagger`. + +### Configuration +- Load with `config.LoadConfig()` +- Access with `config.GetAppConfig()` +- Environment variables: `APP_SERVER_PORT`, `APP_DATABASE_DRIVER`, etc. +- .env file for local development (not committed) + +### Middleware +- **JWTAuthMiddleware**: Validates JWT tokens, sets user in context +- **AdminMiddleware**: Checks if user has admin role +- Access current user: `user, ok := GetCurrentUser(ctx)` + +### Git Hooks +Run `make quality` before committing to ensure code passes all checks.