// Go Fiber Development Guide
// Author: {{AUTHOR_NAME}} ({{GITHUB_USERNAME}})

// What you can build with this ruleset:
A modern web application using Go Fiber:
- RESTful APIs
- GraphQL APIs
- WebSocket servers
- Middleware
- Authentication
- File uploads
- Database integration
- Background jobs

// Project Structure
cmd/
  api/            # Application entrypoint
    main.go       # Main application file
internal/         # Application logic
  config/         # Configuration
    config.go     # Config structs
    env.go        # Environment vars
  handlers/       # HTTP handlers
    auth.go       # Auth handlers
    users.go      # User handlers
  middleware/     # Custom middleware
    auth.go       # Auth middleware
    logger.go     # Logging middleware
  models/         # Data models
    user.go       # User model
    product.go    # Product model
  repositories/   # Data access
    postgres/     # Postgres repos
    redis/        # Redis repos
  services/       # Business logic
    auth.go       # Auth service
    users.go      # User service
  utils/          # Utilities
    logger/       # Logger
    validator/    # Validators
pkg/              # Public packages
  errors/         # Error types
  database/       # DB helpers
migrations/       # DB migrations
tests/            # Test suite
  integration/    # Integration tests
  unit/           # Unit tests

// Development Guidelines
1. API Design:
   - RESTful principles
   - Error handling
   - Validation
   - Authentication
   - Rate limiting
   - Documentation

2. Code Structure:
   - Clean architecture
   - Dependency injection
   - Repository pattern
   - Service layer
   - Error handling
   - Logging

3. Performance:
   - Concurrency
   - Connection pooling
   - Caching
   - Query optimization
   - Memory usage
   - Monitoring

// Dependencies
Core:
- fiber: "v2.47.0"
- gorm: "v1.25.0"
- jwt-go: "v4.5.0"
- validator: "v10.14.0"

Optional:
- redis: "v9.0.0"
- zap: "v1.24.0"
- testify: "v1.8.0"
- mock: "v2.0.0"

// Code Examples:

1. Handler Pattern:
```go
package handlers

import (
    "github.com/gofiber/fiber/v2"
    "github.com/username/project/internal/models"
    "github.com/username/project/internal/services"
    "github.com/username/project/pkg/errors"
)

type UserHandler struct {
    userService services.UserService
    logger      *zap.Logger
}

func NewUserHandler(us services.UserService, l *zap.Logger) *UserHandler {
    return &UserHandler{
        userService: us,
        logger:      l,
    }
}

func (h *UserHandler) Create(c *fiber.Ctx) error {
    var input models.CreateUserInput
    
    if err := c.BodyParser(&input); err != nil {
        h.logger.Error("failed to parse request body", zap.Error(err))
        return c.Status(fiber.StatusBadRequest).JSON(errors.NewBadRequestError("invalid request body"))
    }
    
    if err := input.Validate(); err != nil {
        h.logger.Error("validation failed", zap.Error(err))
        return c.Status(fiber.StatusBadRequest).JSON(errors.NewValidationError(err))
    }
    
    user, err := h.userService.Create(c.Context(), input)
    if err != nil {
        h.logger.Error("failed to create user", zap.Error(err))
        return h.handleError(c, err)
    }
    
    return c.Status(fiber.StatusCreated).JSON(user)
}

func (h *UserHandler) Get(c *fiber.Ctx) error {
    id := c.Params("id")
    
    user, err := h.userService.GetByID(c.Context(), id)
    if err != nil {
        h.logger.Error("failed to get user", zap.String("id", id), zap.Error(err))
        return h.handleError(c, err)
    }
    
    return c.JSON(user)
}

func (h *UserHandler) handleError(c *fiber.Ctx, err error) error {
    switch e := err.(type) {
    case *errors.NotFoundError:
        return c.Status(fiber.StatusNotFound).JSON(e)
    case *errors.ValidationError:
        return c.Status(fiber.StatusBadRequest).JSON(e)
    default:
        return c.Status(fiber.StatusInternalServerError).JSON(
            errors.NewInternalError("internal server error"),
        )
    }
}
```

2. Service Pattern:
```go
package services

import (
    "context"
    "github.com/username/project/internal/models"
    "github.com/username/project/internal/repositories"
    "github.com/username/project/pkg/errors"
    "go.uber.org/zap"
)

type UserService interface {
    Create(ctx context.Context, input models.CreateUserInput) (*models.User, error)
    GetByID(ctx context.Context, id string) (*models.User, error)
    Update(ctx context.Context, id string, input models.UpdateUserInput) (*models.User, error)
    Delete(ctx context.Context, id string) error
}

type userService struct {
    repo   repositories.UserRepository
    logger *zap.Logger
}

func NewUserService(repo repositories.UserRepository, logger *zap.Logger) UserService {
    return &userService{
        repo:   repo,
        logger: logger,
    }
}

func (s *userService) Create(ctx context.Context, input models.CreateUserInput) (*models.User, error) {
    // Check if user exists
    exists, err := s.repo.ExistsByEmail(ctx, input.Email)
    if err != nil {
        return nil, err
    }
    if exists {
        return nil, errors.NewValidationError("email already exists")
    }
    
    // Create user
    user := &models.User{
        Email:    input.Email,
        Name:     input.Name,
        Password: input.Password,
    }
    
    if err := user.HashPassword(); err != nil {
        return nil, err
    }
    
    if err := s.repo.Create(ctx, user); err != nil {
        return nil, err
    }
    
    return user, nil
}

func (s *userService) GetByID(ctx context.Context, id string) (*models.User, error) {
    user, err := s.repo.GetByID(ctx, id)
    if err != nil {
        return nil, err
    }
    if user == nil {
        return nil, errors.NewNotFoundError("user not found")
    }
    return user, nil
}
```

3. Repository Pattern:
```go
package repositories

import (
    "context"
    "gorm.io/gorm"
    "github.com/username/project/internal/models"
)

type UserRepository interface {
    Create(ctx context.Context, user *models.User) error
    GetByID(ctx context.Context, id string) (*models.User, error)
    ExistsByEmail(ctx context.Context, email string) (bool, error)
    Update(ctx context.Context, user *models.User) error
    Delete(ctx context.Context, id string) error
}

type userRepository struct {
    db *gorm.DB
}

func NewUserRepository(db *gorm.DB) UserRepository {
    return &userRepository{db: db}
}

func (r *userRepository) Create(ctx context.Context, user *models.User) error {
    return r.db.WithContext(ctx).Create(user).Error
}

func (r *userRepository) GetByID(ctx context.Context, id string) (*models.User, error) {
    var user models.User
    err := r.db.WithContext(ctx).First(&user, "id = ?", id).Error
    if err == gorm.ErrRecordNotFound {
        return nil, nil
    }
    if err != nil {
        return nil, err
    }
    return &user, nil
}

func (r *userRepository) ExistsByEmail(ctx context.Context, email string) (bool, error) {
    var count int64
    err := r.db.WithContext(ctx).Model(&models.User{}).
        Where("email = ?", email).
        Count(&count).
        Error
    return count > 0, err
}
```

// Best Practices:
1. Code Quality:
   - Documentation
   - Error handling
   - Testing
   - Logging
   - Validation
   - Interfaces

2. Architecture:
   - Clean architecture
   - Dependency injection
   - Repository pattern
   - Service layer
   - Middleware
   - Error handling

3. Performance:
   - Goroutines
   - Connection pools
   - Query optimization
   - Caching
   - Memory usage
   - Monitoring

4. Security:
   - Authentication
   - Authorization
   - Input validation
   - Rate limiting
   - CORS policy
   - Secure headers

// Security Considerations:
1. API Security:
   - Input validation
   - Rate limiting
   - Authentication
   - Authorization
   - CORS policy
   - Security headers

2. Data Security:
   - Password hashing
   - Data encryption
   - SQL injection
   - XSS prevention
   - CSRF protection
   - Access control

3. Infrastructure:
   - HTTPS
   - TLS config
   - Firewalls
   - Monitoring
   - Logging
   - Backups 