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
Core Packages
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
internal/api
HTTP server setup and route configuration
api.go- API configuration and service initializationroutes.go- Route definitions and middleware chaining
internal/handler
HTTP request handlers for all endpointsKey files:
handler.go- Base handler struct with shared dependencieshandler_health.go- Health check endpointhandler_oauth.go- OAuth2 login and callbackhandler_reservations.go- Reservation CRUD operationsparser.go- Request parsing utilitiesresponse.go- Response formatting helpers
internal/auth
JWT-based authentication system
- Token generation and verification
- Bearer token extraction
- User context management
- 1-hour access token TTL
internal/middleware
HTTP middleware components
auth.go- Authentication middlewareratelimit.go- Rate limiting protection
internal/database
Database layer with type-safe queries
connection.go- PostgreSQL connection pooldb.go- Database interfacemodels.go- Data models*.sql.go- SQLC-generated query code
internal/service
Business logic layer
- Reservation validation and creation
- Conflict detection
- Business rule enforcement
Database Layer
Schema Files (sql/schema/)
Migration files applied in order:
001_users.sql- User accounts and authentication002_rooms.sql- Meeting room definitions003_reservations.sql- Booking records004_populate_rooms.sql- Initial room data
Query Files (sql/queries/)
SQL queries for SQLC code generation:
users.sql- User CRUD operationsrooms.sql- Room queriesreservations.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
Thesqlc.yaml file configures code generation:
internal/database/db.gointernal/database/models.gointernal/database/users.sql.gointernal/database/rooms.sql.gointernal/database/reservations.sql.go
Configuration Management
Environment Variables
Configuration is loaded from.env via internal/config/config.go:
Design Patterns
Handler Pattern
All HTTP handlers share a common structure:Middleware Chain
Requests flow through middleware layers:- Rate limiting (global)
- Authentication (extracts JWT)
- Authorization (requires valid user)
- Handler (business logic)
Error Handling
Custom error types per package:internal/auth/auth.go-ErrExpiredToken,ErrNoAuthHeaderIncludedinternal/service/errors.go- Business logic errorsinternal/oauth/errors.go- OAuth-specific errorsinternal/validator/errors.go- Validation errors
Testing Structure
Test files are located alongside their implementation:internal/auth/auth_test.go- JWT token testsinternal/middleware/auth_test.go- Auth middleware testsinternal/middleware/ratelimit_test.go- Rate limiting testsinternal/handler/parser_test.go- Request parsing testsinternal/validator/validator_test.go- Input validation testsinternal/email/email_service_test.go- Email service testsinternal/google/calendar_test.go- Google Calendar tests
Key Files Reference
| File | Purpose | Line Reference |
|---|---|---|
cmd/server/main.go | Application entry point | Main at :22 |
internal/api/routes.go | Route definitions | All HTTP routes |
internal/handler/handler_reservations.go | Reservation endpoints | CRUD handlers |
internal/auth/auth.go | JWT authentication | Token generation |
internal/database/connection.go | DB connection pool | PostgreSQL setup |
sqlc.yaml | SQLC configuration | Code generation |
.golangci.yml | Linter configuration | Code quality rules |
Next Steps
- Building the Project - Learn how to build and run BookMe
- Testing Guide - Understand the testing approach
- Contributing - Start contributing to the project