# 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 structure:
```
internal/{domain}/
├── domain/
│   ├── entity/
│   │   └── entity.go          # Core domain entities
│   ├── aggregate/
│   │   └── aggregate.go       # Aggregate roots and DTOs
│   ├── {domain}.go            # Repository implementation
│   └── repository.go          # Repository interface
├── service/
│   ├── {domain}.go            # Main service implementation
│   ├── profile.go             # Profile-related operations
│   └── form.go                # Request/response forms
└── handler/
    ├── v1/
    │   └── handler.go         # HTTP handlers
    └── middleware/            # Domain-specific middleware
```

### Dependency Rules
- Always depend on interfaces, not concrete implementations
- Use dependency injection through constructors
- Inner layers should never depend on outer layers
- All dependencies flow inward toward the domain
- Repository implementations are embedded in domain package

## 💻 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 domain layer (`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`)

### Service Interfaces
- Define business operations clearly in service package
- Use request/response forms for complex operations
- Include validation in service methods
- Handle business logic, not infrastructure concerns

## 📝 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 domain layer
- [ ] Create proper request/response forms with govalidator tags
- [ ] Plan error handling strategy
- [ ] Design database schema if needed
- [ ] Consider caching requirements
- [ ] Define custom validators if needed

### During Implementation
- [ ] Follow clean architecture layers
- [ ] 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

## 🎯 Code Examples

### Time Handling Utilities
```go
// pkg/timeutil/timeutil.go
package timeutil

import "time"

// NowUnix returns current Unix timestamp
func NowUnix() int64 {
    return time.Now().Unix()
}

// ValidateUnixTimestamp validates if Unix timestamp is reasonable
func ValidateUnixTimestamp(unix int64) bool {
    // Check if timestamp is not too old (before 2020) or too future (after 2030)
    minTime := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
    maxTime := time.Date(2030, 12, 31, 23, 59, 59, 0, time.UTC).Unix()
    return unix >= minTime && unix <= maxTime
}

// ParseUnixTimestamp parses string to Unix timestamp
func ParseUnixTimestamp(timestamp string) (int64, error) {
    // Handle various timestamp formats and convert to Unix
    // This can be extended based on your input requirements
    return 0, nil // Implementation depends on input format
}

// FormatUnixTimestamp formats Unix timestamp for display (if needed)
func FormatUnixTimestamp(unix int64, format string) string {
    return time.Unix(unix, 0).Format(format)
}
```

### Govalidator Request Forms
```go
// internal/customer/service/form.go
package service

import (
    "github.com/asaskevich/govalidator"
    "github.com/google/uuid"
)

// RegisterForm represents customer registration request
type RegisterForm struct {
    FirstName string `json:"first_name" valid:"required,alpha,length(2|50)"`
    LastName  string `json:"last_name" valid:"required,alpha,length(2|50)"`
    Email     string `json:"email" valid:"required,email"`
    Password  string `json:"password" valid:"required,length(8|128)"`
    Mobile    string `json:"mobile" valid:"required,length(10|15)"`
    CompanyID string `json:"company_id" valid:"required,uuid"`
}

// LoginForm represents customer login request
type LoginForm struct {
    Email    string `json:"email" valid:"required,email"`
    Password string `json:"password" valid:"required"`
}

// UpdateProfileForm represents profile update request
type UpdateProfileForm struct {
    FirstName    string `json:"first_name" valid:"required,alpha,length(2|50)"`
    LastName     string `json:"last_name" valid:"required,alpha,length(2|50)"`
    Mobile       string `json:"mobile" valid:"required,length(10|15)"`
    LastLoginAt  *int64 `json:"last_login_at,omitempty" valid:"optional,unix_timestamp"`
}

// CreateCustomerForm represents customer creation request
type CreateCustomerForm struct {
    FirstName    string `json:"first_name" valid:"required,alpha,length(2|50)"`
    LastName     string `json:"last_name" valid:"required,alpha,length(2|50)"`
    Email        string `json:"email" valid:"required,email"`
    Password     string `json:"password" valid:"required,length(8|128)"`
    Mobile       string `json:"mobile" valid:"required,length(10|15)"`
    CompanyID    string `json:"company_id" valid:"required,uuid"`
    CreatedAt    int64  `json:"created_at,omitempty" valid:"optional,unix_timestamp"`
    UpdatedAt    int64  `json:"updated_at,omitempty" valid:"optional,unix_timestamp"`
    LastLoginAt  *int64 `json:"last_login_at,omitempty" valid:"optional,unix_timestamp"`
}

// Custom validation functions
func init() {
    // Register custom validators
    govalidator.CustomTypeTagMap.Set("unix_timestamp", govalidator.CustomTypeValidator(func(i interface{}, context interface{}) bool {
        if unix, ok := i.(int64); ok {
            return timeutil.ValidateUnixTimestamp(unix)
        }
        return false
    }))
}
```

### Domain Entity Pattern
```go
// internal/customer/domain/entity/entity.go
type Customer struct {
    ID           uuid.UUID `bson:"_id"`
    Email        string    `bson:"email"`
    Password     string    `bson:"password"` // Never serialize
    FirstName    string    `bson:"first_name"`
    LastName     string    `bson:"last_name"`
    Mobile       string    `bson:"mobile"`
    CompanyID    uuid.UUID `bson:"company_id"`
    IsActive     bool      `bson:"is_active"`
    IsVerified   bool      `bson:"is_verified"`
    DeviceTokens []string  `bson:"device_tokens"`
    LastLoginAt  *int64    `bson:"last_login_at,omitempty"` // Unix timestamp
    CreatedAt    int64     `bson:"created_at"`              // Unix timestamp
    UpdatedAt    int64     `bson:"updated_at"`              // Unix timestamp
}
```

### Aggregate Pattern
```go
// internal/customer/domain/aggregate/aggregate.go
type Customer struct {
    ID         uuid.UUID `json:"_id"`
    FirstName  string    `json:"first_name"`
    LastName   string    `json:"last_name"`
    Mobile     string    `json:"mobile"`
    Email      string    `json:"email"`
    IsActive   bool      `json:"is_active"`
    IsVerified bool      `json:"is_verified"`
    LastLoginAt *int64   `json:"last_login_at,omitempty"` // Unix timestamp
    CreatedAt   int64    `json:"created_at"`              // Unix timestamp
    UpdatedAt   int64    `json:"updated_at"`              // Unix timestamp
}

func NewCustomer(c entity.Customer) Customer {
    customer := Customer{
        ID:         c.ID,
        FirstName:  c.FirstName,
        LastName:   c.LastName,
        Mobile:     c.Mobile,
        Email:      c.Email,
        IsActive:   c.IsActive,
        IsVerified: c.IsVerified,
        CreatedAt:  c.CreatedAt,
        UpdatedAt:  c.UpdatedAt,
    }
    
    if c.LastLoginAt != nil {
        customer.LastLoginAt = c.LastLoginAt
    }
    
    return customer
}
```

### Repository Implementation with Time Handling
```go
// internal/customer/domain/customer.go
func (r *customerRepository) Create(ctx context.Context, customer *entity.Customer) error {
    // Set created/updated timestamps using Unix timestamps
    now := time.Now().Unix()
    customer.CreatedAt = now
    customer.UpdatedAt = now

    // Insert customer
    _, err := r.collection.InsertOne(ctx, customer)
    if err != nil {
        if mongo.IsDuplicateKeyError(err) {
            return errors.New("customer already exists")
        }
        r.logger.Error("Failed to create customer", map[string]interface{}{
            "error":       err.Error(),
            "email":       customer.Email,
            "customer_id": customer.ID.String(),
        })
        return err
    }

    r.logger.Info("Customer created successfully", map[string]interface{}{
        "customer_id": customer.ID.String(),
        "email":       customer.Email,
    })

    return nil
}

func (r *customerRepository) Update(ctx context.Context, customer *entity.Customer) error {
    // Set updated timestamp using Unix timestamp
    customer.UpdatedAt = time.Now().Unix()

    filter := bson.M{"_id": customer.ID}
    update := bson.M{"$set": customer}

    result, err := r.collection.UpdateOne(ctx, filter, update)
    if err != nil {
        r.logger.Error("Failed to update customer", map[string]interface{}{
            "error":       err.Error(),
            "customer_id": customer.ID.String(),
        })
        return err
    }

    if result.MatchedCount == 0 {
        return errors.New("customer not found")
    }

    return nil
}

func (r *customerRepository) UpdateLastLogin(ctx context.Context, id uuid.UUID) error {
    now := time.Now().Unix()
    
    filter := bson.M{"_id": id}
    update := bson.M{
        "$set": bson.M{
            "last_login_at": now,
            "updated_at":    now,
        },
    }

    result, err := r.collection.UpdateOne(ctx, filter, update)
    if err != nil {
        r.logger.Error("Failed to update last login", map[string]interface{}{
            "error":       err.Error(),
            "customer_id": id.String(),
        })
        return err
    }

    if result.MatchedCount == 0 {
        return errors.New("customer not found")
    }

    return nil
}
```

### Repository Interface
```go
// internal/customer/domain/repository.go
type Repository interface {
    Create(ctx context.Context, customer *entity.Customer) error
    GetByID(ctx context.Context, id uuid.UUID) (*entity.Customer, error)
    GetByEmail(ctx context.Context, email string) (*entity.Customer, error)
    Update(ctx context.Context, customer *entity.Customer) error
    Delete(ctx context.Context, id uuid.UUID) error
    List(ctx context.Context, limit, offset int) ([]*entity.Customer, error)
    GetByCompanyID(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]*entity.Customer, error)
    AddDeviceToken(ctx context.Context, id uuid.UUID, token string) error
    RemoveDeviceToken(ctx context.Context, id uuid.UUID, token string) error
}
```

### Service Implementation Template
```go
type CustomerService struct {
    customerRepo domain.Repository
    config       *infra.AuthConfig
    logger       logger.Logger
}

func NewCustomerService(
    customerRepo domain.Repository,
    config *infra.AuthConfig,
    logger logger.Logger,
) CustomerService {
    return CustomerService{
        customerRepo: customerRepo,
        config:       config,
        logger:       logger,
    }
}

func (s *CustomerService) Register(ctx context.Context, req RegisterForm) (*aggregate.AuthorizationResponse, error) {
    s.logger.Info("Processing customer registration", map[string]interface{}{
        "email": req.Email,
    })

    // Convert form to entity
    customer := &entity.Customer{
        ID:        uuid.New(),
        FirstName: req.FirstName,
        LastName:  req.LastName,
        Email:     req.Email,
        Password:  req.Password, // Will be hashed in service
        Mobile:    req.Mobile,
        CompanyID: uuid.MustParse(req.CompanyID),
        IsActive:  true,
        IsVerified: false,
    }

    // Set timestamps
    s.setTimestamps(customer)

    // Create customer
    if err := s.customerRepo.Create(ctx, customer); err != nil {
        s.logger.Error("Failed to create customer", map[string]interface{}{
            "error": err.Error(),
            "email": req.Email,
        })
        return nil, err
    }

    // Generate tokens and return response
    // ... token generation logic

    return &aggregate.AuthorizationResponse{
        Customer: aggregate.NewCustomer(*customer),
        // ... token fields
    }, nil
}

func (s *CustomerService) GetCustomers(ctx context.Context, limit, offset int) ([]*entity.Customer, error) {
    s.logger.Info("Retrieving customers", map[string]interface{}{
        "limit":  limit,
        "offset": offset,
    })

    customers, err := s.customerRepo.List(ctx, limit, offset)
    if err != nil {
        s.logger.Error("Failed to retrieve customers", map[string]interface{}{
            "error":  err.Error(),
            "limit":  limit,
            "offset": offset,
        })
        return nil, errors.New("failed to retrieve customers")
    }

    s.logger.Info("Customers retrieved successfully", map[string]interface{}{
        "count":  len(customers),
        "limit":  limit,
        "offset": offset,
    })

    return customers, nil
}

// Time handling helper functions - all using Unix timestamps
func (s *CustomerService) setTimestamps(customer *entity.Customer) {
    now := timeutil.NowUnix()
    if customer.CreatedAt == 0 {
        customer.CreatedAt = now
    }
    customer.UpdatedAt = now
}

func (s *CustomerService) setLastLogin(customer *entity.Customer) {
    now := timeutil.NowUnix()
    customer.LastLoginAt = &now
    customer.UpdatedAt = now
}

func (s *CustomerService) validateTimestamps(customer *entity.Customer) error {
    if customer.CreatedAt != 0 && !timeutil.ValidateUnixTimestamp(customer.CreatedAt) {
        return errors.New("invalid created_at timestamp")
    }
    if customer.UpdatedAt != 0 && !timeutil.ValidateUnixTimestamp(customer.UpdatedAt) {
        return errors.New("invalid updated_at timestamp")
    }
    if customer.LastLoginAt != nil && !timeutil.ValidateUnixTimestamp(*customer.LastLoginAt) {
        return errors.New("invalid last_login_at timestamp")
    }
    return nil
}
```

### Handler Implementation Template
```go
type CustomerHandler struct {
    service service.CustomerService
    logger  logger.Logger
}

func NewHandler(
    customerService service.CustomerService,
    logger logger.Logger,
) *CustomerHandler {
    return &CustomerHandler{
        service: customerService,
        logger:  logger,
    }
}

func (h *CustomerHandler) Register(c echo.Context) error {
    var req service.RegisterForm

    // Bind request body
    if err := c.Bind(&req); err != nil {
        return response.BadRequest(c, "Invalid request format", err.Error())
    }

    // Validate request using govalidator
    if _, err := govalidator.ValidateStruct(&req); err != nil {
        return response.ValidationError(c, "Validation failed", err.Error())
    }

    // Call service
    authResponse, err := h.service.Register(c.Request().Context(), req)
    if err != nil {
        return response.InternalServerError(c, "Registration failed")
    }

    return response.Created(c, authResponse, "Customer registered successfully")
}

func (h *CustomerHandler) UpdateProfile(c echo.Context) error {
    var req service.UpdateProfileForm

    // Bind request body
    if err := c.Bind(&req); err != nil {
        return response.BadRequest(c, "Invalid request format", err.Error())
    }

    // Validate request using govalidator
    if _, err := govalidator.ValidateStruct(&req); err != nil {
        return response.ValidationError(c, "Validation failed", err.Error())
    }

    // Call service
    customer, err := h.service.UpdateProfile(c.Request().Context(), req)
    if err != nil {
        return response.InternalServerError(c, "Profile update failed")
    }

    return response.Success(c, customer, "Profile updated successfully")
}

func (h *CustomerHandler) CreateWithTimestamp(c echo.Context) error {
    var req service.CreateCustomerForm

    // Bind request body
    if err := c.Bind(&req); err != nil {
        return response.BadRequest(c, "Invalid request format", err.Error())
    }

    // Validate request using govalidator
    if _, err := govalidator.ValidateStruct(&req); err != nil {
        return response.ValidationError(c, "Validation failed", err.Error())
    }

    // Call service
    customer, err := h.service.CreateCustomer(c.Request().Context(), req)
    if err != nil {
        return response.InternalServerError(c, "Customer creation failed")
    }

    return response.Created(c, customer, "Customer created successfully")
}
```

### Configuration Structure
```go
// infra/config.go
type Config struct {
    Server    ServerConfig    `mapstructure:"server"`
    Database  DatabaseConfig  `mapstructure:"database"`
    Cache     CacheConfig     `mapstructure:"cache"`
    Queue     QueueConfig     `mapstructure:"queue"`
    Search    SearchConfig    `mapstructure:"search"`
    Auth      AuthConfig      `mapstructure:"auth"`
    AI        AIConfig        `mapstructure:"ai"`
    Scraping  ScrapingConfig  `mapstructure:"scraping"`
    Logging   LoggingConfig   `mapstructure:"logging"`
    RateLimit RateLimitConfig `mapstructure:"rate_limiting"`
}
```

### Application Bootstrap
```go
// cmd/web/main.go
func main() {
    conf := intiConfig()

    logger := initLogger(conf.Logging)
    defer logger.Sync()

    logger.Info(
        "Starting Tender Management API Server",
        map[string]interface{}{
            "version": "1.0.0",
            "host":    conf.Server.Host,
            "port":    conf.Server.Port,
        })
}
```

## 🚀 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 established domain structure pattern
- Use the custom logger interface consistently
- Implement proper error handling and logging
- Follow the repository pattern with embedded implementations
- **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 