# Flexbase Control Flow

## 🎯 Overview

This document explains the complete control flow for Flexbase features - from API call to execution completion. We'll cover one **Insert (POST)** and one **Query (GET)** example.

***

## 📝 Insert Feature Flow: AddOrder

### **1. API Request**

```
POST /api/Orders/AddOrder
Content-Type: application/json

{
  "customerId": "12345",
  "totalAmount": 299.99,
  "orderItems": [...]
}
```

### **2. Controller Layer**

```csharp
[HttpPost]
[Route("AddOrder")]
public async Task<IActionResult> AddOrder([FromBody] AddOrderDto dto)
{
    return await RunService(201, dto, _processOrdersService.AddOrder);
}
```

**What happens:** Controller receives request, validates DTO, calls service

### **3. Service Layer**

```csharp
public async Task<IActionResult> AddOrder(AddOrderDto dto)
{
    var command = new AddOrderCommand { Dto = dto };
    await _addOrderHandler.Execute(command, _serviceBusContext);
    return new OkResult();
}
```

**What happens:** Service creates command, calls handler

### **4. Command Handler**

```csharp
public async Task Execute(AddOrderCommand cmd, IFlexServiceBusContext serviceBusContext)
{
    // 1. Initialize repository
    _repoFactory.Init(cmd.Dto);
    
    // 2. Call domain method
    _model = _flexHost.GetDomainModel<Order>().AddOrder(cmd);
    
    // 3. Persist to database
    _repoFactory.GetRepo().InsertOrUpdate(_model);
    await _repoFactory.GetRepo().SaveAsync();
    
    // 4. Publish events
    await this.Fire(EventCondition, serviceBusContext);
}
```

**What happens:** Handler orchestrates the operation, calls domain, persists data, publishes events

### **5. Domain Method (Your Business Logic)**

```csharp
public virtual Order AddOrder(AddOrderCommand cmd)
{
    // Your business rules
    if (cmd.Dto.TotalAmount <= 0)
        throw new BusinessException("Invalid amount");
    
    // Apply business logic
    this.Convert(cmd.Dto);
    this.SetAdded(cmd.Dto.GetGeneratedId());
    this.CalculateTotal();
    
    return this;
}
```

**What happens:** Domain validates business rules, applies logic, returns entity

### **6. Database Persistence**

```csharp
_repoFactory.GetRepo().InsertOrUpdate(_model);
await _repoFactory.GetRepo().SaveAsync();
```

**What happens:** Entity Framework saves to database

### **7. Event Publishing**

```csharp
await this.Fire(EventCondition, serviceBusContext);
```

**What happens:** Domain events published to message bus for side effects

### **8. Response**

```
HTTP 201 Created
Location: /api/Orders/{orderId}
```

***

## 🔍 Query Feature Flow: GetOrders

### **1. API Request**

```
GET /api/Orders/GetOrders?status=Pending
```

### **2. Controller Layer**

```csharp
[HttpGet]
[Route("GetOrders")]
public async Task<IActionResult> GetOrders([FromQuery] GetOrdersQuery query)
{
    return await RunService(200, query, _processOrdersService.GetOrders);
}
```

**What happens:** Controller receives request, calls service

### **3. Service Layer**

```csharp
public async Task<IActionResult> GetOrders(GetOrdersQuery query)
{
    var result = _getOrdersHandler.Fetch();
    return new OkObjectResult(result);
}
```

**What happens:** Service calls query handler

### **4. Query Handler**

```csharp
public override IEnumerable<GetOrdersDto> Fetch()
{
    return _repoFactory.GetRepo()
        .FindAll<Order>()
        .Where(o => o.Status == query.Status)
        .Include(o => o.Customer)
        .SelectTo<GetOrdersDto>()
        .ToList();
}
```

**What happens:** Handler executes optimized database query with projection

### **5. Database Query**

```sql
-- Generated SQL (optimized)
SELECT 
    o.Id,
    c.Name AS CustomerName,
    o.TotalAmount,
    o.Status,
    o.OrderDate
FROM Orders o
LEFT JOIN Customers c ON o.CustomerId = c.Id
WHERE o.Status = @Status
```

**What happens:** Only required fields fetched from database

### **6. Projection Mapping**

```csharp
// AutoMapper automatically maps to DTO
CreateMap<Order, GetOrdersDto>()
    .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer.Name));
```

**What happens:** Database results mapped to DTO

### **7. Response**

```json
HTTP 200 OK
[
  {
    "id": "12345",
    "customerName": "John Doe",
    "totalAmount": 299.99,
    "status": "Pending",
    "orderDate": "2024-01-15T10:30:00Z"
  }
]
```

***

## 🔄 Complete Flow Summary

### **Insert Flow:**

```
API Request → Controller → Service → Command Handler → Domain Method → Database → Events → Response
```

### **Query Flow:**

```
API Request → Controller → Service → Query Handler → Database Query → Projection → Response
```

***

## 🎯 Key Points

### **Insert Features:**

* **Command Pattern** - Encapsulates operation
* **Domain Logic** - Business rules in domain layer
* **Event Publishing** - Side effects handled asynchronously
* **Transaction Management** - Automatic rollback on errors

### **Query Features:**

* **Projection-Based** - Only fetch required fields
* **Optimized SQL** - Generated automatically
* **Type Safety** - Compile-time validation
* **Performance** - Database-level optimization

### **Common Benefits:**

* **Separation of Concerns** - Each layer has single responsibility
* **Testability** - Each layer can be tested independently
* **Maintainability** - Clear, readable code structure
* **Consistency** - Same pattern across all features

***

*This control flow ensures reliable, maintainable, and performant enterprise applications with Flexbase.*
