> 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/interface.md).

# Interface Documentation

## Overview

This document provides comprehensive documentation of TypeScript interfaces, DTOs, enums, and contracts used throughout the Order Management module. All interfaces are based on real implementations from the codebase.

## Data Transfer Objects (DTOs)

### Core Order DTOs

#### OrderDto

```typescript
import { BaseEntityDto } from '@root/common/application/dto/base-entity.dto';
import { MetaDto } from '@root/common/application/dto/meta.dto';
import { PaymentStatusEnum } from '../../payment/domain/enums/payment.status.enum';
import { OrderStatusEnum } from '../domain/enums/order.status.enum';
import { OrderNotificationSettingsDto } from './sub/notification-settings';
import { OrderProductDto } from './sub/order-product.dto';
import { OrderServiceDto } from './sub/order-service.dto';
import { CustomerDto } from '../../customer/dtos/customer.dto';

@Exclude()
export class OrderDto extends BaseEntityDto {
  @ApiProperty({ example: 'OrderDto', required: false })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'OrderDto';

  @ApiProperty({
    enum: OrderStatusEnum,
    default: OrderStatusEnum.inProgress,
    required: false
  })
  @IsEnum(OrderStatusEnum)
  @Expose()
  status?: OrderStatusEnum;

  @ApiProperty({
    type: () => MetaDto,
    required: false
  })
  @Type(() => MetaDto)
  @IsOptional()
  @Expose()
  meta?: MetaDto;

  @ApiProperty({
    type: () => OrderProductDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => OrderProductDto)
  @IsOptional()
  @Expose()
  products?: OrderProductDto[];

  @ApiProperty({
    type: () => OrderServiceDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => OrderServiceDto)
  @IsOptional()
  @Expose()
  services?: OrderServiceDto[];

  @ApiProperty({
    enum: PaymentStatusEnum, 
    default: PaymentStatusEnum.pending,
    required: false
  })
  @IsEnum(PaymentStatusEnum)
  @IsOptional()
  @Expose()
  paymentStatus?: PaymentStatusEnum;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  businessNote?: string;

  @ApiProperty({
    type: () => OrderNotificationSettingsDto,
    required: false
  })
  @Type(() => OrderNotificationSettingsDto)
  @IsOptional()
  @Expose()
  notificationSettings?: OrderNotificationSettingsDto;

  @ApiProperty({ required: false })
  @Type(() => CustomerDto)
  @IsOptional()
  @Expose()
  customer?: CustomerDto;
}
```

#### OrderServiceDto

```typescript
import { BaseEntityDto } from '@root/common/application/dto/base-entity.dto';
import { MetaDto } from '@root/common/application/dto/meta.dto';
import { PaymentStatusEnum } from '@root/common/module/payment/domain/enums/payment.status.enum';
import { ServiceDto } from "@root/common/module/service/dtos/service.dto";
import { OrderServiceStatusEnum } from '../../domain/enums/order-service.status.enum';
import { OrderAppointmentDetailsDto } from './order-service-details.dto';

@Exclude()
export class OrderServiceDto extends BaseEntityDto {
  @ApiProperty({ example: 'OrderServiceDto', required: false })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'OrderServiceDto';

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  orderId?: string;

  @ApiProperty({
    type: () => ServiceDto,
    required: false
  })
  @Type(() => ServiceDto)
  @IsOptional()
  @Expose()
  serviceSnapshot?: ServiceDto;

  @ApiProperty({
    type: () => OrderAppointmentDetailsDto,
    required: false
  })
  @Type(() => OrderAppointmentDetailsDto)
  @IsOptional()
  @Expose()
  orderAppointmentDetails?: OrderAppointmentDetailsDto;

  @ApiProperty({
    enum: OrderServiceStatusEnum,
    default: OrderServiceStatusEnum.inProgress
  })
  @IsEnum(OrderServiceStatusEnum)
  @Expose()
  status: OrderServiceStatusEnum;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  customerNote?: string;

  @ApiProperty({ required: false })
  @Type(() => MetaDto)
  @IsOptional()
  @Expose()
  meta?: MetaDto;

  @ApiProperty({
    enum: PaymentStatusEnum, 
    default: PaymentStatusEnum.pending,
    required: false
  })
  @IsEnum(PaymentStatusEnum)
  @IsOptional()
  @Expose()
  paymentStatus?: PaymentStatusEnum;
}
```

#### OrderProductDto

```typescript
import { BaseEntityDto } from '@root/common/application/dto/base-entity.dto';
import { MetaDto } from '@root/common/application/dto/meta.dto';
import { PaymentStatusEnum } from '@root/common/module/payment/domain/enums/payment.status.enum';
import { ProductDto } from '@root/common/module/product/product/dtos/product.dto';

@Exclude()
export class OrderProductDto extends BaseEntityDto {
  @ApiProperty({ example: 'OrderProductDto', required: false })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'OrderProductDto';

  @ApiProperty()
  @IsNumber()
  @Expose()
  quantity: number;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  orderId?: string;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  orderServiceId?: string;

  @ApiProperty({
    type: () => ProductDto
  })
  @Type(() => ProductDto)
  @ValidateNested()
  @Expose()
  productSnapshot: ProductDto;

  @ApiProperty({
    type: () => MetaDto,
    required: false
  })
  @Type(() => MetaDto)
  @IsOptional()
  @Expose()
  meta?: MetaDto;

  @ApiProperty({
    enum: PaymentStatusEnum,
    default: PaymentStatusEnum.pending,
    required: false
  })
  @IsEnum(PaymentStatusEnum)
  @IsOptional()
  @Expose()
  paymentStatus?: PaymentStatusEnum;
}
```

#### OrderAppointmentDetailsDto

```typescript
import { LocationDto } from '@root/common/application/dto/location.dto';
import { LanguageCodeEnum } from '@root/common/core/enum/language-code.enum';
import { AttachmentDto } from '@root/common/module/order/dtos/sub/attachment.dto';
import { AttendantDto } from '@root/common/module/order/dtos/sub/attendant.dto';
import { SpecialistDto } from '@root/common/module/specialist/dtos/specialist.dto';
import { ReservationTypeEnum } from '../../domain/enums/reservation.type.enum';

@Exclude()
export class OrderAppointmentDetailsDto {
  @ApiProperty({ example: 'OrderAppointmentDetailsDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'OrderAppointmentDetailsDto';

  @ApiProperty()
  @IsString()
  @Expose()
  start: string;

  @ApiProperty()
  @IsString()
  @Expose()
  end: string;

  @ApiProperty({
    enum: ReservationTypeEnum,
    default: ReservationTypeEnum.service
  })
  @IsEnum(ReservationTypeEnum)
  @IsOptional()
  @Expose()
  type?: ReservationTypeEnum;

  @ApiProperty({
    enum: LanguageCodeEnum,
    isArray: true,
    default: [LanguageCodeEnum.uk]
  })
  @Expose()
  @IsArray()
  @IsEnum(LanguageCodeEnum, { each: true })
  @IsOptional()
  languageCodes?: LanguageCodeEnum[];

  @ApiProperty({
    type: () => SpecialistDto,
    isArray: true
  })
  @IsArray()
  @Type(() => SpecialistDto)
  @ValidateNested({ each: true })
  @Expose()
  specialists: SpecialistDto[];

  @ApiProperty({
    type: () => AttendantDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => AttendantDto)
  @ValidateNested({ each: true })
  @IsOptional()
  @Expose()
  attendants?: AttendantDto[];

  @ApiProperty({
    type: () => LocationDto,
    required: false
  })
  @Type(() => LocationDto)
  @ValidateNested()
  @IsOptional()
  @Expose()
  location?: LocationDto;

  @ApiProperty({
    type: () => AttachmentDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => AttachmentDto)
  @ValidateNested({ each: true })
  @IsOptional()
  @Expose()
  attachments?: AttachmentDto[];
}
```

### Pagination DTOs

#### OrderPaginationDto

```typescript
import { PaginationDto } from '@root/common/application/dto/pagination/pagination.dto';
import { OrderStatusEnum } from '../domain/enums/order.status.enum';

@Exclude()
export class OrderPaginationDto extends PaginationDto {
  @ApiPropertyOptional({
    example: (new Date()).toISOString(),
    default: (new Date()).toISOString()
  })
  @IsString()
  @IsOptional()
  @Expose()
  start?: string;

  @ApiPropertyOptional()
  @IsString()
  @IsOptional()
  @Expose()
  customerId?: string;

  @ApiPropertyOptional({
    example: (new Date()).toISOString(),
    default: (new Date()).toISOString()
  })
  @IsString()
  @IsOptional()
  @Expose()
  end?: string;

  @ApiPropertyOptional({
    type: () => [OrderStatusEnum],
    isArray: true,
    example: [
      OrderStatusEnum.inProgress,
      OrderStatusEnum.cancelled
    ],
    description: 'Array of order statuses to filter by. If not provided, all statuses will be included.'
  })
  @IsArray()
  @IsOptional()
  @Expose()
  @Transform(({ value }) => {
    const statuses = Array.isArray(value) ? value : [value];
    return statuses.reduce((acc, status) => {
      if (OrderStatusEnum[status]) {
        acc.push(OrderStatusEnum[status]);
      }
      return acc;
    }, []);
  })
  statuses?: OrderStatusEnum[];

  @ApiPropertyOptional({
    type: [String],
    example: ['64fa1c71b19d6d001c88a91f', '64fa1c71b19d6d001c88a91e'],
    description: 'Filter orders by assigned member IDs',
  })
  @IsArray()
  @IsOptional()
  @Expose()
  @Transform(({ value }) => Array.isArray(value) ? value : [value])
  memberIds?: string[];
}
```

### Supporting DTOs

#### AttendantDto

```typescript
import { CustomerDto } from '@root/common/module/customer/dtos/customer.dto';

@Exclude()
export class AttendantDto {
  @ApiProperty({ example: 'AttendantDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'AttendantDto';

  @ApiProperty()
  @Type(() => CustomerDto)
  @IsOptional()
  @Expose()
  customer?: CustomerDto;

  @ApiProperty({ 
    description: 'Indicates if this is the first time the attendant is visiting the business' 
  })
  @IsOptional()
  @IsBoolean()
  @Expose()
  firstTime?: boolean;
}
```

#### AttachmentDto

```typescript
@Exclude()
export class AttachmentDto {
  @ApiProperty({ example: 'AttachmentDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'AttachmentDto';

  @ApiProperty()
  @IsString()
  @Expose()
  filename: string;

  @ApiProperty()
  @IsString()
  @Expose()
  url: string;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  description?: string;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  mimeType?: string;

  @ApiProperty({ required: false })
  @IsNumber()
  @IsOptional()
  @Expose()
  size?: number;
}
```

### Public Order DTOs

#### PublicOrderDto

```typescript
import { OrderStatusEnum } from '../domain/enums/order.status.enum';
import { PublicOrderProductDto } from './sub/public-order-product.dto';
import { PublicOrderServiceDto } from './sub/public-order-service.dto';

@Exclude()
export class PublicOrderDto {
  @ApiProperty({ example: 'PublicOrderDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'PublicOrderDto';

  @ApiProperty()
  @IsString()
  @Transform(from_object_id)
  @Expose()
  _id: string;

  @ApiProperty({
    enum: OrderStatusEnum,
    default: OrderStatusEnum.inProgress
  })
  @IsEnum(OrderStatusEnum)
  @Expose()
  status: OrderStatusEnum;

  @ApiProperty({
    type: () => PublicOrderProductDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => PublicOrderProductDto)
  @IsOptional()
  @Expose()
  products?: PublicOrderProductDto[];

  @ApiProperty({
    type: () => PublicOrderServiceDto,
    isArray: true,
    required: false
  })
  @IsArray()
  @Type(() => PublicOrderServiceDto)
  @IsOptional()
  @Expose()
  services?: PublicOrderServiceDto[];
}
```

#### PublicOrderServiceDto

```typescript
import { PublicServiceDto } from '@root/common/module/service/dtos/public-service.dto';
import { OrderServiceStatusEnum } from '../../domain/enums/order-service.status.enum';
import { PublicOrderAppointmentDetailsDto } from './public-order-appointment-details.dto';

@Exclude()
export class PublicOrderServiceDto {
  @ApiProperty({ example: 'PublicOrderServiceDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'PublicOrderServiceDto';

  @ApiProperty()
  @IsString()
  @Transform(from_object_id)
  @Expose()
  _id: string;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  orderId?: string;

  @ApiProperty({
    type: () => PublicServiceDto,
    required: false
  })
  @Type(() => PublicServiceDto)
  @IsOptional()
  @Expose()
  serviceSnapshot?: PublicServiceDto;

  @ApiProperty({
    type: () => PublicOrderAppointmentDetailsDto,
    required: false
  })
  @Type(() => PublicOrderAppointmentDetailsDto)
  @IsOptional()
  @Expose()
  orderAppointmentDetails?: PublicOrderAppointmentDetailsDto;

  @ApiProperty({
    enum: OrderServiceStatusEnum,
    default: OrderServiceStatusEnum.inProgress
  })
  @IsEnum(OrderServiceStatusEnum)
  @Expose()
  status: OrderServiceStatusEnum;

  @ApiProperty({ required: false })
  @IsString()
  @IsOptional()
  @Expose()
  customerNote?: string;
}
```

### Use Case DTOs

#### CreatePublicOrderDto

```typescript
import { OrderProductDto } from '../../../dtos/sub/order-product.dto';
import { CreatePublicOrderServiceDto } from './create-public-order-service.dto';

@Exclude()
export class CreatePublicOrderDto {
  @ApiProperty({ example: 'CreatePublicOrderDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'CreatePublicOrderDto';

  @ApiProperty()
  @IsString()
  @Expose()
  _id: string;

  @ApiProperty({
    type: () => OrderProductDto,
    isArray: true
  })
  @IsArray()
  @Type(() => OrderProductDto)
  @ValidateNested({ each: true })
  @IsOptional()
  @Expose()
  products?: OrderProductDto[];

  @ApiProperty({
    type: () => CreatePublicOrderServiceDto,
    isArray: true
  })
  @IsArray()
  @Type(() => CreatePublicOrderServiceDto)
  @IsOptional()
  @ValidateNested({ each: true })
  @Expose()
  services?: CreatePublicOrderServiceDto[];
}
```

#### CreatePublicOrderServiceDto

```typescript
import { RequestPublicServiceDto } from '@root/common/module/service/dtos/request-public-service.dto';
import { CreatePublicOrderAppointmentDetailsDto } from './public-order-service-details.dto';

@Exclude()
export class CreatePublicOrderServiceDto {
  @ApiProperty({ example: 'CreatePublicOrderServiceDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'CreatePublicOrderServiceDto';

  @ApiProperty({
    type: () => RequestPublicServiceDto
  })
  @Type(() => RequestPublicServiceDto)
  @ValidateNested()
  @IsOptional()
  @Expose()
  serviceSnapshot?: RequestPublicServiceDto;

  @ApiProperty({
    type: () => CreatePublicOrderAppointmentDetailsDto
  })
  @Type(() => CreatePublicOrderAppointmentDetailsDto)
  @ValidateNested()
  @IsOptional()
  @Expose()
  orderAppointmentDetails?: CreatePublicOrderAppointmentDetailsDto;

  @ApiProperty()
  @IsString()
  @IsOptional()
  @Expose()
  customerNote?: string;
}
```

#### ChangeOrderStatusDto

```typescript
import { OrderStatusEnum } from '../../../domain/enums/order.status.enum';

@Exclude()
export class ChangeOrderStatusDto {
  @ApiProperty({ example: 'ChangeOrderStatusDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'ChangeOrderStatusDto';

  @ApiProperty()
  @IsOptional()
  @IsString()
  @Expose()
  orderId?: string;

  @ApiProperty({
    enum: OrderStatusEnum,
    default: OrderStatusEnum.inProgress,
  })
  @IsEnum(OrderStatusEnum)
  @IsOptional()
  @Expose()
  status?: OrderStatusEnum;
}
```

#### CancelOrderDto

```typescript
@Exclude()
export class CancelOrderDto {
  @ApiProperty({ example: 'CancelOrderDto' })
  @IsString()
  @IsOptional()
  @Expose()
  object?: 'CancelOrderDto';

  @ApiProperty()
  @IsOptional()
  @IsString()
  @Expose()
  orderId?: string;
}
```

## Domain Interfaces

### Core Domain Interfaces

#### IOrder

```typescript
import { IBase } from '@root/common/core/entities/entity';
import { IMeta } from '@root/common/core/value-objects/meta.value';
import { PaymentStatusEnum } from '@root/common/module/payment/domain/enums/payment.status.enum';
import { OrderStatusEnum } from '../enums/order.status.enum';
import { IOrderProduct } from './IOrderProduct';
import { IOrderService } from './IOrderService';
import { IOrderNotificationSettings } from '../values/sub/notification-settings.value';

export interface IOrder extends IBase {
  status: OrderStatusEnum;
  meta?: IMeta;
  services?: IOrderService[];
  businessNote?: string;
  products?: IOrderProduct[];
  paymentStatus?: PaymentStatusEnum;
  notificationSettings?: IOrderNotificationSettings;
  createdAt?: string;
  updatedAt?: string;
}
```

#### IOrderService

```typescript
import { IBase } from '@root/common/core/entities/entity';
import { IMeta } from '@root/common/core/value-objects/meta.value';
import { PaymentStatusEnum } from '@root/common/module/payment/domain/enums/payment.status.enum';
import { IService } from '@root/common/module/service/domain/persistance/IService';
import { OrderServiceStatusEnum } from '../enums/order-service.status.enum';
import { IOrderAppointmentDetails } from '../values/ordered-appointment-details.value';

export interface IOrderService extends IBase {
  orderId: string;
  serviceSnapshot: IService;
  orderAppointmentDetails: IOrderAppointmentDetails;
  status: OrderServiceStatusEnum;
  customerNote?: string;
  meta?: IMeta;
  paymentStatus?: PaymentStatusEnum;
}
```

#### IOrderProduct

```typescript
import { IBase } from '@root/common/core/entities/entity';
import { IMeta } from '@root/common/core/value-objects/meta.value';
import { PaymentStatusEnum } from '@root/common/module/payment/domain/enums/payment.status.enum';
import { IProduct } from '@root/common/module/product/product/domain/persistance/IProduct';

export interface IOrderProduct extends IBase {
  orderId?: string;
  orderServiceId?: string;
  productSnapshot: IProduct;
  meta?: IMeta;
  quantity: number;
  saleDate?: string;
  paymentStatus?: PaymentStatusEnum;
}
```

## Enumerations

### OrderStatusEnum

```typescript
export enum OrderStatusEnum {
  draft = 'draft',                      // Order in draft state
  deleted = 'deleted',                  // Order soft deleted
  requested = 'requested',              // Order requested by customer
  confirmed = 'confirmed',              // Order confirmed by business
  inProgress = 'inProgress',            // Order currently being processed
  done = 'done',                       // Order completed successfully
  cancelled = 'cancelled',              // Order cancelled
  rejected = 'rejected',                // Order rejected by business
  waitingForPayment = 'waitingForPayment' // Order awaiting payment
}
```

### OrderServiceStatusEnum

```typescript
export enum OrderServiceStatusEnum {
  requested = 'requested',              // Service has been requested but not yet accepted
  accepted = 'accepted',                // Service request has been accepted by the specialist
  ready = 'ready',                      // Service is ready to be provided by the specialist
  inProgress = 'inProgress',            // Service is currently being provided by the specialist
  done = 'done',                       // Service has been successfully completed
  rejected = 'rejected',                // Service request has been rejected
  cancelled = 'cancelled',              // Service has been cancelled by customer or specialist
  deleted = 'deleted'                   // Service has been removed or marked as deleted
}
```

### ReservationTypeEnum

```typescript
export enum ReservationTypeEnum {
  service = 'service',                  // Standard service reservation
  event = 'event',                     // Event-based reservation
  consultation = 'consultation'         // Consultation appointment
}
```

### PaymentStatusEnum

```typescript
export enum PaymentStatusEnum {
  pending = 'pending',                  // Payment is pending
  processing = 'processing',            // Payment is being processed
  completed = 'completed',              // Payment completed successfully
  failed = 'failed',                   // Payment failed
  refunded = 'refunded',               // Payment has been refunded
  cancelled = 'cancelled'               // Payment was cancelled
}
```

### ResponseStatusEnum

```typescript
export enum ResponseStatusEnum {
  confirmed = 'confirmed',              // Response confirmed
  declined = 'declined',                // Response declined
  pending = 'pending',                  // Response pending
  cancelled = 'cancelled'               // Response cancelled
}
```

## Use Case Interfaces

### Use Case Parameter Interfaces

#### GetOrderUseCaseParams

```typescript
import { TenantActorContext } from '@root/common/application/context/tenant-actor.context';

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

#### GetPagedOrdersUseCaseParams

```typescript
import { TenantActorContext } from '@root/common/application/context/tenant-actor.context';
import { OrderPaginationDto } from '../../dtos/order-pagination.dto';

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

#### CreateOrderSagaParams

```typescript
import { TenantActorContext } from '@root/common/application/context/tenant-actor.context';
import { OrderDto } from '../../dtos/order.dto';

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

#### UpdateOrderSagaParams

```typescript
import { TenantActorContext } from '@root/common/application/context/tenant-actor.context';
import { OrderDto } from '../../dtos/order.dto';

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

#### DeleteOrderSagaParams

```typescript
import { TenantActorContext } from '@root/common/application/context/tenant-actor.context';

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

## Repository Interfaces

### IOrderRepository

```typescript
import { IBaseRepository } from '@root/common/core/persistance/i-base.repository';
import { IOrder } from './IOrder';

export interface IOrderRepository extends IBaseRepository<IOrder> {
  findByCustomerId(customerId: string): Promise<IOrder[]>;
  findByMemberId(memberId: string): Promise<IOrder[]>;
  findByStatus(status: OrderStatusEnum): Promise<IOrder[]>;
  findByDateRange(start: Date, end: Date): Promise<IOrder[]>;
  findWithServices(orderId: string): Promise<IOrder | null>;
  findWithProducts(orderId: string): Promise<IOrder | null>;
}
```

### IOrderServiceRepository

```typescript
import { IBaseRepository } from '@root/common/core/persistance/i-base.repository';
import { IOrderService } from './IOrderService';

export interface IOrderServiceRepository extends IBaseRepository<IOrderService> {
  findByOrderId(orderId: string): Promise<IOrderService[]>;
  findBySpecialistId(specialistId: string): Promise<IOrderService[]>;
  findByStatus(status: OrderServiceStatusEnum): Promise<IOrderService[]>;
  findByDateRange(start: Date, end: Date): Promise<IOrderService[]>;
  findConflictingAppointments(start: Date, end: Date, specialistId: string): Promise<IOrderService[]>;
}
```

### IOrderProductRepository

```typescript
import { IBaseRepository } from '@root/common/core/persistance/i-base.repository';
import { IOrderProduct } from './IOrderProduct';

export interface IOrderProductRepository extends IBaseRepository<IOrderProduct> {
  findByOrderId(orderId: string): Promise<IOrderProduct[]>;
  findByOrderServiceId(orderServiceId: string): Promise<IOrderProduct[]>;
  findByProductId(productId: string): Promise<IOrderProduct[]>;
}
```

## Value Object Interfaces

### IOrderAppointmentDetails

```typescript
import { LanguageCodeEnum } from '@root/common/core/enum/language-code.enum';
import { ReservationTypeEnum } from '../enums/reservation.type.enum';
import { IAttendant } from './sub/attendant.value';
import { IAttachment } from './sub/attachment.value';
import { ILocation } from './sub/location.value';

export interface IOrderAppointmentDetails {
  start: string;
  end: string;
  type?: ReservationTypeEnum;
  languageCodes?: LanguageCodeEnum[];
  specialists: string[]; // Specialist IDs
  attendants?: IAttendant[];
  location?: ILocation;
  attachments?: IAttachment[];
}
```

### IOrderNotificationSettings

```typescript
export interface IOrderNotificationSettings {
  emailNotifications: boolean;
  smsNotifications: boolean;
  pushNotifications: boolean;
  reminderSettings?: {
    enabled: boolean;
    timeBeforeInMinutes: number;
  };
}
```

### IAttendant

```typescript
export interface IAttendant {
  customerId: string;
  firstTime?: boolean;
  specialRequests?: string;
  notes?: string;
}
```

### IAttachment

```typescript
export interface IAttachment {
  filename: string;
  url: string;
  description?: string;
  mimeType?: string;
  size?: number;
  uploadedBy?: string;
  uploadedAt?: string;
}
```

### ILocation

```typescript
export interface ILocation {
  address?: string;
  coordinates?: {
    latitude: number;
    longitude: number;
  };
  roomNumber?: string;
  buildingInfo?: string;
  accessInstructions?: string;
}
```

## Event Interfaces

### Order Events

#### OrderCreatedEvent

```typescript
export interface OrderCreatedEvent {
  orderId: string;
  tenantId: string;
  customerId?: string;
  orderStatus: OrderStatusEnum;
  totalServices: number;
  totalProducts: number;
  createdBy: string;
  createdAt: string;
}
```

#### OrderUpdatedEvent

```typescript
export interface OrderUpdatedEvent {
  orderId: string;
  tenantId: string;
  changes: {
    status?: {
      from: OrderStatusEnum;
      to: OrderStatusEnum;
    };
    services?: {
      added?: string[];
      removed?: string[];
      modified?: string[];
    };
    products?: {
      added?: string[];
      removed?: string[];
      modified?: string[];
    };
  };
  updatedBy: string;
  updatedAt: string;
}
```

#### OrderStatusChangedEvent

```typescript
export interface OrderStatusChangedEvent {
  orderId: string;
  tenantId: string;
  previousStatus: OrderStatusEnum;
  newStatus: OrderStatusEnum;
  changedBy: string;
  changedAt: string;
  reason?: string;
}
```

#### OrderDeletedEvent

```typescript
export interface OrderDeletedEvent {
  orderId: string;
  tenantId: string;
  deletedBy: string;
  deletedAt: string;
  reason?: string;
}
```

### Order Service Events

#### OrderServiceStatusChangedEvent

```typescript
export interface OrderServiceStatusChangedEvent {
  orderServiceId: string;
  orderId: string;
  tenantId: string;
  previousStatus: OrderServiceStatusEnum;
  newStatus: OrderServiceStatusEnum;
  specialistId?: string;
  changedBy: string;
  changedAt: string;
}
```

#### OrderServiceAcceptedEvent

```typescript
export interface OrderServiceAcceptedEvent {
  orderServiceId: string;
  orderId: string;
  tenantId: string;
  specialistId: string;
  acceptedBy: string;
  acceptedAt: string;
}
```

#### OrderServiceCancelledEvent

```typescript
export interface OrderServiceCancelledEvent {
  orderServiceId: string;
  orderId: string;
  tenantId: string;
  specialistId?: string;
  cancelledBy: string;
  cancelledAt: string;
  reason?: string;
}
```

## Validation Constraints

### Order Validation

```typescript
export interface OrderValidationConstraints {
  maxServicesPerOrder: number;           // Maximum 10 services per order
  maxProductsPerService: number;         // Maximum products per service
  maxAttendeesPerService: number;        // Maximum attendees per service
  minAdvanceBookingHours: number;        // Minimum hours in advance for booking
  maxAdvanceBookingDays: number;         // Maximum days in advance for booking
  allowPastDateModification: boolean;    // Allow modification of past appointments
  requireCustomerForOrder: boolean;      // Customer required for order creation
}
```

### Service Validation

```typescript
export interface ServiceValidationConstraints {
  maxAppointmentDurationHours: number;   // Maximum appointment duration
  minAppointmentDurationMinutes: number; // Minimum appointment duration
  maxSimultaneousBookings: number;       // Max bookings per specialist per time slot
  requireSpecialistAssignment: boolean;  // Specialist assignment required
  allowDoubleBooking: boolean;           // Allow overlapping appointments
}
```

## Type Guards and Utility Types

### Type Guards

```typescript
export function isOrderDto(obj: any): obj is OrderDto {
  return obj && typeof obj === 'object' && obj.object === 'OrderDto';
}

export function isOrderServiceDto(obj: any): obj is OrderServiceDto {
  return obj && typeof obj === 'object' && obj.object === 'OrderServiceDto';
}

export function isOrderProductDto(obj: any): obj is OrderProductDto {
  return obj && typeof obj === 'object' && obj.object === 'OrderProductDto';
}

export function isValidOrderStatus(status: string): status is OrderStatusEnum {
  return Object.values(OrderStatusEnum).includes(status as OrderStatusEnum);
}

export function isValidOrderServiceStatus(status: string): status is OrderServiceStatusEnum {
  return Object.values(OrderServiceStatusEnum).includes(status as OrderServiceStatusEnum);
}
```

### Utility Types

```typescript
// Partial order for updates
export type PartialOrder = Partial<Omit<OrderDto, '_id' | 'createdAt' | 'updatedAt'>>;

// Order creation payload
export type CreateOrderPayload = Omit<OrderDto, '_id' | 'createdAt' | 'updatedAt' | 'status'>;

// Order update payload
export type UpdateOrderPayload = PartialOrder & { _id: string };

// Order service creation payload
export type CreateOrderServicePayload = Omit<OrderServiceDto, '_id' | 'createdAt' | 'updatedAt' | 'orderId'>;

// Order search criteria
export type OrderSearchCriteria = {
  customerId?: string;
  memberIds?: string[];
  statuses?: OrderStatusEnum[];
  dateRange?: {
    start: string;
    end: string;
  };
  phrase?: string;
};

// Order aggregation result
export type OrderAggregationResult = {
  totalOrders: number;
  ordersByStatus: Record<OrderStatusEnum, number>;
  totalRevenue: number;
  averageOrderValue: number;
  topServices: Array<{
    serviceId: string;
    serviceName: string;
    bookingCount: number;
  }>;
};
```

## Error Types

### Domain Error Types

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

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

export class OrderValidationError extends OrderDomainError {
  constructor(field: string, message: 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 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 });
  }
}
```

## Constants and Configuration

### Order Configuration

```typescript
export const ORDER_CONSTANTS = {
  MAX_SERVICES_PER_ORDER: 10,
  MAX_PRODUCTS_PER_ORDER: 50,
  MAX_ATTENDEES_PER_SERVICE: 20,
  MAX_ATTACHMENTS_PER_SERVICE: 5,
  MAX_ATTACHMENT_SIZE_MB: 10,
  DEFAULT_PAGE_SIZE: 10,
  MAX_PAGE_SIZE: 100,
  MIN_ADVANCE_BOOKING_MINUTES: 30,
  MAX_ADVANCE_BOOKING_DAYS: 365
} as const;

export const ORDER_STATUS_TRANSITIONS: Record<OrderStatusEnum, OrderStatusEnum[]> = {
  [OrderStatusEnum.draft]: [OrderStatusEnum.requested, OrderStatusEnum.cancelled],
  [OrderStatusEnum.requested]: [OrderStatusEnum.confirmed, OrderStatusEnum.rejected, OrderStatusEnum.cancelled],
  [OrderStatusEnum.confirmed]: [OrderStatusEnum.inProgress, OrderStatusEnum.cancelled],
  [OrderStatusEnum.inProgress]: [OrderStatusEnum.done, OrderStatusEnum.cancelled],
  [OrderStatusEnum.done]: [],
  [OrderStatusEnum.cancelled]: [],
  [OrderStatusEnum.rejected]: [],
  [OrderStatusEnum.deleted]: [],
  [OrderStatusEnum.waitingForPayment]: [OrderStatusEnum.confirmed, OrderStatusEnum.cancelled]
};

export const ORDER_SERVICE_STATUS_TRANSITIONS: Record<OrderServiceStatusEnum, OrderServiceStatusEnum[]> = {
  [OrderServiceStatusEnum.requested]: [OrderServiceStatusEnum.accepted, OrderServiceStatusEnum.rejected],
  [OrderServiceStatusEnum.accepted]: [OrderServiceStatusEnum.ready, OrderServiceStatusEnum.cancelled],
  [OrderServiceStatusEnum.ready]: [OrderServiceStatusEnum.inProgress, OrderServiceStatusEnum.cancelled],
  [OrderServiceStatusEnum.inProgress]: [OrderServiceStatusEnum.done, OrderServiceStatusEnum.cancelled],
  [OrderServiceStatusEnum.done]: [],
  [OrderServiceStatusEnum.rejected]: [],
  [OrderServiceStatusEnum.cancelled]: [],
  [OrderServiceStatusEnum.deleted]: []
};
```
