Documentation

Maestro Pattern

Overview

The Maestro Pattern is the core business logic orchestration pattern in this framework. It provides a structured approach to implementing complex business operations through sequential step execution with clear input/output contracts.

Pattern Principles

Single Responsibility

Each Mae (Maestro module) handles one specific business operation: - CreateGardenMae - Creates a new garden - UpdateUserProfileMae - Updates user profile information - ProcessOrderMae - Handles order processing workflow

Sequential Execution

Mae modules execute business logic in defined sequential steps: 1. Validation - Input validation and business rule checking 2. Preparation - Data transformation and preparation 3. Persistence - Database operations and state changes 4. Post-Processing - Notifications, logging, cleanup 5. Response - Result formatting and return

Explicit Contracts

Mae modules define clear input and output contracts:

type CreateGardenMaeInput struct {
    Form *forms.CreateGardenForm
    UserId string
}

type CreateGardenMaeOutput struct {
    Garden *mdl.Garden
    Success bool
}

Mae Structure

Basic Mae Template

package mae

type CreateGardenMae struct {
    // Service dependencies
    GardenFetcher   *fetchers.GardenFetcher
    GardenHandler   *handlers.GardenHandler
    GardenMolder    *molders.CreateGardenFormMolder
    UserFetcher     *fetchers.UserFetcher

    // Utility dependencies
    Logger *logger.Logger
    Time   time.Time
}

func (this *CreateGardenMae) Execute(ctx context.Context, input *maes.CreateGardenMaeInput) (*maes.CreateGardenMaeOutput, error) {
    // Step 1: Validate input
    if err := this.validateInput(input); err != nil {
        return nil, err
    }

    // Step 2: Check business rules
    if err := this.checkBusinessRules(ctx, input); err != nil {
        return nil, err
    }

    // Step 3: Transform data
    garden := this.prepareGarden(input)

    // Step 4: Persist to database
    createdGarden, err := this.GardenHandler.Create(ctx, garden, nil)
    if err != nil {
        return nil, err
    }

    // Step 5: Post-processing
    this.Logger.Info("Garden created successfully", "garden_id", createdGarden.Id)

    return &maes.CreateGardenMaeOutput{
        Garden:  createdGarden,
        Success: true,
    }, nil
}

Step Methods

Mae modules break down execution into focused step methods:

func (this *CreateGardenMae) validateInput(input *maes.CreateGardenMaeInput) error {
    if input.Form == nil {
        return erro.N("Form is required")
    }

    if input.Form.Name == "" {
        return erro.N("Garden name is required")
    }

    if input.UserId == "" {
        return erro.N("User ID is required")
    }

    return nil
}

func (this *CreateGardenMae) checkBusinessRules(ctx context.Context, input *maes.CreateGardenMaeInput) error {
    // Check if user exists
    user, exists, err := this.UserFetcher.FindOneById(ctx, input.UserId, nil)
    if err != nil {
        return err
    }
    if !exists {
        return erro.N("User not found")
    }

    // Check user's garden limit
    mod := this.GardenFetcher.Mod()
    mod.ExactStringValueFilter("user_id", input.UserId)
    gardens, err := this.GardenFetcher.FindAll(ctx, mod)
    if err != nil {
        return err
    }

    if len(gardens) >= user.MaxGardens {
        return erro.N("User has reached maximum garden limit")
    }

    return nil
}

func (this *CreateGardenMae) prepareGarden(input *maes.CreateGardenMaeInput) *mdl.Garden {
    garden := &mdl.Garden{}
    garden, _ = this.GardenMolder.ToEntity(input.Form, garden)
    garden.UserId = input.UserId
    garden.CreatedAt = this.Time.Now()
    garden.UpdatedAt = this.Time.Now()
    return garden
}

Mae Input/Output Structures

Input Structure Pattern

// src/dat/maes/create_garden_mae.go
package maes

type CreateGardenMaeInput struct {
    Form   *forms.CreateGardenForm  // User input
    UserId string                   // Context data
    Options *CreateGardenOptions    // Operation options (optional)
}

type CreateGardenOptions struct {
    SkipValidation bool
    SendEmail      bool
    CreateDefault  bool
}

Output Structure Pattern

type CreateGardenMaeOutput struct {
    Garden    *mdl.Garden           // Primary result
    Success   bool                  // Operation success flag
    Messages  []string              // User messages
    Metadata  map[string]interface{} // Additional data
}

Advanced Mae Patterns

Transaction Management

func (this *CreateGardenWithPlantsMae) Execute(ctx context.Context, input *maes.CreateGardenWithPlantsMaeInput) (*maes.CreateGardenWithPlantsMaeOutput, error) {
    // Begin transaction
    tx, err := this.SqlDb.Begin(ctx)
    if err != nil {
        return nil, err
    }
    defer tx.Rollback() // Will be no-op if committed

    // Step 1: Create garden
    handlerMod := &handler.HandlerMod{Tx: tx}
    garden, err := this.GardenHandler.Create(ctx, input.Garden, handlerMod)
    if err != nil {
        return nil, err
    }

    // Step 2: Create plants
    for _, plantForm := range input.PlantForms {
        plant := this.preparePlant(plantForm, garden.Id)
        _, err := this.PlantHandler.Create(ctx, plant, handlerMod)
        if err != nil {
            return nil, err
        }
    }

    // Commit transaction
    if err := tx.Commit(); err != nil {
        return nil, err
    }

    return &maes.CreateGardenWithPlantsMaeOutput{
        Garden:  garden,
        Success: true,
    }, nil
}

Cross-Entity Operations

func (this *TransferGardenOwnershipMae) Execute(ctx context.Context, input *maes.TransferGardenOwnershipMaeInput) (*maes.TransferGardenOwnershipMaeOutput, error) {
    // Step 1: Validate both users exist
    currentOwner, err := this.validateUser(ctx, input.CurrentOwnerId)
    if err != nil {
        return nil, err
    }

    newOwner, err := this.validateUser(ctx, input.NewOwnerId)
    if err != nil {
        return nil, err
    }

    // Step 2: Validate garden ownership
    garden, err := this.validateGardenOwnership(ctx, input.GardenId, input.CurrentOwnerId)
    if err != nil {
        return nil, err
    }

    // Step 3: Check new owner capacity
    if err := this.checkOwnerCapacity(ctx, input.NewOwnerId); err != nil {
        return nil, err
    }

    // Step 4: Transfer ownership
    garden.UserId = input.NewOwnerId
    updatedGarden, err := this.GardenHandler.Update(ctx, garden, nil)
    if err != nil {
        return nil, err
    }

    // Step 5: Update related entities
    if err := this.updateRelatedEntities(ctx, garden.Id, input.NewOwnerId); err != nil {
        return nil, err
    }

    // Step 6: Send notifications
    this.sendTransferNotifications(ctx, currentOwner, newOwner, garden)

    return &maes.TransferGardenOwnershipMaeOutput{
        Garden:      updatedGarden,
        PreviousOwner: currentOwner,
        NewOwner:    newOwner,
        Success:     true,
    }, nil
}

Mae Composition

func (this *CompleteGardenSetupMae) Execute(ctx context.Context, input *maes.CompleteGardenSetupMaeInput) (*maes.CompleteGardenSetupMaeOutput, error) {
    // Step 1: Create garden
    createGardenOutput, err := this.CreateGardenMae.Execute(ctx, &maes.CreateGardenMaeInput{
        Form:   input.GardenForm,
        UserId: input.UserId,
    })
    if err != nil {
        return nil, err
    }

    // Step 2: Add default plants
    for _, plantForm := range input.DefaultPlants {
        plantForm.GardenId = createGardenOutput.Garden.Id
        _, err := this.CreatePlantMae.Execute(ctx, &maes.CreatePlantMaeInput{
            Form: plantForm,
        })
        if err != nil {
            // Log error but continue
            this.Logger.Error("Failed to create default plant", "error", err)
        }
    }

    // Step 3: Setup garden tasks
    if err := this.setupDefaultTasks(ctx, createGardenOutput.Garden.Id); err != nil {
        this.Logger.Error("Failed to setup default tasks", "error", err)
    }

    return &maes.CompleteGardenSetupMaeOutput{
        Garden:  createGardenOutput.Garden,
        Success: true,
    }, nil
}

Error Handling in Maes

Structured Error Response

type MaeError struct {
    Code     string                 `json:"code"`
    Message  string                 `json:"message"`
    Field    string                 `json:"field,omitempty"`
    Context  map[string]interface{} `json:"context,omitempty"`
}

func (this *CreateGardenMae) validateBusinessRules(ctx context.Context, input *maes.CreateGardenMaeInput) error {
    // Check garden name uniqueness
    existing, _, err := this.GardenFetcher.FindByName(ctx, input.Form.Name, nil)
    if err != nil {
        return &MaeError{
            Code:    "database_error",
            Message: "Failed to check garden name uniqueness",
            Context: map[string]interface{}{
                "operation": "find_by_name",
                "name":      input.Form.Name,
            },
        }
    }

    if existing != nil {
        return &MaeError{
            Code:    "validation_error",
            Message: "Garden name already exists",
            Field:   "name",
            Context: map[string]interface{}{
                "existing_id": existing.Id,
            },
        }
    }

    return nil
}

Mae Testing Patterns

Unit Testing Structure

func TestCreateGardenMae_Success(t *testing.T) {
    // Arrange
    ctx := context.Background()
    mae := setupCreateGardenMae(t)

    input := &maes.CreateGardenMaeInput{
        Form: &forms.CreateGardenForm{
            Name:        "Test Garden",
            Description: "A test garden",
        },
        UserId: "user123",
    }

    // Act
    output, err := mae.Execute(ctx, input)

    // Assert
    require.NoError(t, err)
    assert.True(t, output.Success)
    assert.Equal(t, "Test Garden", output.Garden.Name)
    assert.NotEmpty(t, output.Garden.Id)
}

func TestCreateGardenMae_ValidationError(t *testing.T) {
    // Arrange
    mae := setupCreateGardenMae(t)
    input := &maes.CreateGardenMaeInput{
        Form: &forms.CreateGardenForm{
            Name: "", // Invalid: empty name
        },
        UserId: "user123",
    }

    // Act
    output, err := mae.Execute(context.Background(), input)

    // Assert
    assert.Error(t, err)
    assert.Nil(t, output)
    assert.Contains(t, err.Error(), "name is required")
}

Integration Testing

func TestCreateGardenMae_Integration(t *testing.T) {
    // Setup real database and services
    db := setupTestDatabase(t)
    container := setupTestContainer(t, db)
    mae := container.CreateGardenMae

    // Test complete flow
    input := createValidInput()
    output, err := mae.Execute(context.Background(), input)

    // Verify database state
    garden := mustFindGardenInDb(t, db, output.Garden.Id)
    assert.Equal(t, input.Form.Name, garden.Name)
}

Mae Best Practices

Design Guidelines

  1. Single Business Operation - Each Mae handles one coherent business operation
  2. Clear Steps - Break complex operations into focused step methods
  3. Input Validation - Always validate input early and comprehensively
  4. Error Context - Provide detailed error context for debugging
  5. Transaction Boundaries - Use transactions for multi-entity operations

Implementation Guidelines

  1. Dependency Injection - Inject all required services through constructor
  2. Context Propagation - Pass context through all service calls
  3. Logging - Log significant operations and errors
  4. Testing - Write both unit and integration tests
  5. Documentation - Document business rules and edge cases

Performance Considerations

  1. Batch Operations - Use batch operations when processing multiple entities
  2. Lazy Loading - Only load data that’s actually needed
  3. Connection Management - Proper database connection handling
  4. Memory Management - Avoid holding large datasets in memory

LLM Mae Development Notes

When implementing Mae modules: - Start with input/output structure definition - Break complex operations into sequential steps - Always validate input and business rules - Use explicit error types with context - Test both success and failure scenarios - Follow transaction patterns for data consistency - Compose Maes for complex workflows