242 lines
7.1 KiB
Markdown
242 lines
7.1 KiB
Markdown
|
|
# 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!** ๐
|