# 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!** 🎉 