Files
tm_back/.cursor/rules/backend-coding-rules.mdc
T
n.nakhostin 3e9877574c Refactor customer domain structure and implement core entities, services, and handlers
- Introduced a flat structure for the customer domain, consolidating entities, aggregates, repositories, services, forms, and handlers into a single package.
- Added core entities: Customer and CustomerAggregate.
- Implemented request/response forms for customer authentication (Register, Login, Refresh Token, Change Password).
- Created CustomerService to handle business logic and data access through the Repository interface.
- Established CustomerHandler for HTTP request handling related to customer authentication.
- Removed previous domain structure artifacts to streamline the codebase.
2025-08-02 11:26:35 +03:30

355 lines
13 KiB
Plaintext

---
alwaysApply: true
---
# Cursor Rules for Tender Management Go Backend
## Project Context
This is a Go backend API for a tender management system following Clean Architecture principles with Domain-Driven Design (DDD) patterns, designed to be AI-friendly and easy to maintain.
## 🏗️ Architecture Guidelines
### Clean Architecture Layers
- **Domain Layer** (`internal/{domain}/domain/`): Business entities, aggregates, interfaces, and core business rules
- **Service Layer** (`internal/{domain}/service/`): Business logic and use cases
- **Handler Layer** (`internal/{domain}/handler/`): HTTP controllers and request/response handling
- **Repository Layer** (`internal/{domain}/domain/`): Data access implementations (embedded in domain)
- **Infrastructure Layer** (`infra/`): External dependencies (DB, cache, queues, config)
### Domain Structure Pattern
Each domain follows this flat structure:
```
internal/{domain}/
├── entity.go # Core domain entities
├── aggregate.go # Aggregate roots and DTOs
├── repository.go # Repository interface and implementation
├── service.go # Business logic and use cases
├── form.go # Request/response forms with validation
└── handler.go # HTTP controllers and request/response handling
```
**Package Structure**: All files in a domain use the same package name (e.g., `package customer`)
### Dependency Rules
- Always depend on interfaces, not concrete implementations
- Use dependency injection through constructors
- All files in a domain use the same package name for easy access
- Repository implementations are in the same package as interfaces
- Keep dependencies minimal and focused
## 💻 Go Best Practices
### Code Structure
- Use standard Go project layout with `internal/` for private code
- Group related functionality in domain packages
- Keep packages focused on single responsibility
- Use meaningful package names (not generic like `utils` or `helpers`)
### Naming Conventions
- Use Go naming conventions: camelCase for private, PascalCase for public
- Interface names should describe what they do (e.g., `CustomerRepository`, `AuthService`)
- Use descriptive variable names, avoid abbreviations
- Constants should be in ALL_CAPS with underscores
- Domain packages use singular form (e.g., `customer`, not `customers`)
### Error Handling
- Always handle errors explicitly, never ignore them
- Use structured error messages with context
- Wrap errors with additional context using `fmt.Errorf("context: %w", err)`
- Log errors at the point they occur with relevant fields
- Return domain-specific error types when appropriate
### Function Design
- Keep functions small and focused (max 20-30 lines)
- Use early returns to reduce nesting
- Validate inputs at function entry points
- Use descriptive parameter names
- Limit function parameters (max 3-4, use structs for more)
## 🔌 Interface Design
### Repository Interfaces
- Always create interfaces in the same package (`repository.go`)
- Use context.Context as first parameter for all methods
- Return domain entities, not database models
- Include common operations: Create, GetByID, Update, Delete, List
- Use specific query methods (e.g., `GetByEmail`, `GetByCompanyID`)
- Repository implementation is in the same file as the interface
### Service Interfaces
- Define business operations clearly in service.go
- Use request/response forms for complex operations
- Include validation in service methods
- Handle business logic, not infrastructure concerns
- Service implementation is in the same package as other domain files
## 📝 Logging Standards
### Using Custom Logger Interface
- Always use structured logging with fields
- Include relevant context (user_id, customer_id, request_id, etc.)
- Use appropriate log levels:
- `Debug`: Detailed debugging information
- `Info`: General operational messages
- `Warn`: Warning conditions that should be addressed
- `Error`: Error conditions that need attention
- `Fatal`: Critical errors that cause program termination
### Logging Examples
```go
// Good
log.Info("Customer authenticated successfully", map[string]interface{}{
"customer_id": customer.ID.String(),
"email": customer.Email,
"ip": clientIP,
})
// Bad
log.Info("Customer login")
```
### Error Logging
- Log errors with full context
- Include error details and relevant fields
- Don't log the same error multiple times in the call stack
## 🗄️ Database & Repository Patterns
### Repository Implementation
- Implement repository interfaces in domain package (`{domain}.go`)
- Use proper database transactions for related operations
- Handle database errors gracefully
- Use prepared statements or ORM query builders
- Implement proper pagination with limit/offset
- **Time Handling**: Always use Unix timestamps (int64) for database operations
- **Timestamp Updates**: Use `time.Now().Unix()` for created_at and updated_at fields
### Data Models
- Use domain entities directly with BSON tags for MongoDB
- Include audit fields (created_at, updated_at)
- Use proper database field tags (bson, json)
- Never serialize sensitive fields (passwords)
### Time Handling Patterns
- **Input**: Accept Unix timestamps (int64) for all time fields
- **Database Storage**: Store as Unix timestamps (int64) in MongoDB
- **Output**: Return Unix timestamps (int64) for all time fields in API responses
- **Internal Processing**: Use Unix timestamps (int64) for all business logic
- **Audit Fields**: Always use Unix timestamps for created_at, updated_at
- **Consistency**: All time operations use Unix timestamps throughout the application
### MongoDB Patterns
- Create indexes in repository constructor
- Use proper BSON field names
- Handle duplicate key errors appropriately
- Use MongoDB-specific features (aggregations, etc.)
- **Time Fields**: Store all time fields as Unix timestamps (int64) for consistency
- **Queries**: Use Unix timestamps for time-based queries and filtering
## 🌐 HTTP Handler Guidelines
### Request Handling
- Validate all incoming requests using govalidator
- Use proper HTTP status codes
- Return consistent API response format using `pkg/response`
- Handle CORS appropriately
- Include request timeout handling
- **Time Input**: Accept Unix timestamps (int64) for all time fields in requests
- **Time Validation**: Validate Unix timestamps are within reasonable ranges
- **Time Consistency**: All time inputs must be Unix timestamps (int64)
### Govalidator Usage
- Use govalidator for all request validation
- Define validation tags in request structs
- Use custom validation functions for complex rules
- Validate at handler level before calling services
- Return validation errors using `response.ValidationError()`
- Use meaningful error messages for validation failures
### Response Format
- Always use standardized response structure from `pkg/response`
- Include appropriate metadata for paginated responses
- Provide meaningful error messages
- Never expose internal errors to clients
- **Time Output**: Always return Unix timestamps (int64) for all time fields in API responses
- **Time Consistency**: Ensure all time fields in responses use Unix timestamps consistently
### Security
- Validate and sanitize all inputs
- Use proper authentication middleware
- Implement rate limiting
- Never log sensitive information (passwords, tokens)
- Use HTTPS in production
## 🧪 Testing Guidelines
### Test Structure
- Write unit tests for all business logic
- Use table-driven tests for multiple scenarios
- Mock external dependencies using interfaces
- Test error cases, not just happy paths
- Use meaningful test names that describe the scenario
### Test Organization
- Place tests in same package as code being tested
- Use `_test.go` suffix for test files
- Create test utilities in `testutil` package if needed
- Use setup/teardown functions for common test data
## 📋 Configuration Management
### Configuration Structure
- Use YAML for configuration files
- Support environment variable overrides
- Validate configuration on startup
- Use default values for optional settings
- Document all configuration options
### Configuration Types
- Server configuration (host, port, timeouts)
- Database configuration (MongoDB URI, pool settings)
- Cache configuration (Redis settings)
- Queue configuration (RabbitMQ settings)
- Auth configuration (JWT settings)
- Logging configuration (level, format, output)
### Environment Variables
- Use consistent naming convention (e.g., `TM_DATABASE_URI`)
- Never commit secrets in configuration files
- Use different configs for different environments
## 🚀 Performance Guidelines
### Optimization
- Use database indexes appropriately
- Implement caching for frequently accessed data
- Use connection pooling for databases
- Avoid N+1 queries
- Profile performance bottlenecks
### Memory Management
- Close resources properly (database connections, files)
- Use context for cancellation and timeouts
- Avoid memory leaks in goroutines
- Use sync.Pool for frequently allocated objects
## 📚 Documentation Standards
### Code Documentation
- Write clear comments for complex business logic
- Document all public interfaces and types
- Use Go doc comments format
- Include examples for complex functions
- Keep comments up to date with code changes
### API Documentation
- Use OpenAPI/Swagger annotations
- Document all endpoints with examples
- Include error response examples
- Document authentication requirements
## 🔐 Security Best Practices
### Authentication & Authorization
- Use JWT tokens with proper expiration
- Implement refresh token rotation
- Use bcrypt for password hashing
- Validate token claims properly
- Implement proper RBAC
### Input Validation
- Validate all inputs at API boundaries
- Use whitelist validation, not blacklist
- Sanitize inputs to prevent injection attacks
- Validate file uploads properly
## 📦 Dependency Management
### Go Modules
- Keep go.mod clean and organized
- Pin major versions for stability
- Regular dependency updates with testing
- Remove unused dependencies
- Use vendor directory for critical dependencies
### External Libraries
- Prefer standard library when possible
- Choose well-maintained libraries
- Avoid dependencies with security issues
- Keep dependencies minimal
## 🔄 Code Review Guidelines
### Before Committing
- Run `go fmt`, `go vet`, and linting tools
- Ensure all tests pass
- Check for proper error handling
- Verify logging is appropriate
- Confirm no sensitive data is exposed
### Code Quality
- Follow single responsibility principle
- Avoid code duplication
- Use meaningful variable names
- Keep functions and files reasonably sized
- Maintain consistent code style
## 🚨 Error Patterns to Avoid
### Anti-patterns
- Don't use panic for regular error handling
- Avoid global variables for application state
- Don't ignore context cancellation
- Avoid deeply nested if statements
- Don't use reflection unless absolutely necessary
### Common Mistakes
- Not handling database connection errors
- Forgetting to close resources
- Not validating user inputs
- Exposing internal errors to clients
- Not using proper HTTP status codes
## 📋 Checklist for New Features
### Before Implementation
- [ ] Define interfaces in the same package (`repository.go`)
- [ ] Create proper request/response forms with govalidator tags (`form.go`)
- [ ] Plan error handling strategy
- [ ] Design database schema if needed
- [ ] Consider caching requirements
- [ ] Define custom validators if needed
### During Implementation
- [ ] Follow flat domain structure (all files in same package)
- [ ] Use dependency injection
- [ ] Implement proper logging
- [ ] Add govalidator validation tags to forms
- [ ] Register custom validators in init() functions
- [ ] Handle errors gracefully
### After Implementation
- [ ] Write unit tests
- [ ] Update API documentation
- [ ] Test error scenarios
- [ ] Verify security implications
- [ ] Check performance impact
- [ ] Test validation scenarios
## 🚀 Remember
- Prioritize simplicity and readability over cleverness
- Make code self-documenting through clear naming
- Always consider the person who will maintain this code
- Test your code thoroughly
- Security and performance are not optional
- **Follow the flat domain structure**: All files in a domain use the same package name
- Use the custom logger interface consistently
- Implement proper error handling and logging
- Follow the repository pattern with interface and implementation in same file
- **Time Consistency**: Always use Unix timestamps (int64) for input, storage, and output
- **Time Validation**: Validate all Unix timestamp inputs are within reasonable ranges
- **Time Utilities**: Use centralized time utility functions for consistency across the application
- **No Format Conversion**: Never convert between Unix timestamps and other time formats in the application
- **Validation**: Always use govalidator for request validation with proper tags
- **Form Design**: Define validation rules in request forms, not in handlers
- **Custom Validators**: Register custom validators for complex validation rules
- **Package Structure**: Keep all domain files in the same package for easy access and minimal imports