> For the complete documentation index, see [llms.txt](https://docs.flexbase.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flexbase.in/solution-structure/getting-started/features/crud/insert-example.md).

# Insert Example

## Overview

This document demonstrates the complete **Insert flow** using the **AddOrder** feature from the EBusiness application. The flow starts with a POST request to the controller and ends with event publishing and subscriber processing.

## Complete Flow Architecture

```
POST Request → Controller → Service → PreBus Plugins → Command Handler → Domain Model → Database → Event Publishing → Subscribers
```

### **Detailed Flow Breakdown**

```
1. POST Request
   ↓
2. Controller (API Entry Point)
   ↓
3. Service Layer (Business Orchestration)
   ↓
4. PreBus Processing (Validation Pipeline)
   ├── AddOrderSequence (Plugin Registration)
   ├── AddOrderDataPacket (Validation Context)
   └── ValidateCustomer Plugin (Business Rules)
   ↓
5. Command Handler (Data Processing)
   ↓
6. Domain Model (Business Logic)
   ↓
7. Database (Data Persistence)
   ↓
8. Event Publishing (Asynchronous Processing)
   ↓
9. Subscribers (Side Effects)
```

## Step-by-Step Implementation

### 1. **API Controller** - The Entry Point

**File**: `OrdersController_AddOrder.cs`

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

**What Happens:**

* **HTTP Method**: `POST /api/Orders/AddOrder`
* **Input**: `AddOrderDto` from request body
* **Action**: Calls the service layer to process the order
* **Response**: HTTP 201 Created with order ID

### 2. **Service Layer** - Business Orchestration

**File**: `ProcessOrdersService_AddOrder.cs`

```csharp
public async Task<CommandResult> AddOrder(AddOrderDto dto)
{
    var packet = await ProcessBusinessRuleSequence<AddOrderDataPacket, AddOrderSequence, AddOrderDto, FlexAppContextBridge>(dto);

    if (packet.HasError)
    {
        return new CommandResult(Status.Failed, packet.Errors());
    }
    else
    {
        dto.SetGeneratedId(_pkGenerator.GenerateKey());
        AddOrderCommand cmd = new AddOrderCommand
        {
             Dto = dto,
        };

        await ProcessCommand(cmd);

        CommandResult cmdResult = new CommandResult(Status.Success);

        AddOrderResultModel outputResult = new AddOrderResultModel();
        outputResult.Id = dto.GetGeneratedId();
        cmdResult.result = outputResult;

        return cmdResult;
    }
}
```

**What Happens:**

* **PreBus Processing**: Executes business rule sequences (plugins)
* **Validation**: Processes business rule sequences
* **ID Generation**: Generates unique order ID
* **Command Creation**: Creates `AddOrderCommand` with DTO
* **Command Processing**: Calls the command handler
* **Result**: Returns success with generated order ID

### 2.1. **PreBus Business Rule Sequence** - Validation Pipeline

**File**: `AddOrderSequence.cs`

```csharp
public class AddOrderSequence : FlexiBusinessRuleSequenceBase<AddOrderDataPacket>
{
    public AddOrderSequence()
    {
        this.Add<ValidateCustomer>(); 
    }
}
```

**What Happens:**

* **Plugin Registration**: Registers validation plugins in execution order
* **Sequential Processing**: Executes plugins one by one
* **Error Collection**: Collects validation errors from all plugins
* **Early Exit**: Stops processing if any plugin fails

### 2.2. **PreBus Data Packet** - Validation Context

**File**: `AddOrderDataPacket.cs`

```csharp
public partial class AddOrderDataPacket : FlexiFlowDataPacketWithDtoBridge<AddOrderDto, FlexAppContextBridge>
{
    protected readonly ILogger<AddOrderDataPacket> _logger;

    public AddOrderDataPacket(ILogger<AddOrderDataPacket> logger)
    {
        _logger = logger;
    }

    #region "Properties
    //Models and other properties goes here
    #endregion
}
```

**What Happens:**

* **Context Container**: Holds DTO and application context
* **Error Collection**: Collects validation errors from plugins
* **Data Sharing**: Allows plugins to share data during validation
* **Logging**: Provides logging capabilities for plugins

### 2.3. **PreBus Validation Plugin** - Business Rules

**File**: `ValidateCustomer.cs`

```csharp
public partial class ValidateCustomer : FlexiBusinessRuleBase, IFlexiBusinessRule<AddOrderDataPacket>
{
    public override string Id { get; set; } = "3a1cd0401f931dd4a01587e229b720dc";
    public override string FriendlyName { get; set; } = "ValidateCustomer";

    protected readonly ILogger<ValidateCustomer> _logger;
    protected readonly RepoFactory _repoFactory;

    public ValidateCustomer(ILogger<ValidateCustomer> logger, RepoFactory repoFactory)
    {
        _logger = logger;
        _repoFactory = repoFactory;
    }

    public virtual async Task Validate(AddOrderDataPacket packet)
    {
        //Uncomment the below line if validating against a db data using your repo
        //_repoFactory.Init(packet.Dto);

        //If any validation fails, uncomment and use the below line of code to add error to the packet
        //packet.AddError("key", "ErrorMessage");

        await Task.CompletedTask; //If you have any await in the validation, remove this line
    }
}
```

**What Happens:**

* **Business Rule Validation**: Implements specific validation logic
* **Database Access**: Can access repository for data validation
* **Error Reporting**: Adds errors to the data packet if validation fails
* **Async Support**: Supports asynchronous validation operations
* **Dependency Injection**: Receives logger and repository factory

### 2.4. **PreBus Plugin Benefits**

* **Modular Validation**: Each plugin handles one validation concern
* **Reusable Rules**: Plugins can be reused across different features
* **Testable**: Each plugin can be unit tested independently
* **Configurable**: Plugins can be enabled/disabled per feature
* **Extensible**: Easy to add new validation rules
* **Ordered Execution**: Plugins execute in defined sequence

### 3. **Command Handler** - Data Processing

**File**: `AddOrderHandler.cs`

```csharp
public virtual async Task Execute(AddOrderCommand cmd, IFlexServiceBusContext serviceBusContext)
{
    _flexAppContext = cmd.Dto.GetAppContext();
    _repoFactory.Init(cmd.Dto);

    _model = _flexHost.GetDomainModel<Order>().AddOrder(cmd);
    _repoFactory.GetRepo().InsertOrUpdate(_model);
    int records = await _repoFactory.GetRepo().SaveAsync();
    
    if (records > 0)
    {
        _logger.LogDebug("{Entity} with {EntityId} inserted into Database: ", typeof(Order).Name, _model.Id);
    }
    else
    {
        _logger.LogWarning("No records inserted for {Entity} with {EntityId}", typeof(Order).Name, _model.Id);
    }
    
    await this.Fire(EventCondition, serviceBusContext);
}
```

**What Happens:**

* **Context Setup**: Initializes application context and repository
* **Domain Logic**: Calls domain model to process business rules
* **Database Save**: Inserts/updates the order in database
* **Logging**: Logs success/failure of database operation
* **Event Publishing**: Fires events for subscribers

### 4. **Domain Model** - Business Logic

**File**: `Order/AddOrder.cs`

```csharp
public virtual Order AddOrder(AddOrderCommand cmd)
{
    Guard.AgainstNull("Order command cannot be empty", cmd);

    this.Convert(cmd.Dto);
    this.CreatedBy = cmd.Dto.GetAppContext()?.UserId;
    this.LastModifiedBy = cmd.Dto.GetAppContext()?.UserId;

    this.SetAdded(cmd.Dto.GetGeneratedId());

    //Set your appropriate SetAdded for the inner object here
    this.OrderState = new OrderIsCreated().SetTFlexId(this.Id).SetStateChangedBy("");
    this.TotalAmount = this.OrderItems.Select(s => s.SellingPrice).Sum();
    this.TotalQty = this.OrderItems.Select(s => s.Qty).Sum();

    this.OrderItems.SetAddedOrModified();

    return this;
}
```

**What Happens:**

* **Validation**: Guards against null commands
* **Data Mapping**: Converts DTO to domain model
* **Audit Fields**: Sets created/modified by user
* **ID Assignment**: Sets the generated ID
* **Business Rules**: Calculates totals, sets order state
* **Child Objects**: Processes order items

### 5. **NServiceBus Handler** - Message Processing

**File**: `AddOrderNsbHandler.cs`

```csharp
public class AddOrderNsbHandler : NsbCommandHandler<AddOrderCommand>
{
    readonly ILogger<AddOrderNsbHandler> _logger;
    readonly IFlexHost _flexHost;
    readonly IAddOrderHandler _handler;

    public AddOrderNsbHandler(ILogger<AddOrderNsbHandler> logger, IFlexHost flexHost, IAddOrderHandler handler)
    {
        _logger = logger;
        _flexHost = flexHost;
        _handler = handler;
    }

    public override async Task Handle(AddOrderCommand message, IMessageHandlerContext context)
    {
        _logger.LogTrace($"Executing {nameof(AddOrderNsbHandler)}");

        await _handler.Execute(message, new NsbHandlerContextBridge(context));
    }
}
```

**What Happens:**

* **Message Reception**: Receives `AddOrderCommand` from message bus
* **Logging**: Logs handler execution
* **Delegation**: Calls the actual command handler
* **Context Bridge**: Converts NServiceBus context to FlexBase context

### 6. **Event Publishing** - Asynchronous Processing

**Event**: `OrderAddedEvent`

```csharp
public class OrderAddedEvent : FlexEventBridge<FlexAppContextBridge>
{
    // Event data is automatically populated by FlexBase
}
```

**What Happens:**

* **Event Creation**: FlexBase creates event with order data
* **Message Bus**: Event is published to message bus
* **Subscriber Notification**: All subscribers are notified

### 7. **Event Subscribers** - Side Effects

**File**: `NotifyAccountsOnOrderAdded.cs`

```csharp
public partial class NotifyAccountsOnOrderAdded : INotifyAccountsOnOrderAdded
{
    protected readonly ILogger<NotifyAccountsOnOrderAdded> _logger;
    protected string EventCondition = "";

    public NotifyAccountsOnOrderAdded(ILogger<NotifyAccountsOnOrderAdded> logger)
    {
        _logger = logger;
    }

    public virtual async Task Execute(OrderAddedEvent @event, IFlexServiceBusContext serviceBusContext)
    {
        _flexAppContext = @event.AppContext;

        //TODO: Write your business logic here:
        // - Send confirmation email
        // - Update inventory
        // - Notify accounting system
        // - Update analytics

        await this.Fire<NotifyAccountsOnOrderAdded>(EventCondition, serviceBusContext);
    }
}
```

**What Happens:**

* **Event Reception**: Receives `OrderAddedEvent` from message bus
* **Side Effects**: Executes business logic (emails, notifications, etc.)
* **Additional Events**: Can fire more events if needed

## Data Transfer Objects (DTOs)

### **Input DTO**: `AddOrderDto`

```csharp
public partial class AddOrderDto : DtoBridge 
{
    [StringLength(100)]
    public string CustomerId { get; set; }

    public ICollection<AddOrderDto_OrderItem> OrderItems { get; set; }
}
```

### **Command**: `AddOrderCommand`

```csharp
public class AddOrderCommand : FlexCommandBridge<AddOrderDto, FlexAppContextBridge>
{
    // Command data is automatically populated by FlexBase
}
```

## Flow Summary

### **Synchronous Flow (Immediate Response)**

1. **POST Request** → Controller receives request
2. **Service Processing** → Business orchestration and PreBus validation
3. **PreBus Plugins** → Sequential validation of business rules
4. **Command Handler** → Data processing and database save
5. **Domain Logic** → Business rules and calculations
6. **Response** → HTTP 201 with order ID

### **Asynchronous Flow (Event Processing)**

1. **Event Publishing** → OrderAddedEvent published to message bus
2. **Subscriber Processing** → NotifyAccountsOnOrderAdded executes
3. **Side Effects** → Emails, notifications, inventory updates
4. **Additional Events** → Can trigger more business processes

## Key Benefits

* **Separation of Concerns**: Each layer has a single responsibility
* **Testability**: Each component can be tested independently
* **Scalability**: Asynchronous processing handles high loads
* **Maintainability**: Clear, readable code structure
* **Event-Driven**: Loose coupling between components

***

**This AddOrder example demonstrates how FlexBase enables clean, maintainable, and scalable insert operations with proper separation of concerns and event-driven architecture!** 🚀
