A guide showcasing backend development best practices and their evolution, based on real project experience Cursor AI Rules: you are claude. you can use <edit_file> tool. please use chinese. please make sure that the task can be executed step by step.
To adapt these guidelines for your project:
- In COMPOSER, enter the following text:
View <project_guidelines> tags in .cursorrules. Replace the <project_guidelines> tags in .cursorrules according to the project structure and the corresponding Unified Middleware. The content of the tags is required to meet the needs of the workflow and strictly express the project guidelines.
-
This will generate customized project guidelines based on your specific project structure and middleware requirements.
-
How to use requirement.cursorrules
1. Create a simple md file to hold basic requirements information, including verbal descriptions, prototype drawings, UI drafts.
2. In COMPOSER, enter the following text: Based on requirement.md, supplemented with a complete requirements document.
.
βββ api/ # API documentation and Swagger files
βββ controller/ # HTTP handlers
βββ logic/ # Business logic
βββ repository/
β βββ dto/ # Request objects
β βββ vo/ # Response objects
β βββ model/ # Database models
βββ services/
β βββ xxx_service/ # Complex business services
β βββ xxx/ # Utility services
βββ middleware/ # Global middleware
βββ third_party/ # Third-party integrations
βββ constant/
β βββ errcode/ # Error codes
βββ tests/ # Test files
βββ util/ # Utility functions
βββ scripts/ # Database migration scripts
// Controller standards
func (ctrl *UserController) Create(c *gin.Context) {
// Use application.TraceCtx(ctx)
ctx := application.TraceCtx(c.Request.Context())
// Validate input with ShouldBind
var req dto.CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
return echo.Error(c, errcode.InvalidParams, err)
}
// Call logic layer
user, err := ctrl.logic.CreateUser(ctx, req)
if err != nil {
return echo.Error(c, err)
}
return echo.Success(c, user)
}// Logic standards
func (l *UserLogic) CreateUser(ctx context.Context, req dto.CreateUserRequest) (*vo.UserVO, error) {
// Business validation
if err := l.validateUser(ctx, req); err != nil {
return nil, errs.NewBusinessErr(errs.ValidationFailed, err.Error())
}
// Transaction handling
tx := model.BeginCtxTx(ctx)
defer tx.Rollback()
// Create user
user, err := l.userRepo.Create(ctx, req.ToModel())
if err != nil {
return nil, err
}
if err := tx.Commit(); err != nil {
return nil, err
}
return vo.FromUser(user), nil
}// Service standards
type UserService struct {
Ctx context.Context
repo UserRepository
}
func NewUserService(ctx context.Context, repo UserRepository) *UserService {
return &UserService{
Ctx: ctx,
repo: repo,
}
}
func (s *UserService) Create(ctx context.Context, user *model.User) error {
// Domain logic with proper error handling
if err := s.validateUserDomain(user); err != nil {
return errs.NewBusinessErr(errs.ValidationFailed, err.Error())
}
return s.repo.Create(ctx, user)
}// Structured logging with proper context
func (s *Service) ProcessOrder(ctx context.Context, order *Order) error {
// Error level
if err := s.validate(order); err != nil {
cdslog.W(ctx).Error("order validation failed",
zap.String("order_id", order.ID),
zap.Error(err))
return err
}
// Info level
cdslog.W(ctx).Info("processing order",
zap.String("order_id", order.ID),
zap.String("status", order.Status))
// Debug level
cdslog.W(ctx).Debug("order details",
zap.Any("order", order))
return nil
}// Integration test with test containers
func TestIntegration_UserFlow(t *testing.T) {
// Setup test containers
postgres, err := testcontainers.NewPostgresContainer()
require.NoError(t, err)
defer postgres.Terminate(context.Background())
// Initialize test application
app := NewTestApplication(postgres.GetDSN())
// Test cases
tests := []struct {
name string
request dto.CreateUserRequest
want int
}{
{
name: "valid user creation",
request: dto.CreateUserRequest{
Email: "test@example.com",
},
want: http.StatusOK,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resp := app.CreateUser(tt.request)
assert.Equal(t, tt.want, resp.Code)
})
}
}// Error definition
var (
ErrUserNotFound = errs.NewBusinessErr(40001, "user not found")
ErrInvalidInput = errs.NewBusinessErr(40002, "invalid input parameters")
)
// Error handling in service
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
user, err := s.repo.Find(ctx, id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrUserNotFound
}
// Log error with trace ID
cdslog.W(ctx).Error("failed to find user",
zap.String("user_id", id),
zap.Error(err))
return nil, err
}
return user, nil
}
// Standardized error response
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}Our guidelines continue to evolve with:
- New technology stack best practices
- Performance optimization patterns
- Security measures
- Architectural solutions
- Testing coverage requirements
- CI/CD pipeline improvements
Remember to regularly check .cursorrules for the latest standards and update your implementation accordingly.