# Internal Architecture This document describes the clean architecture implementation for the POS backend with complete separation of concerns between database entities, business models, and constants. ## ๐Ÿ“ Package Structure ### `/constants` - Business Constants - **Purpose**: All business logic constants, enums, and validation helpers - **Usage**: Used by models, services, and validation layers - **Features**: - Type-safe enums (UserRole, OrderStatus, PaymentStatus, etc.) - Business validation functions (IsValidUserRole, etc.) - Default values and limits - No dependencies on database or frameworks ### `/entities` - Database Models - **Purpose**: Database-specific models with GORM tags and hooks - **Usage**: **ONLY** used by repository layer for database operations - **Features**: - GORM annotations (`gorm:` tags) - Database relationships and constraints - BeforeCreate/AfterCreate hooks - Table name specifications - SQL-specific data types - **Never used in business logic** ### `/models` - Business Models - **Purpose**: **Pure** business domain models without any framework dependencies - **Usage**: Used by services, handlers, and business logic - **Features**: - Clean JSON serialization (`json:` tags) - Validation rules (`validate:` tags) - Request/Response DTOs - **Zero GORM dependencies** - **Zero database annotations** - Uses constants package for type safety - Pure business logic methods ### `/mappers` - Data Transformation - **Purpose**: Convert between entities and business models - **Usage**: Bridge between repository and service layers - **Features**: - Entity โ†” Model conversion functions - Request DTO โ†’ Entity conversion - Entity โ†’ Response DTO conversion - Null-safe conversions - Slice/collection conversions - Type conversions between constants and entities ### `/repository` - Data Access Layer - **Purpose**: Database operations using entities exclusively - **Usage**: Only works with database entities - **Features**: - CRUD operations with entities - Query methods with entities - **Private repository implementations** - Interface-based contracts - **Never references business models** ## ๐Ÿ”„ Data Flow ``` API Request (JSON) โ†“ Request DTO (models) โ†“ Business Logic (services with models + constants) โ†“ Entity (via mapper) โ†“ Repository Layer (entities only) โ†“ Database โ†“ Entity (from database) โ†“ Business Model (via mapper) โ†“ Response DTO (models) โ†“ API Response (JSON) ``` ## ๐ŸŽฏ Key Design Principles ### โœ… **Clean Business Models** ```go type User struct { ID uuid.UUID `json:"id"` Role constants.UserRole `json:"role"` } ``` ```go type User struct { ID uuid.UUID `gorm:"primaryKey" json:"id"` Role string `gorm:"size:50" json:"role"` } ``` ### โœ… **Type-Safe Constants** ```go type UserRole string const ( RoleAdmin UserRole = "admin" ) func IsValidUserRole(role UserRole) bool { /* ... */ } ``` ```go const AdminRole = "admin" ``` ### โœ… **Repository Isolation** ```go func (r *userRepository) Create(ctx context.Context, user *entities.User) error { return r.db.Create(user).Error } ``` ```go func (r *userRepository) Create(ctx context.Context, user *models.User) error { } ``` ## ๐Ÿ“Š Example Usage ### Service Layer (Business Logic) ```go func (s *userService) CreateUser(req *models.UserCreateRequest) (*models.UserResponse, error) { if !constants.IsValidUserRole(req.Role) { return nil, errors.New("invalid role") } entity := mappers.UserCreateRequestToEntity(req, hashedPassword) err := s.userRepo.Create(ctx, entity) if err != nil { return nil, err } return mappers.UserEntityToResponse(entity), nil } ``` ### Repository Layer (Data Access) ```go func (r *userRepository) Create(ctx context.Context, user *entities.User) error { return r.db.WithContext(ctx).Create(user).Error } ``` ### Handler Layer (API) ```go func (h *userHandler) CreateUser(c *gin.Context) { var req models.UserCreateRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } resp, err := h.userService.CreateUser(&req) if err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(201, resp) } ``` ## ๐Ÿ—๏ธ Architecture Benefits 1. **๐ŸŽฏ Single Responsibility**: Each package has one clear purpose 2. **๐Ÿ”’ Zero Database Leakage**: Business logic never sees database concerns 3. **๐Ÿงช Testability**: Easy to mock interfaces and test business logic 4. **๐Ÿ”ง Maintainability**: Changes to database don't affect business models 5. **๐Ÿš€ Flexibility**: Can change ORM without touching business logic 6. **๐Ÿ“œ API Stability**: Business models provide stable contracts 7. **๐Ÿ›ก๏ธ Type Safety**: Constants package prevents invalid states 8. **๐Ÿงน Clean Code**: No mixed concerns anywhere in the codebase ## ๐Ÿ“‹ Development Guidelines ### Constants Package (`/constants`) - โœ… Define all business enums and constants - โœ… Provide validation helper functions - โœ… Include default values and limits - โŒ Never import database or framework packages - โŒ No business logic, only constants and validation ### Models Package (`/models`) - โœ… Pure business structs with JSON tags only - โœ… Use constants package for type safety - โœ… Include validation tags for input validation - โœ… Separate Request/Response DTOs - โœ… Add business logic methods (validation, calculations) - โŒ **NEVER** include GORM tags or database annotations - โŒ **NEVER** import database packages - โŒ No database relationships or foreign keys ### Entities Package (`/entities`) - โœ… Include GORM tags and database constraints - โœ… Define relationships and foreign keys - โœ… Add database hooks (BeforeCreate, etc.) - โœ… Use database-specific types - โŒ **NEVER** use in business logic or handlers - โŒ **NEVER** add business validation rules ### Mappers Package (`/mappers`) - โœ… Always check for nil inputs - โœ… Handle type conversions between constants and strings - โœ… Provide slice conversion helpers - โœ… Keep conversions simple and direct - โŒ No business logic in mappers - โŒ No database operations ### Repository Package (`/repository`) - โœ… Work exclusively with entities - โœ… Use private repository implementations - โœ… Provide clean interface contracts - โŒ **NEVER** reference business models - โŒ **NEVER** import models package ## ๐Ÿš€ Migration Complete **All packages have been successfully reorganized:** - โœ… **4 Constants files** - All business constants moved to type-safe enums - โœ… **10 Clean Model files** - Zero GORM dependencies, pure business logic - โœ… **11 Entity files** - Database-only models with GORM tags - โœ… **11 Repository files** - Updated to use entities exclusively - โœ… **2 Mapper files** - Handle conversions between layers - โœ… **Complete separation** - No cross-layer dependencies **The codebase now follows strict clean architecture principles with complete separation of database concerns from business logic!** ๐ŸŽ‰