5.6 KiB
5.6 KiB
AGENTS.md
This file provides guidance for agentic coding agents working on this repository.
Build/Lint/Test Commands
Building
make build # Build executable (trace-backend.exe)
make run # Run development server
go build -o bin/backend.exe . # Build to custom location
Testing
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
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
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):
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:
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:
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:
{
"message": "操作成功",
"data": { ... }
}
Error response:
{
"message": "错误描述",
"error": "详细错误信息"
}
Logging
Use structured logger from logger package:
logger.Info("用户登录", logger.String("username", user.Username))
logger.Error("数据库错误", logger.Err(err))
logger.Fatal("致命错误", logger.Err(err))
Database Operations
- Use
database.DBfor 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/assertfor assertions - Use
TestMainfor 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:
// @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.