Skip to main content

Overview

BookMe follows a clean, modular architecture with clear separation of concerns. The project uses Go’s standard layout conventions with internal packages for business logic and cmd for application entry points.

Directory Structure

book-me/
├── cmd/                    # Application entry points
   └── server/
       └── main.go        # Main application entry point
├── internal/              # Private application code
   ├── api/              # API server setup and routing
   ├── auth/             # JWT authentication logic
   ├── config/           # Configuration management
   ├── database/         # Database connection and queries
   ├── dto/              # Data transfer objects
   ├── email/            # Email service and templates
   ├── google/           # Google Calendar integration
   ├── handler/          # HTTP request handlers
   ├── logger/           # Logging utilities
   ├── middleware/       # HTTP middleware
   ├── oauth/            # OAuth2 authentication
   ├── service/          # Business logic layer
   └── validator/        # Input validation
├── sql/                   # Database schema and queries
   ├── queries/          # SQL queries for SQLC
   └── schema/           # Database migrations
├── assets/                # Static assets
├── docs/                  # Project documentation
└── Configuration files

Core Packages

1

cmd/server

Application entry point located at cmd/server/main.go:1
  • Initializes configuration from environment
  • Sets up database connection
  • Configures API routes and middleware
  • Manages graceful shutdown with 15-second timeout
2

internal/api

HTTP server setup and route configuration
  • api.go - API configuration and service initialization
  • routes.go - Route definitions and middleware chaining
3

internal/handler

HTTP request handlers for all endpointsKey files:
  • handler.go - Base handler struct with shared dependencies
  • handler_health.go - Health check endpoint
  • handler_oauth.go - OAuth2 login and callback
  • handler_reservations.go - Reservation CRUD operations
  • parser.go - Request parsing utilities
  • response.go - Response formatting helpers
4

internal/auth

JWT-based authentication system
  • Token generation and verification
  • Bearer token extraction
  • User context management
  • 1-hour access token TTL
5

internal/middleware

HTTP middleware components
  • auth.go - Authentication middleware
  • ratelimit.go - Rate limiting protection
6

internal/database

Database layer with type-safe queries
  • connection.go - PostgreSQL connection pool
  • db.go - Database interface
  • models.go - Data models
  • *.sql.go - SQLC-generated query code
7

internal/service

Business logic layer
  • Reservation validation and creation
  • Conflict detection
  • Business rule enforcement
8

internal/oauth

42 Intra OAuth2 integration
  • provider42.go - 42 OAuth provider implementation
  • service.go - OAuth service orchestration
  • errors.go - OAuth-specific errors

Database Layer

Schema Files (sql/schema/)

Migration files applied in order:
  1. 001_users.sql - User accounts and authentication
  2. 002_rooms.sql - Meeting room definitions
  3. 003_reservations.sql - Booking records
  4. 004_populate_rooms.sql - Initial room data

Query Files (sql/queries/)

SQL queries for SQLC code generation:
  • users.sql - User CRUD operations
  • rooms.sql - Room queries
  • reservations.sql - Reservation management
SQLC generates type-safe Go code from SQL queries. After modifying .sql files in sql/queries/, run make sqlc to regenerate the database layer code in internal/database/.

Code Generation

SQLC Configuration

The sqlc.yaml file configures code generation:
version: "2"
sql:
  - schema: "sql/schema"
    queries: "sql/queries"
    engine: "postgresql"
    gen:
      go:
        out: "internal/database"
Generated files:
  • internal/database/db.go
  • internal/database/models.go
  • internal/database/users.sql.go
  • internal/database/rooms.sql.go
  • internal/database/reservations.sql.go

Configuration Management

Environment Variables

Configuration is loaded from .env via internal/config/config.go:
PORT=8080
SERVER_READ_TIMEOUT=15s
SERVER_WRITE_TIMEOUT=15s
SERVER_IDLE_TIMEOUT=60s
LOG_LEVEL=info

Design Patterns

Handler Pattern

All HTTP handlers share a common structure:
type APIHandler struct {
    db          *database.Queries
    authService *auth.Service
    // ... other services
}

func (h *APIHandler) HandleSomething(w http.ResponseWriter, r *http.Request) {
    // Request handling logic
}

Middleware Chain

Requests flow through middleware layers:
  1. Rate limiting (global)
  2. Authentication (extracts JWT)
  3. Authorization (requires valid user)
  4. Handler (business logic)

Error Handling

Custom error types per package:
  • internal/auth/auth.go - ErrExpiredToken, ErrNoAuthHeaderIncluded
  • internal/service/errors.go - Business logic errors
  • internal/oauth/errors.go - OAuth-specific errors
  • internal/validator/errors.go - Validation errors

Testing Structure

Test files are located alongside their implementation:
  • internal/auth/auth_test.go - JWT token tests
  • internal/middleware/auth_test.go - Auth middleware tests
  • internal/middleware/ratelimit_test.go - Rate limiting tests
  • internal/handler/parser_test.go - Request parsing tests
  • internal/validator/validator_test.go - Input validation tests
  • internal/email/email_service_test.go - Email service tests
  • internal/google/calendar_test.go - Google Calendar tests
Run make test to execute all tests with verbose output. Use make test-coverage to generate an HTML coverage report.

Key Files Reference

FilePurposeLine Reference
cmd/server/main.goApplication entry pointMain at :22
internal/api/routes.goRoute definitionsAll HTTP routes
internal/handler/handler_reservations.goReservation endpointsCRUD handlers
internal/auth/auth.goJWT authenticationToken generation
internal/database/connection.goDB connection poolPostgreSQL setup
sqlc.yamlSQLC configurationCode generation
.golangci.ymlLinter configurationCode quality rules

Next Steps

Build docs developers (and LLMs) love