> For the complete documentation index, see [llms.txt](https://docs.beeoclock.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.beeoclock.com/services/order-management/usecase.md).

# Use Case Documentation

## Overview

This document provides comprehensive documentation of business logic and use case implementations for the Order Management module. All use cases follow Clean Architecture principles and implement the CQRS pattern with proper permission validation and error handling.

## Architecture Overview

### Design Patterns

* **Clean Architecture**: Separation of concerns with clear dependency inversion
* **CQRS (Command Query Responsibility Segregation)**: Separate models for read and write operations
* **Saga Pattern**: Complex business transactions with compensation logic
* **Domain-Driven Design**: Rich domain models with business rules enforcement
* **Event-Driven Architecture**: Asynchronous processing through domain events

### Core Components

* **Use Cases**: Business logic implementation with single responsibility
* **Sagas**: Multi-step business processes with rollback capabilities
* **Handlers**: CQRS command and query handlers
* **Steps**: Atomic operations within sagas
* **Validators**: Permission and business rule validation
* **Events**: Domain events for system integration

## Read Use Cases

### Get Order Use Case

**Purpose:** Retrieve a single order by ID with permission validation and scope-based access control.

**Implementation:**

```typescript
export interface GetOrderUseCaseParams {
  ctx: TenantActorContext;
  orderId: string;
}

export class GetOrderUseCase implements IUseCase<GetOrderUseCaseParams, OrderDto> {
  private readonly logger = new Logger(GetOrderUseCase.name);

  constructor(
    private readonly queryBus: QueryBus,
    private readonly permissionValidator: PermissionValidatorUseCase,
  ) {}

  public async execute({ ctx, orderId }: GetOrderUseCaseParams): Promise<OrderDto> {
    return this.permissionValidator.executeOrReturn<OrderDto>({
      actor: ctx.actor,
      requiredPermissions: [ModulePermissionEnum.READ_ORDER],

      fallback: () => {
        this.logger.warn(
          `Member ${ctx.actor.issuerId} lacks READ_ORDER permission for order ${orderId}`,
        );
        return null;
      },

      onSuccess: async (scope: PermissionScopeEnum) => {
        try {
          const order: OrderDto = await this.queryBus.execute(
            new GetOrderByIdQuery(ctx.tenantId, orderId),
          );

          if (!order) {
            this.logger.warn(`Order ${orderId} not found`);
            throw new AccessPermissionException('Order not found or access denied');
          }
          
          // Scope-based access control
          if (scope === PermissionScopeEnum.OWN &&
              order.services.some((service) =>
                service.orderAppointmentDetails.specialists.some(
                  (spec) => spec.member._id.toString() !== ctx.actor.issuerId,
                )
              )
          ) {
            this.logger.warn(
              `Member ${ctx.actor.issuerId} tried to access order ${orderId} not assigned to them`,
            );
            throw new AccessPermissionException('You can only view your own orders');
          }

          return order;
        } catch (error) {
          this.logger.error(`Error fetching order ${orderId}`, error);
          throw error;
        }
      },
    });
  }
}
```

**Business Rules:**

1. **Permission Validation**: User must have READ\_ORDER permission
2. **Scope Enforcement**: OWN scope restricts access to user's assigned orders only
3. **Data Privacy**: Orders not assigned to user are hidden in OWN scope
4. **Error Handling**: Proper logging and exception management
5. **Audit Trail**: All access attempts are logged for security

**Permission Scopes:**

* **OWN**: Access only orders where user is assigned as specialist
* **TEAM**: Access orders within user's team
* **BUSINESS**: Access all orders within the business tenant
* **ADMIN**: Full administrative access

### Get Paged Orders Use Case

**Purpose:** Retrieve paginated list of orders with advanced filtering and permission-based scope restrictions.

**Implementation:**

```typescript
export interface GetPagedOrdersUseCaseParams {
  ctx: TenantActorContext;
  pagination: OrderPaginationDto;
}

export class GetPagedOrdersUseCase 
  implements IUseCase<GetPagedOrdersUseCaseParams, PaginationResponseDto<OrderDto> | null> {
  
  private readonly logger = new Logger(GetPagedOrdersUseCase.name);

  constructor(
    private readonly queryBus: QueryBus,
    private readonly permissionValidator: PermissionValidatorUseCase,
  ) {}

  public async execute({
    ctx,
    pagination,
  }: GetPagedOrdersUseCaseParams): Promise<PaginationResponseDto<OrderDto> | null> {
    return this.permissionValidator.executeOrReturn({
      actor: ctx.actor,
      requiredPermissions: [ModulePermissionEnum.READ_ORDER],

      fallback: () => {
        this.logger.warn(
          `Access denied for actor ${ctx.actor.issuerId} to read paged orders`,
        );
        return { items: [], totalSize: 0 };
      },

      onSuccess: async (scope: PermissionScopeEnum) => {
        try {
          // Apply scope-based filtering
          if (scope === PermissionScopeEnum.OWN) {
            pagination.memberIds = [ctx.actor.issuerId];
          }

          return await this.queryBus.execute(
            new GetPagedOrdersQuery(ctx.tenantId, pagination),
          );
        } catch (error) {
          this.logger.error('Error fetching paged orders', error);
          throw error;
        }
      },
    });
  }
}
```

**Business Rules:**

1. **Automatic Scope Filtering**: OWN scope automatically filters by user's member ID
2. **Flexible Pagination**: Configurable page size and sorting options
3. **Advanced Filtering**: Support for date ranges, statuses, customer filters
4. **Performance Optimization**: Database indexes optimize common query patterns
5. **Consistent Results**: Stable pagination with consistent ordering

**Filtering Capabilities:**

* **Date Range**: Filter orders by creation date or appointment dates
* **Status Filter**: Multiple order statuses with array support
* **Customer Filter**: Filter by specific customer ID
* **Member Filter**: Filter by assigned specialist members
* **Text Search**: Search across order content and notes

## Write Use Cases (Sagas)

### Create Order Saga

**Purpose:** Create a new order with comprehensive validation, attendee management, and rollback capabilities.

**Implementation:**

```typescript
export type CreateOrderSagaParams = {
  ctx: TenantActorContext;
  order: OrderDto;
};

export class CreateOrderSaga {
  private readonly logger = new Logger(CreateOrderSaga.name);
  private rollbackActions: (() => Promise<void>)[] = [];

  constructor(
    private readonly addAttendeesStep: AddAttendeesStep,
    private readonly createOrderStep: CreateOrderStep,
    private readonly orderValidationStep: OrderValidationStep,
    private readonly permissionValidator: PermissionValidatorUseCase,
  ) {}

  async execute(params: CreateOrderSagaParams): Promise<OrderDto> {
    try {
      const { ctx, order } = params;

      // Step 0: Permission validation
      const { scope } = await this.permissionValidator.execute({
        actor: ctx.actor,
        requiredPermissions: [ModulePermissionEnum.CREATE_ORDER],
      });

      // Step 1: Comprehensive order validation
      await this.orderValidationStep.execute(ctx.tenantId, order, ctx.actor);

      // Step 2: Add and validate attendees
      const orderWithAttendees = await this.addAttendeesStep.execute(
        ctx.tenantId,
        order,
        ctx.actor,
      );

      // Step 3: Create the order
      const createdOrder = await this.createOrderStep.execute(
        ctx.tenantId,
        orderWithAttendees,
        ctx.actor,
      );

      this.logger.log(`Order ${createdOrder._id} created successfully`);
      return createdOrder;

    } catch (error) {
      this.logger.error('Error in CreateOrderSaga, executing rollback', error);
      await this.executeRollback();
      throw new OrderCreationException(
        `Failed to create order: ${error.message}`,
        error,
      );
    }
  }

  private async executeRollback(): Promise<void> {
    for (const rollbackAction of this.rollbackActions.reverse()) {
      try {
        await rollbackAction();
      } catch (rollbackError) {
        this.logger.error('Error during rollback action', rollbackError);
      }
    }
  }
}
```

**Saga Steps:**

#### 1. Order Validation Step

```typescript
export class OrderValidationStep {
  async execute(tenantId: string, order: OrderDto, actor: ActorDto): Promise<void> {
    // Validate order structure
    this.validateOrderStructure(order);
    
    // Validate services
    await this.validateServices(tenantId, order.services);
    
    // Validate products
    await this.validateProducts(tenantId, order.products);
    
    // Validate appointment conflicts
    await this.validateAppointmentConflicts(tenantId, order.services);
    
    // Validate business rules
    await this.validateBusinessRules(tenantId, order);
  }

  private validateOrderStructure(order: OrderDto): void {
    if (!order.services?.length && !order.products?.length) {
      throw new OrderValidationError('Order must contain at least one service or product');
    }

    if (order.services?.length > ORDER_CONSTANTS.MAX_SERVICES_PER_ORDER) {
      throw new OrderValidationError(
        `Order cannot contain more than ${ORDER_CONSTANTS.MAX_SERVICES_PER_ORDER} services`
      );
    }
  }

  private async validateServices(tenantId: string, services: OrderServiceDto[]): Promise<void> {
    for (const service of services || []) {
      // Validate service exists and is active
      const serviceSnapshot = await this.getServiceSnapshot(tenantId, service.serviceSnapshot._id);
      if (!serviceSnapshot || !serviceSnapshot.isActive) {
        throw new OrderValidationError(`Service ${service.serviceSnapshot._id} is not available`);
      }

      // Validate appointment details
      this.validateAppointmentDetails(service.orderAppointmentDetails);
      
      // Validate specialists
      await this.validateSpecialists(tenantId, service.orderAppointmentDetails.specialists);
    }
  }

  private async validateAppointmentConflicts(
    tenantId: string, 
    services: OrderServiceDto[]
  ): Promise<void> {
    for (const service of services || []) {
      const { start, end, specialists } = service.orderAppointmentDetails;
      
      for (const specialist of specialists) {
        const conflicts = await this.queryBus.execute(
          new GetConflictingAppointmentsQuery(tenantId, specialist._id, start, end)
        );
        
        if (conflicts.length > 0) {
          throw new OrderConflictError(
            `Specialist ${specialist._id} is not available during ${start} - ${end}`
          );
        }
      }
    }
  }
}
```

#### 2. Add Attendees Step

```typescript
export class AddAttendeesStep {
  async execute(
    tenantId: string,
    order: OrderDto,
    actor: ActorDto,
  ): Promise<OrderDto> {
    const updatedServices = await Promise.all(
      order.services?.map(async (service) => {
        const processedAttendees = await this.processAttendees(
          tenantId,
          service.orderAppointmentDetails.attendants || [],
        );

        return {
          ...service,
          orderAppointmentDetails: {
            ...service.orderAppointmentDetails,
            attendants: processedAttendees,
          },
        };
      }) || [],
    );

    return { ...order, services: updatedServices };
  }

  private async processAttendees(
    tenantId: string,
    attendants: AttendantDto[],
  ): Promise<AttendantDto[]> {
    return Promise.all(
      attendants.map(async (attendant) => {
        // Create customer if not exists
        if (!attendant.customer?._id) {
          const customer = await this.customerService.createCustomer(
            tenantId,
            attendant.customer,
          );
          return { ...attendant, customer };
        }

        // Validate existing customer
        const existingCustomer = await this.customerService.getCustomer(
          tenantId,
          attendant.customer._id,
        );
        
        if (!existingCustomer) {
          throw new OrderValidationError(`Customer ${attendant.customer._id} not found`);
        }

        return { ...attendant, customer: existingCustomer };
      }),
    );
  }
}
```

#### 3. Create Order Step

```typescript
export class CreateOrderStep {
  async execute(
    tenantId: string,
    order: OrderDto,
    actor: ActorDto,
  ): Promise<OrderDto> {
    // Create order entity
    const createdOrder = await this.commandBus.execute(
      new CreateOrderCommand(tenantId, order, actor),
    );

    // Publish order created event
    await this.eventBus.publish(
      new OrderConfirmedEvent(tenantId, createdOrder._id, actor),
    );

    return createdOrder;
  }

  async compensate(
    tenantId: string,
    createdOrderDto: OrderDto,
    actor: ActorDto,
  ): Promise<void> {
    try {
      await this.commandBus.execute(
        new DeleteOrderCommand(tenantId, createdOrderDto._id, actor),
      );
    } catch (error) {
      this.logger.error('Failed to compensate order creation', error);
    }
  }
}
```

**Business Rules:**

1. **Validation First**: Comprehensive validation before any data changes
2. **Atomic Operations**: Each step is atomic with compensation capabilities
3. **Conflict Prevention**: Specialist availability validation prevents double booking
4. **Customer Management**: Automatic customer creation and validation
5. **Event Publishing**: Domain events for system integration
6. **Rollback Support**: Full compensation for failed transactions

### Update Order Saga

**Purpose:** Update existing order with validation, change tracking, and event publishing.

**Implementation:**

```typescript
export type UpdateOrderSagaParams = {
  ctx: TenantActorContext;
  orderToUpdate: OrderDto;
};

export class UpdateOrderSaga {
  private readonly logger = new Logger(UpdateOrderSaga.name);
  private rollbackActions: (() => Promise<void>)[] = [];

  async execute(params: UpdateOrderSagaParams): Promise<OrderDto> {
    try {
      const { ctx, orderToUpdate } = params;

      // Step 0: Get existing order for comparison
      const existingOrder = await this.queryBus.execute(
        new GetOrderByIdQuery(ctx.tenantId, orderToUpdate._id)
      );

      if (!existingOrder) {
        throw new OrderNotFountException(orderToUpdate._id);
      }

      // Step 1: Permission validation with ownership check
      await this.orderPermissionValidator.validateOrderAccess(
        ctx.actor,
        existingOrder,
        [ModulePermissionEnum.UPDATE_ORDER],
      );

      // Step 2: Validate update constraints
      await this.validateUpdateConstraints(existingOrder, orderToUpdate);

      // Step 3: Process attendee updates
      const orderWithUpdatedAttendees = await this.addAttendeesStep.execute(
        ctx.tenantId,
        orderToUpdate,
        ctx.actor,
      );

      // Step 4: Update the order
      const updatedOrder = await this.updateOrderStep.execute(
        ctx.tenantId,
        orderWithUpdatedAttendees,
        ctx.actor,
      );

      // Step 5: Publish update events
      await this.publishOrderUpdatedStep.execute(
        ctx.tenantId,
        existingOrder,
        updatedOrder,
        ctx.actor,
      );

      return updatedOrder;

    } catch (error) {
      this.logger.error('Error in UpdateOrderSaga, executing rollback', error);
      await this.executeRollback();
      throw error;
    }
  }

  private async validateUpdateConstraints(
    existingOrder: OrderDto,
    orderToUpdate: OrderDto,
  ): Promise<void> {
    // Cannot update completed orders
    if (existingOrder.status === OrderStatusEnum.done) {
      throw new OrderValidationError('Cannot update completed orders');
    }

    // Cannot update past appointments
    const now = new Date();
    for (const service of orderToUpdate.services || []) {
      const appointmentStart = new Date(service.orderAppointmentDetails.start);
      if (appointmentStart < now) {
        throw new OrderValidationError('Cannot update past appointments');
      }
    }

    // Validate status transitions
    if (existingOrder.status !== orderToUpdate.status) {
      this.validateStatusTransition(existingOrder.status, orderToUpdate.status);
    }
  }

  private validateStatusTransition(
    fromStatus: OrderStatusEnum,
    toStatus: OrderStatusEnum,
  ): void {
    const allowedTransitions = ORDER_STATUS_TRANSITIONS[fromStatus] || [];
    if (!allowedTransitions.includes(toStatus)) {
      throw new OrderValidationError(
        `Invalid status transition from ${fromStatus} to ${toStatus}`
      );
    }
  }
}
```

**Update Step Implementation:**

```typescript
export class UpdateOrderStep {
  async execute(
    tenantId: string,
    order: OrderDto,
    actor: ActorDto,
  ): Promise<OrderDto> {
    // Track changes for audit
    const changeTracker = new OrderChangeTracker();
    
    // Update order with change tracking
    const updatedOrder = await this.commandBus.execute(
      new UpdateOrderCommand(tenantId, order, actor, changeTracker),
    );

    // Add history entry
    await this.addHistoryEntry(updatedOrder, changeTracker.getChanges(), actor);

    return updatedOrder;
  }

  private async addHistoryEntry(
    order: OrderDto,
    changes: OrderChanges,
    actor: ActorDto,
  ): Promise<void> {
    const historyEntry: IHistoryEntry = {
      timestamp: new Date().toISOString(),
      changedBy: actor.issuerId,
      changes: changes,
      reason: 'Order updated through panel',
    };

    await this.commandBus.execute(
      new AddOrderHistoryEntryCommand(order._id, historyEntry),
    );
  }
}
```

**Business Rules:**

1. **Change Validation**: Strict validation of what can be changed and when
2. **Status Transition Rules**: Predefined valid status transitions
3. **Time Constraints**: Cannot modify past appointments
4. **Permission Checks**: User must have appropriate permissions for changes
5. **Audit Trail**: Complete tracking of changes with actor information
6. **Event Publishing**: Change events for system integration

### Delete Order Saga

**Purpose:** Soft delete order with dependency checking and cleanup coordination.

**Implementation:**

```typescript
export type DeleteOrderSagaParams = {
  ctx: TenantActorContext;
  orderId: string;
};

export class DeleteOrderSaga {
  private readonly logger = new Logger(DeleteOrderSaga.name);

  async execute(params: DeleteOrderSagaParams): Promise<void> {
    try {
      const { ctx, orderId } = params;

      // Step 0: Get order to validate existence
      const order = await this.queryBus.execute(
        new GetOrderByIdQuery(ctx.tenantId, orderId)
      );

      if (!order) {
        throw new OrderNotFountException(orderId);
      }

      // Step 1: Permission validation
      const { scope } = await this.permissionValidator.execute({
        actor: ctx.actor,
        requiredPermissions: [ModulePermissionEnum.DELETE_ORDER],
      });

      // Step 2: Validate deletion constraints
      await this.validateDeletionConstraints(order);

      // Step 3: Check order ownership for OWN scope
      if (scope === PermissionScopeEnum.OWN) {
        await this.orderPermissionValidator.validateOrderOwnership(
          ctx.actor,
          order,
        );
      }

      // Step 4: Perform soft deletion
      await this.deleteOrderStep.execute(ctx.tenantId, orderId, ctx.actor);

      this.logger.log(`Order ${orderId} deleted successfully`);

    } catch (error) {
      this.logger.error(`Error deleting order ${orderId}`, error);
      throw error;
    }
  }

  private async validateDeletionConstraints(order: OrderDto): Promise<void> {
    // Cannot delete completed orders
    if (order.status === OrderStatusEnum.done) {
      throw new OrderValidationError('Cannot delete completed orders');
    }

    // Cannot delete orders with completed payments
    if (order.paymentStatus === PaymentStatusEnum.completed) {
      throw new OrderValidationError('Cannot delete orders with completed payments');
    }

    // Cannot delete orders in progress
    if (order.status === OrderStatusEnum.inProgress) {
      throw new OrderValidationError('Cannot delete orders currently in progress');
    }

    // Check for active dependencies
    await this.checkActiveDependencies(order);
  }

  private async checkActiveDependencies(order: OrderDto): Promise<void> {
    // Check for active related records
    const dependencies = await this.dependencyChecker.checkOrderDependencies(order._id);
    
    if (dependencies.hasActiveDependencies) {
      throw new OrderValidationError(
        `Cannot delete order with active dependencies: ${dependencies.details.join(', ')}`
      );
    }
  }
}
```

**Delete Step Implementation:**

```typescript
export class DeleteOrderStep {
  async execute(
    tenantId: string,
    orderId: string,
    actor: ActorDto,
  ): Promise<void> {
    // Soft delete the order
    await this.commandBus.execute(
      new DeleteOrderCommand(tenantId, orderId, actor),
    );

    // Publish deletion event
    await this.eventBus.publish(
      new OrderStatusChangedEvent(
        tenantId,
        orderId,
        OrderStatusEnum.deleted,
        actor.issuerId,
        new Date().toISOString(),
      ),
    );

    // Schedule cleanup tasks
    await this.scheduleCleanupTasks(tenantId, orderId);
  }

  private async scheduleCleanupTasks(
    tenantId: string,
    orderId: string,
  ): Promise<void> {
    // Schedule cache invalidation
    await this.cacheService.invalidateOrderCache(orderId);
    
    // Schedule notification cleanup
    await this.notificationService.cancelOrderNotifications(orderId);
    
    // Schedule related data cleanup
    await this.cleanupService.scheduleOrderCleanup(orderId);
  }
}
```

**Business Rules:**

1. **Soft Deletion**: Orders are marked as deleted, not physically removed
2. **Dependency Checking**: Cannot delete orders with active dependencies
3. **Payment Protection**: Cannot delete orders with completed payments
4. **Status Restrictions**: Cannot delete completed or in-progress orders
5. **Cleanup Coordination**: Automatic cleanup of related resources
6. **Audit Preservation**: Historical data is preserved for compliance

## Service Status Management Use Cases

### Change Order Service Status Saga

**Purpose:** Update individual service status within an order with proper validation and event publishing.

**Implementation:**

```typescript
export class ChangeOrderServiceStatusSaga {
  async execute(params: ChangeOrderServiceStatusParams): Promise<void> {
    try {
      const { ctx, orderServiceId, newStatus, reason } = params;

      // Step 1: Get order service
      const orderService = await this.queryBus.execute(
        new GetOrderServiceByIdQuery(ctx.tenantId, orderServiceId)
      );

      if (!orderService) {
        throw new OrderServiceNotFoundError(orderServiceId);
      }

      // Step 2: Permission validation
      await this.permissionValidator.execute({
        actor: ctx.actor,
        requiredPermissions: [ModulePermissionEnum.UPDATE_ORDER_SERVICE],
      });

      // Step 3: Validate status transition
      this.validateServiceStatusTransition(orderService.status, newStatus);

      // Step 4: Update service status
      await this.changeOrderServiceStatusStep.execute(
        ctx.tenantId,
        orderServiceId,
        newStatus,
        reason,
        ctx.actor,
      );

      // Step 5: Publish status change event
      await this.publishOrderServiceStatusChangedStep.execute(
        ctx.tenantId,
        orderServiceId,
        orderService.status,
        newStatus,
        ctx.actor,
      );

    } catch (error) {
      this.logger.error('Error changing order service status', error);
      throw error;
    }
  }

  private validateServiceStatusTransition(
    currentStatus: OrderServiceStatusEnum,
    newStatus: OrderServiceStatusEnum,
  ): void {
    const allowedTransitions = ORDER_SERVICE_STATUS_TRANSITIONS[currentStatus] || [];
    if (!allowedTransitions.includes(newStatus)) {
      throw new OrderValidationError(
        `Invalid service status transition from ${currentStatus} to ${newStatus}`
      );
    }
  }
}
```

**Business Rules:**

1. **Status Transition Validation**: Only valid transitions are allowed
2. **Permission Requirements**: User must have service update permissions
3. **Atomic Updates**: Service status changes are atomic operations
4. **Event Publishing**: Status changes trigger system-wide events
5. **Audit Trail**: All status changes are logged with actor and reason

## Permission Validation

### Order Permission Validator

**Purpose:** Centralized permission validation logic for order operations with scope-based access control.

**Implementation:**

```typescript
export class OrderPermissionValidator {
  async validateOrderAccess(
    actor: ActorDto,
    order: OrderDto,
    requiredPermissions: ModulePermissionEnum[],
  ): Promise<PermissionScopeEnum> {
    const { scope } = await this.permissionValidator.execute({
      actor,
      requiredPermissions,
    });

    // Apply scope-based restrictions
    if (scope === PermissionScopeEnum.OWN) {
      await this.validateOrderOwnership(actor, order);
    }

    return scope;
  }

  async validateOrderOwnership(actor: ActorDto, order: OrderDto): Promise<void> {
    const isOwner = order.services?.some((service) =>
      service.orderAppointmentDetails.specialists.some(
        (specialist) => specialist.member?._id === actor.issuerId,
      ),
    );

    if (!isOwner) {
      throw new OrderPermissionError(
        actor.issuerId,
        order._id,
        'access - user is not assigned to this order',
      );
    }
  }

  async validateServiceAccess(
    actor: ActorDto,
    orderService: OrderServiceDto,
    requiredPermissions: ModulePermissionEnum[],
  ): Promise<void> {
    const { scope } = await this.permissionValidator.execute({
      actor,
      requiredPermissions,
    });

    if (scope === PermissionScopeEnum.OWN) {
      const isAssigned = orderService.orderAppointmentDetails.specialists.some(
        (specialist) => specialist.member?._id === actor.issuerId,
      );

      if (!isAssigned) {
        throw new OrderPermissionError(
          actor.issuerId,
          orderService._id,
          'access service - user is not assigned specialist',
        );
      }
    }
  }
}
```

## Error Handling Strategies

### Exception Hierarchy

```typescript
export class OrderDomainError extends Error {
  constructor(
    public code: string,
    message: string,
    public context?: Record<string, any>,
  ) {
    super(message);
    this.name = 'OrderDomainError';
  }
}

export class OrderValidationError extends OrderDomainError {
  constructor(message: string, field?: string) {
    super('ORDER_VALIDATION_ERROR', message, { field });
  }
}

export class OrderConflictError extends OrderDomainError {
  constructor(message: string, context?: Record<string, any>) {
    super('ORDER_CONFLICT', message, context);
  }
}

export class OrderNotFoundError extends OrderDomainError {
  constructor(orderId: string) {
    super('ORDER_NOT_FOUND', `Order ${orderId} not found`, { orderId });
  }
}

export class OrderPermissionError extends OrderDomainError {
  constructor(userId: string, orderId: string, action: string) {
    super(
      'ORDER_PERMISSION_DENIED',
      `User ${userId} does not have permission to ${action} order ${orderId}`,
      { userId, orderId, action },
    );
  }
}
```

### Error Recovery Strategies

1. **Validation Errors**: Return detailed validation messages to user
2. **Conflict Errors**: Suggest alternative time slots or specialists
3. **Permission Errors**: Log security events and return generic access denied
4. **Not Found Errors**: Return 404 with safe error message
5. **System Errors**: Log full details, return generic error to user

## Event Publishing

### Domain Events

#### Order Events

```typescript
export class OrderCreatedEvent {
  constructor(
    public readonly tenantId: string,
    public readonly orderId: string,
    public readonly customerId: string,
    public readonly createdBy: string,
    public readonly createdAt: string,
  ) {}
}

export class OrderStatusChangedEvent {
  constructor(
    public readonly tenantId: string,
    public readonly orderId: string,
    public readonly previousStatus: OrderStatusEnum,
    public readonly newStatus: OrderStatusEnum,
    public readonly changedBy: string,
    public readonly changedAt: string,
    public readonly reason?: string,
  ) {}
}

export class OrderUpdatedEvent {
  constructor(
    public readonly tenantId: string,
    public readonly orderId: string,
    public readonly changes: OrderChanges,
    public readonly updatedBy: string,
    public readonly updatedAt: string,
  ) {}
}
```

#### Service Events

```typescript
export class OrderServiceStatusChangedEvent {
  constructor(
    public readonly tenantId: string,
    public readonly orderServiceId: string,
    public readonly orderId: string,
    public readonly previousStatus: OrderServiceStatusEnum,
    public readonly newStatus: OrderServiceStatusEnum,
    public readonly changedBy: string,
    public readonly changedAt: string,
  ) {}
}

export class OrderServiceAcceptedEvent {
  constructor(
    public readonly tenantId: string,
    public readonly orderServiceId: string,
    public readonly orderId: string,
    public readonly specialistId: string,
    public readonly acceptedBy: string,
    public readonly acceptedAt: string,
  ) {}
}
```

### Event Handlers

```typescript
@EventsHandler(OrderCreatedEvent)
export class OrderCreatedHandler implements IEventHandler<OrderCreatedEvent> {
  async handle(event: OrderCreatedEvent): Promise<void> {
    // Send confirmation email
    await this.emailService.sendOrderConfirmation(event);
    
    // Update business analytics
    await this.analyticsService.recordOrderCreation(event);
    
    // Schedule reminders
    await this.reminderService.scheduleOrderReminders(event);
  }
}

@EventsHandler(OrderStatusChangedEvent)
export class OrderStatusChangedHandler implements IEventHandler<OrderStatusChangedEvent> {
  async handle(event: OrderStatusChangedEvent): Promise<void> {
    // Notify stakeholders
    await this.notificationService.notifyStatusChange(event);
    
    // Update order timeline
    await this.timelineService.recordStatusChange(event);
    
    // Trigger status-specific workflows
    await this.workflowService.handleStatusChange(event);
  }
}
```

## Performance Considerations

### Optimization Strategies

1. **Database Indexes**: Optimized queries with compound indexes
2. **Caching**: Multi-level caching with intelligent invalidation
3. **Pagination**: Efficient pagination for large datasets
4. **Async Processing**: Non-critical operations handled asynchronously
5. **Connection Pooling**: Optimized database connection management

### Monitoring Metrics

1. **Use Case Execution Time**: Track performance of business operations
2. **Permission Validation Time**: Monitor permission check performance
3. **Database Query Performance**: Track slow queries and optimization opportunities
4. **Cache Hit Rates**: Monitor cache effectiveness
5. **Error Rates**: Track business rule violations and system errors

### Scalability Patterns

1. **CQRS Separation**: Read and write models can scale independently
2. **Event Sourcing**: Complete audit trail with replay capabilities
3. **Saga Pattern**: Complex workflows with compensation logic
4. **Microservice Ready**: Clean boundaries for service extraction
5. **Database Sharding**: Tenant-based data partitioning support

## Integration Patterns

### External Service Integration

1. **Payment Services**: Payment processing and validation
2. **Notification Services**: Email, SMS, and push notifications
3. **Calendar Services**: Calendar integration for appointments
4. **Analytics Services**: Business intelligence and reporting
5. **Audit Services**: Compliance and audit trail management

### Internal Module Integration

1. **Customer Module**: Customer creation and validation
2. **Service Module**: Service availability and configuration
3. **Member Module**: Specialist assignment and availability
4. **Business Module**: Business rules and configuration
5. **Permission Module**: Role-based access control
