# Request Lifecycle

## Overview

Understanding how requests flow through the framework is crucial for both debugging and development. This document traces the complete lifecycle of HTTP requests from arrival to response.

## Request Flow Architecture

```
HTTP Request
     ↓
Gin Router (Middleware Stack)
     ↓
Route Handler
     ↓
Controller Method
     ↓
Binder (Form/JSON extraction)
     ↓
Mae (Business Logic)
     ↓
Services (Fetchers, Handlers, etc.)
     ↓
Database Operations
     ↓
Response Formation (View/JSON)
     ↓
HTTP Response
```

## Detailed Request Lifecycle

### 1. HTTP Request Arrival
```go
// Gin receives the HTTP request
// Example: POST /gardens
```

### 2. Middleware Processing
```go
// Middleware stack executes in order
router.Use(middleware.Recovery())
router.Use(middleware.Logger())
router.Use(middleware.CORS())
router.Use(middleware.Authentication())
```

### 3. Route Matching
```go
// Route resolution based on method and path
gardens.POST("/", gardenController.Create)
gardens.GET("/:id", gardenController.Show)
gardens.PUT("/:id", gardenController.Update)
```

### 4. Controller Execution
```go
func (this *GardenController) Create(c *gin.Context) {
    // Extract and bind form data
    form := &forms.CreateGardenForm{}
    if err := this.GardenBinder.BindCreateForm(c, form); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    // Execute business logic
    output, err := this.CreateGardenMae.Execute(c.Request.Context(), &maes.CreateGardenMaeInput{
        Form:   form,
        UserId: this.getCurrentUserId(c),
    })

    if err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    // Format response
    c.JSON(201, gin.H{
        "garden": output.Garden,
        "success": true,
    })
}
```

### 5. Mae Business Logic
```go
func (this *CreateGardenMae) Execute(ctx context.Context, input *CreateGardenMaeInput) (*CreateGardenMaeOutput, error) {
    // Step 1: Validate
    if err := this.validateInput(input); err != nil {
        return nil, err
    }

    // Step 2: Transform
    garden := &mdl.Garden{}
    garden, _ = this.GardenMolder.ToEntity(input.Form, garden)

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

    return &CreateGardenMaeOutput{Garden: createdGarden}, nil
}
```

### 6. Service Layer Operations
```go
// Handler creates the entity
func (this *GardenHandler) Create(ctx context.Context, entity *mdl.Garden, mod *handler.HandlerMod) (*mdl.Garden, error) {
    // Set timestamps
    entity.CreatedAt = this.Time.Now()
    entity.UpdatedAt = this.Time.Now()

    // Use Table service for database operation
    values := this.GardenTable.EntityToValues(entity)
    id, _, err := this.Handler.Create(ctx, mod.Tx, this.GardenTable.TableName(), this.GardenTable.Columns(), values)
    if err != nil {
        return nil, err
    }

    entity.Id = id
    return entity, nil
}
```

### 7. Database Operations
```go
// SQL execution through SqlDb abstraction
func (this *SqlDb) Create(ctx context.Context, tx *sql.Tx, table string, columns []string, values []interface{}) (string, int, error) {
    query := this.buildInsertQuery(table, columns)

    var result sql.Result
    var err error

    if tx != nil {
        result, err = tx.ExecContext(ctx, query, values...)
    } else {
        result, err = this.db.ExecContext(ctx, query, values...)
    }

    if err != nil {
        return "", 0, err
    }

    // Return generated ID
    id, _ := result.LastInsertId()
    return fmt.Sprintf("%d", id), 1, nil
}
```

### 8. Response Formation
```go
// Controller formats final response
c.JSON(201, gin.H{
    "garden": output.Garden,
    "success": true,
})

// Or for HTML responses
c.HTML(200, "gardens/show.html", gin.H{
    "garden": garden,
    "title":  "Garden Details",
})
```

## Request Types and Patterns

### CRUD Operations

#### Create Request Flow
```
POST /gardens
├── GardenController.Create
├── CreateGardenMae.Execute
├── GardenHandler.Create
├── GardenTable.EntityToValues
└── SqlDb.Create → Database
```

#### Read Request Flow
```
GET /gardens/123
├── GardenController.Show
├── GardenFetcher.FindOneById
├── GardenTable.EsoToEntity
├── GardenHydrator.OneViaPreset (optional)
└── Response (JSON/HTML)
```

#### Update Request Flow
```
PUT /gardens/123
├── GardenController.Update
├── UpdateGardenMae.Execute
├── GardenMolder.ToEntity (change detection)
├── GardenHandler.UpdateFields
├── GardenTable.EntityToValues
└── SqlDb.Update → Database
```

#### Delete Request Flow
```
DELETE /gardens/123
├── GardenController.Delete
├── DeleteGardenMae.Execute
├── GardenFetcher.FindOneById (verify exists)
├── GardenHandler.Delete
└── SqlDb.Delete → Database
```

### List/Search Operations
```
GET /gardens?search=tomato&page=2
├── GardenController.List
├── GardenBinder.BindListParams
├── GardenFetcher.FindPage (with filters)
├── GardenHydrator.ManyViaPreset
├── GardenSerializer.SetToJson
└── JSON Response with pagination
```

## Context Propagation

### Request Context Flow
```go
// Context flows through entire request
func (this *GardenController) Create(c *gin.Context) {
    ctx := c.Request.Context()  // Extract request context

    // Pass to Mae
    output, err := this.CreateGardenMae.Execute(ctx, input)
}

func (this *CreateGardenMae) Execute(ctx context.Context, input *CreateGardenMaeInput) {
    // Pass to services
    garden, err := this.GardenHandler.Create(ctx, entity, nil)
}

func (this *GardenHandler) Create(ctx context.Context, entity *mdl.Garden, mod *handler.HandlerMod) {
    // Pass to database
    id, _, err := this.Handler.Create(ctx, mod.Tx, table, columns, values)
}
```

### Context Values
```go
// Adding values to context
func (this *AuthMiddleware) Authenticate(c *gin.Context) {
    user := this.validateToken(c.GetHeader("Authorization"))

    // Add user to context
    ctx := context.WithValue(c.Request.Context(), "user", user)
    c.Request = c.Request.WithContext(ctx)

    c.Next()
}

// Retrieving from context
func (this *GardenController) getCurrentUser(c *gin.Context) *mdl.User {
    user, _ := c.Request.Context().Value("user").(*mdl.User)
    return user
}
```

## Error Handling Through Lifecycle

### Error Propagation
```go
// Errors bubble up through layers
Database Error
     ↑
Service Error (with context)
     ↑
Mae Error (with business context)
     ↑
Controller Error Handling
     ↑
HTTP Error Response
```

### Error Response Formation
```go
func (this *GardenController) Create(c *gin.Context) {
    output, err := this.CreateGardenMae.Execute(c.Request.Context(), input)
    if err != nil {
        // Determine error type and appropriate response
        switch e := err.(type) {
        case *ValidationError:
            c.JSON(400, gin.H{
                "error": e.Message,
                "field": e.Field,
            })
        case *BusinessRuleError:
            c.JSON(422, gin.H{
                "error": e.Message,
                "code":  e.Code,
            })
        default:
            c.JSON(500, gin.H{
                "error": "Internal server error",
            })
        }
        return
    }

    c.JSON(201, gin.H{"garden": output.Garden})
}
```

## Transaction Lifecycle

### Transaction Boundaries
```go
func (this *ComplexGardenMae) Execute(ctx context.Context, input *ComplexGardenMaeInput) (*ComplexGardenMaeOutput, error) {
    // Begin transaction
    tx, err := this.SqlDb.Begin(ctx)
    if err != nil {
        return nil, err
    }
    defer tx.Rollback() // Auto-rollback if not committed

    // All operations use the same transaction
    handlerMod := &handler.HandlerMod{Tx: tx}

    // Create garden
    garden, err := this.GardenHandler.Create(ctx, gardenEntity, handlerMod)
    if err != nil {
        return nil, err
    }

    // Create related plants
    for _, plant := range input.Plants {
        plant.GardenId = 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 &ComplexGardenMaeOutput{Garden: garden}, nil
}
```

## Performance Monitoring Points

### Request Timing
```go
func (this *GardenController) Create(c *gin.Context) {
    start := time.Now()
    defer func() {
        duration := time.Since(start)
        this.Metrics.RecordRequestDuration("POST", "/gardens", duration)
    }()

    // ... request processing
}
```

### Service Operation Timing
```go
func (this *GardenHandler) Create(ctx context.Context, entity *mdl.Garden, mod *handler.HandlerMod) (*mdl.Garden, error) {
    this.Spy.LogOperation(ctx, "GardenHandler.Create", map[string]interface{}{
        "garden_name": entity.Name,
        "user_id":     entity.UserId,
    })

    // ... implementation
}
```

## Request Lifecycle Debugging

### Tracing Requests
```go
// Add request ID to context
func (this *TracingMiddleware) AddRequestID(c *gin.Context) {
    requestId := uuid.New().String()
    ctx := context.WithValue(c.Request.Context(), "request_id", requestId)
    c.Request = c.Request.WithContext(ctx)
    c.Header("X-Request-ID", requestId)
    c.Next()
}

// Log with request ID
func (this *Logger) LogWithContext(ctx context.Context, level, message string, fields ...interface{}) {
    requestId, _ := ctx.Value("request_id").(string)
    this.Log(level, message, append(fields, "request_id", requestId)...)
}
```

### Request State Inspection
```go
// Middleware for request state logging
func (this *DebugMiddleware) LogRequestState(c *gin.Context) {
    if this.Config.Environment == "dev" {
        this.Logger.Debug("Request received",
            "method", c.Request.Method,
            "path", c.Request.URL.Path,
            "headers", c.Request.Header,
        )
    }

    c.Next()

    if this.Config.Environment == "dev" {
        this.Logger.Debug("Response sent",
            "status", c.Writer.Status(),
            "size", c.Writer.Size(),
        )
    }
}
```

## LLM Request Lifecycle Notes

When debugging or developing:
1. **Request Context** - Always propagate context through all layers
2. **Error Handling** - Handle errors at appropriate levels with context
3. **Transaction Management** - Use transactions for multi-entity operations
4. **Performance Monitoring** - Add timing and logging at key points
5. **Debugging** - Use middleware for request tracing and state inspection
6. **Service Integration** - Understand the flow through Mae → Services → Database
7. **Response Formation** - Handle both success and error cases consistently