# Service Layer Architecture

## Overview

The service layer provides a comprehensive, standardized approach to handling all aspects of domain entity operations. Each entity receives a complete suite of specialized services that work together to handle different concerns.

## Service Types

Every domain entity has these service types:

### Data Services
- **Fetchers** - Data retrieval with filtering, pagination, and querying
- **Handlers** - CRUD operations with transaction support and validation
- **Tables** - Database-to-entity mapping with ESO (Entity Storage Object) pattern

### Transformation Services  
- **Molders** - Form-to-entity transformation with change detection
- **Serializers** - Entity-to-JSON conversion for API responses
- **Stringers** - Entity-to-string conversion for display purposes

### Relationship Services
- **Hydrators** - Relationship loading with preset configurations
- **Relationers** - Batch relationship loading to prevent N+1 queries

### Specialized Services
- **Searchers** - Full-text search capabilities with indexing
- **Validators** - Business rule validation
- **Policies** - Access control and authorization

## Service Architecture Pattern

### Complete Service Suite
```go
// Example for Garden entity
type GardenServices struct {
    // Core data services
    GardenFetcher    *fetchers.GardenFetcher
    GardenHandler    *handlers.GardenHandler  
    GardenTable      *tables.GardenTable
    
    // Transformation services
    GardenMolder     *molders.CreateGardenFormMolder
    GardenSerializer *serializers.GardenSerializer
    GardenStringer   *stringers.GardenStringer
    
    // Relationship services
    GardenHydrator   *hydrators.GardenHydrator
    GardenRelationer *relationers.GardenRelationer
    
    // Specialized services
    GardenSearcher   *searchers.GardenSearcher
    GardenValidator  *validators.GardenValidator
}
```

### Service Interaction Patterns

#### Create Operation Flow
```
Form → Validator → Molder → Handler → Table → Database
                              ↓
                           Entity
                              ↓  
                         Serializer → JSON Response
```

#### Read Operation Flow
```
Query → Fetcher → Table → Entity → Hydrator → Relationer
                             ↓           ↓
                        Serializer  String Representation
```

#### Update Operation Flow
```
Form → Validator → Molder → Handler → Table → Database
  ↓                   ↓
Change Detection  Transaction Management
```

## Service Implementation Standards

### Interface Consistency
All services of the same type follow identical interface patterns:

```go
// Fetcher interface pattern (example)
type EntityFetcher interface {
    FindAll(ctx context.Context, mod *fetcher.FetcherMod) ([]*Entity, error)
    FindOne(ctx context.Context, mod *fetcher.FetcherMod) (*Entity, bool, error)
    FindOneById(ctx context.Context, id string, mod *fetcher.FetcherMod) (*Entity, bool, error)
    FindPage(ctx context.Context, mod *fetcher.FetcherMod) ([]*Entity, *fetcher.FetcherPagination, error)
}

// Handler interface pattern (example)
type EntityHandler interface {
    Create(ctx context.Context, entity *Entity, mod *handler.HandlerMod) (*Entity, error)
    Update(ctx context.Context, entity *Entity, mod *handler.HandlerMod) (*Entity, error)
    Delete(ctx context.Context, entity *Entity, mod *handler.HandlerMod) error
}
```

### Dependency Injection
Services are wired together through explicit dependency injection:

```go
type GardenFetcher struct {
    Fetcher     *fetcher.Fetcher     // Base functionality
    GardenTable *tables.GardenTable // Entity mapping
}

type GardenHandler struct {
    Handler     *handler.Handler     // Base functionality
    GardenTable *tables.GardenTable // Entity mapping
    Spy         *spy.Spy            // Operation logging
    Time        time.Time           // Time utilities
}
```

## Service Composition Patterns

### Layered Service Usage
```go
// Mae uses multiple services in coordination
func (this *CreateGardenMae) Execute(ctx context.Context, input *CreateGardenMaeInput) (*CreateGardenMaeOutput, error) {
    // 1. Form validation
    if err := this.GardenValidator.ValidateCreateForm(input.Form); err != nil {
        return nil, err
    }
    
    // 2. Transform form to entity
    garden := &mdl.Garden{}
    garden, changes := this.GardenMolder.ToEntity(input.Form, garden)
    
    // 3. Persist entity
    createdGarden, err := this.GardenHandler.Create(ctx, garden, nil)
    if err != nil {
        return nil, err
    }
    
    // 4. Load relationships if needed
    if input.IncludeRelationships {
        err := this.GardenHydrator.OneViaPreset(ctx, createdGarden, "show", nil)
        if err != nil {
            return nil, err
        }
    }
    
    return &CreateGardenMaeOutput{
        Garden: createdGarden,
    }, nil
}
```

### Service Chaining
```go
// Services can be chained for complex operations
func (this *GardenController) List(c *gin.Context) {
    // 1. Fetch entities
    gardens, pagination, err := this.GardenFetcher.FindPage(c, mod)
    if err != nil {
        c.JSON(500, gin.H{"error": err.Error()})
        return
    }
    
    // 2. Hydrate relationships
    err = this.GardenHydrator.ManyViaPreset(c, gardens, "list", nil)
    if err != nil {
        c.JSON(500, gin.H{"error": err.Error()})
        return
    }
    
    // 3. Serialize for response
    jsonData, err := this.GardenSerializer.SetToJson(gardens)
    if err != nil {
        c.JSON(500, gin.H{"error": err.Error()})
        return
    }
    
    c.Data(200, "application/json", jsonData)
}
```

## Service Configuration Patterns

### Modifier Objects
Services use modifier objects to configure operations:

```go
// Fetcher modification
mod := gardenFetcher.Mod()
mod.ExactStringValueFilter("user_id", "123")
mod.DescOrder("created_at")
mod.Page = 1
mod.PerPage = 25

// Handler modification
handlerMod := &handler.HandlerMod{
    Tx: transaction,        // Use existing transaction
    Fields: []string{"name", "description"}, // Partial update
}

// Hydrator modification
hydratorMod := &hydrator.HydratorMod{}
hydratorMod.AddHydratingPath("plants")
hydratorMod.AddHydratingPath("garden_tasks", "assignee")
```

### Service Presets
Services can define preset configurations:

```go
// Hydrator presets
func (this *GardenHydrator) OneViaPreset(ctx context.Context, entity *mdl.Garden, preset string, mod *hydrator.HydratorMod) error {
    mod = this.Hydrator.ModDefaulting(mod)
    
    switch preset {
    case "show":
        mod.AddHydratingPath("plants")
        mod.AddHydratingPath("garden_tasks")
        mod.AddHydratingPath("plantations", "plants")
    case "list":
        mod.AddHydratingPath("user")
    case "api":
        mod.AddHydratingPath("plants", "plant_tasks")
    }
    
    return this.One(ctx, entity, mod)
}
```

## Error Handling in Services

### Service-Level Errors
```go
// Services return structured errors
type ServiceError struct {
    Service   string
    Operation string
    Message   string
    Cause     error
}

func (this *GardenFetcher) FindOneById(ctx context.Context, id string, mod *fetcher.FetcherMod) (*mdl.Garden, bool, error) {
    if id == "" {
        return nil, false, &ServiceError{
            Service:   "GardenFetcher",
            Operation: "FindOneById",
            Message:   "ID parameter is required",
        }
    }
    
    // ... implementation
}
```

### Error Propagation
```go
// Services propagate errors with context
func (this *CreateGardenMae) Execute(ctx context.Context, input *CreateGardenMaeInput) (*CreateGardenMaeOutput, error) {
    garden, err := this.GardenHandler.Create(ctx, entity, nil)
    if err != nil {
        return nil, fmt.Errorf("failed to create garden in CreateGardenMae: %w", err)
    }
    
    return output, nil
}
```

## Testing Service Layer

### Service Unit Testing
```go
func TestGardenHandler_Create(t *testing.T) {
    // Setup service with mock dependencies
    handler := &handlers.GardenHandler{
        Handler:     mockHandler,
        GardenTable: mockTable,
    }
    
    // Test creation
    garden := &mdl.Garden{Name: "Test Garden"}
    result, err := handler.Create(ctx, garden, nil)
    
    // Assertions
    require.NoError(t, err)
    assert.NotEmpty(t, result.Id)
    assert.Equal(t, "Test Garden", result.Name)
}
```

### Service Integration Testing
```go
func TestGardenServices_Integration(t *testing.T) {
    // Setup real database and services
    db := setupTestDatabase(t)
    services := setupGardenServices(t, db)
    
    // Test service interaction
    form := &forms.CreateGardenForm{Name: "Integration Test"}
    garden := &mdl.Garden{}
    garden, _ = services.GardenMolder.ToEntity(form, garden)
    
    created, err := services.GardenHandler.Create(ctx, garden, nil)
    require.NoError(t, err)
    
    found, exists, err := services.GardenFetcher.FindOneById(ctx, created.Id, nil)
    require.NoError(t, err)
    assert.True(t, exists)
    assert.Equal(t, created.Name, found.Name)
}
```

## Performance Considerations

### Service Optimization
1. **Batch Operations** - Use batch methods when available
2. **Connection Pooling** - Proper database connection management
3. **Query Optimization** - Efficient query patterns in Fetchers
4. **Memory Management** - Avoid loading large datasets unnecessarily
5. **Caching Strategy** - Cache frequently accessed data

### Monitoring and Observability
```go
// Services integrate with monitoring
type GardenHandler struct {
    Handler *handler.Handler
    Spy     *spy.Spy  // Operation logging
    Metrics *metrics.Metrics // Performance metrics
}

func (this *GardenHandler) Create(ctx context.Context, entity *mdl.Garden, mod *handler.HandlerMod) (*mdl.Garden, error) {
    start := time.Now()
    defer func() {
        this.Metrics.RecordDuration("garden.handler.create", time.Since(start))
    }()
    
    this.Spy.LogOperation(ctx, "GardenHandler.Create", entity.Id)
    
    // ... implementation
}
```

## LLM Service Development Notes

When working with the service layer:
1. **Complete Coverage** - Always implement full service suite for entities
2. **Consistent Interfaces** - Follow established patterns for each service type
3. **Explicit Dependencies** - Wire all dependencies through constructor injection
4. **Error Handling** - Provide structured errors with operation context
5. **Testing Strategy** - Test services both in isolation and integration
6. **Performance Awareness** - Consider query efficiency and resource usage
7. **Monitoring Integration** - Include logging and metrics in service operations