Skip to content

Orders Domain

The Orders domain manages the order lifecycle, from creation through completion or cancellation. It includes order workflow state management, chat communication between buyers and sellers, comments/reviews, and payment tracking.

Overview

The Orders domain encompasses:

  • Orders – Service purchase transactions with state machine workflow
  • Chat – Real-time communication between customer and seller
  • Comments – Reviews and ratings after order completion
  • Payments – Payment tracking and status

Entities

Order Entity

Represents a service purchase with complex workflow.

// domain/orders/order.entity.ts
export class Order {
  id: string;
  sellerId: string;
  customerId: string;
  serviceId: string;
  serviceTitle: string;
  servicePrice: Decimal;
  serviceDeliveryTime: number;
  selectedOptions: Option[];
  totalAmount: Decimal;
  commissionAmount: Decimal;
  paymentId: string;
  state: State;
  completionDate: Date | null;
  createdAt: Date;
  updatedAt: Date;
  events: Event[];
  notes: string;

  static create(
    id: string,
    sellerId: string,
    customerId: string,
    serviceId: string,
    serviceTitle: string,
    servicePrice: Decimal,
    serviceDeliveryTime: number,
    selectedOptions: Option[],
    paymentId: string,
    commissionRate: Decimal
  ): Order

  getTotalPrice(): Decimal
  getDeliveryTime(): number
  getAssumedDeliveryDate(): Date
  isLate(): boolean
  getCancelationRequestCount(): number
  getNumber(): string
}

Order states:

type State =
  | "paid"                    // Payment completed, awaiting seller acceptance
  | "rejected"                // Seller rejected the order
  | "inprogress"             // Seller accepted, working on it
  | "cancel_requested"       // Customer requested cancellation
  | "disputing"              // Dispute under admin review
  | "delivered"              // Seller delivered, awaiting customer approval
  | "correction_requested"   // Customer requested corrections
  | "completed"              // Customer approved, order complete
  | "cancelled"              // Order cancelled (refund issued)

Event types:

type EventType =
  | "payment.completed"
  | "order.accepted"
  | "order.rejected"
  | "order.delivered"
  | "order.completed"
  | "dispute.resolved"
  | "order.cancel_accepted"
  | "order.cancel_rejected"
  | "order.requires_correction"
  | "correction_request.accepted"
  | "correction_request.declined"
  | "order.cancel_requested"

Key properties: - serviceTitle, servicePrice, serviceDeliveryTime – Captured at order time - selectedOptions – Options selected by customer (immutable) - totalAmount – Computed: servicePrice + sum of option prices - commissionAmount – Platform commission: totalAmount × commissionRate - events – Audit trail of state transitions - notes – Admin notes or special instructions

Chat Entity

Communication channel for an order.

// domain/orders/chat.entity.ts
export class Chat {
  id: string;
  title: string;
  serviceId: string | null;
  orderId: string | null;
  ownerId: string;
  createdAt: Date;
  lastMessageAt: Date;
}

export class Message {
  id: string;
  chatId: string;
  senderId: string;
  content: string;
  timestamp: Date;
  attachments: Attachment[];
}

export class ChatMember {
  chatId: string;
  userId: string;
  isArchived: boolean;
}

type Attachment = {
  path: string;
  type: string;
  size: number;
}

Key features: - Chat can be order-specific or general - Messages support file attachments - Members can archive chats - lastMessageAt used for sorting

Comment Entity

Reviews and ratings for completed orders.

// domain/orders/comment.entity.ts
export class Comment {
  id: string;
  userId: string;
  authorName: string;
  serviceId: string;
  orderId: string;
  content: string;
  rating: number; // 1-5 stars
  replies: Reply[];
  createdAt: Date;
  updatedAt: Date;

  static create(
    id: string,
    userId: string,
    authorName: string,
    serviceId: string,
    orderId: string,
    content: string,
    rating: number
  ): Comment

  addReply(
    id: string,
    authorId: string,
    authorName: string,
    content: string,
    createdAt: Date,
    updatedAt: Date
  ): void
}

export class Reply {
  id: string;
  authorId: string;
  authorName: string;
  content: string;
  createdAt: Date;
  updatedAt: Date;
}

Key features: - One comment per order - Seller can reply to comments - Rating affects Service.averageRating - Comments visible on service page

Payment Entity

Payment transaction tracking.

// domain/orders/payment.entity.ts
export class Payment {
  id: string;
  amount: Decimal;
  orderAmount: Decimal;
  currency: string;
  userId: string;
  status: PaymentStatus; // 'received' | 'refunded' | 'released'
  createdAt: Date;

  static create(
    id: string,
    amount: Decimal,
    orderAmount: Decimal,
    currency: string,
    userId: string,
    status: PaymentStatus
  ): Payment
}

Payment statuses: - received – Payment collected from customer - refunded – Payment returned to customer (order rejected/cancelled) - released – Payment transferred to seller (order completed)

Repositories

OrderRepository

// domain/orders/order.repository.ts
export abstract class OrderRepository extends AbstractRepository<Order, string, OrderQueryPolicy> {
  abstract updateState(
    orderId: string,
    state: State,
    event: Event,
    opts?: any
  ): Promise<void>;
  abstract computeReceipt(orderId: string): Promise<Receipt>;
  abstract computeInvoice(orderId: string, user: User): Promise<Invoice>;
  abstract recordEvent(
    orderId: string,
    event: Event,
    transaction?: any
  ): Promise<void>;
  abstract monthlyCommission(filters: OrderOpQueryPolicy): Promise<MonthCommission[]>;
  abstract getOrdersInState(state: State): Promise<Order[]>;
}

export class OrderQueryPolicy {
  userId?: string;
  state?: OrderState;
  serviceId?: string;
  serviceTitle?: string;
  sellerId?: string;
  customerId?: string;
  createdFrom?: Date;
  createdTo?: Date;
}

Key operations: - updateState() – Transition to new state and record event - recordEvent() – Add event to audit trail - computeReceipt() – Generate receipt for order - computeInvoice() – Generate invoice for seller - monthlyCommission() – Calculate platform commission by month - getOrdersInState() – Get all orders in specific state

ChatRepository

// domain/orders/chat.repository.ts
export abstract class ChatRepository extends AbstractRepository<Chat> {
  abstract addMessage(message: Message): Promise<Message>;
  abstract getMessages(chatId: string, pagination: Pagination): Promise<Paginated<Message>>;
  abstract addMember(member: ChatMember): Promise<void>;
  abstract getMembers(chatId: string): Promise<ChatMember[]>;
  abstract isMember(userId: string, chatId: string): Promise<boolean>;
  abstract archiveChat(userId: string, chatId: string): Promise<void>;
  abstract updateLastMessageAt(chatId: string, timestamp: Date): Promise<void>;
}

CommentRepository

// domain/orders/comment.repository.ts
export abstract class CommentRepository extends AbstractRepository<Comment> {
  abstract getByServiceId(serviceId: string): Promise<Comment[]>;
  abstract getByOrderId(orderId: string): Promise<Comment | null>;
  abstract addReply(commentId: string, reply: Reply): Promise<void>;
}

PaymentRepository

// domain/orders/payment.repository.ts
export abstract class PaymentRepository extends AbstractRepository<Payment> {
  abstract updateStatus(id: string, status: PaymentStatus): Promise<void>;
}

Business Rules

Order Creation

  1. Payment must be completed first – Order created after successful payment
  2. Service data captured – Title, price, delivery time captured (immutable)
  3. Options captured – Selected options stored (immutable)
  4. Commission calculated – Based on current platform commission rate
  5. Initial state is "paid" – Awaiting seller acceptance

Order Workflow (State Machine)

The order follows a complex state machine (implemented with XState in adapters layer):

          ┌──────┐
          │ paid │ (initial state)
          └──┬───┘
     ┌───────┴────────┐
     │                │
     ↓                ↓
┌──────────┐    ┌────────────┐
│ rejected │    │ inprogress │
└──────────┘    └─────┬──────┘
        ┌─────────────┼─────────────┐
        │             │             │
        ↓             ↓             ↓
┌────────────────┐ ┌───────────┐ ┌──────────┐
│cancel_requested│ │ delivered │ │disputing │
└────────┬───────┘ └─────┬─────┘ └──────────┘
         │               │
    ┌────┴────┐     ┌────┴────┐
    │         │     │         │
    ↓         ↓     ↓         ↓
┌─────────┐┌───────────────────┐
│cancelled││correction_requested│
└─────────┘└─────────┬──────────┘
                ┌────┴────┐
                │         │
                ↓         ↓
           ┌──────────┐┌──────────┐
           │ delivered││ disputing│
           └────┬─────┘└──────────┘
           ┌───────────┐
           │ completed │
           └───────────┘

State transitions:

  • paidrejected (seller declines, refund issued)
  • paidinprogress (seller accepts)
  • inprogressdelivered (seller delivers work)
  • inprogresscancel_requested (customer requests cancel)
  • cancel_requestedcancelled (seller accepts cancel, refund issued)
  • cancel_requestedinprogress (seller rejects cancel)
  • cancel_requesteddisputing (after 3 cancel requests, admin review)
  • deliveredcompleted (customer approves)
  • deliveredcorrection_requested (customer requests changes)
  • correction_requesteddelivered (seller makes corrections)
  • disputingcompleted | cancelled (admin decision)

Refund Rules

Refunds are issued when: - Seller rejects order (paidrejected) - Seller accepts cancellation (cancel_requestedcancelled) - Admin resolves dispute in favor of customer

Payment Release Rules

Payment released to seller when: - Order reaches completed state - Platform commission deducted - Seller receives: totalAmount - commissionAmount

Late Order Detection

order.isLate() // Returns true if current time > delivery date
order.getAssumedDeliveryDate() // createdAt + serviceDeliveryTime + sum(option.additionalTime)

Dispute Escalation

  • After 3 cancellation requests, order moves to disputing
  • Admin reviews and makes final decision
  • Admin can resolve to completed, cancelled, or keep inprogress

Use Cases

Order Management

  • Create order – After payment completion
  • Accept order – Seller accepts to work on it
  • Reject order – Seller declines (within timeframe)
  • Deliver order – Seller submits completed work
  • Request corrections – Customer asks for changes
  • Complete order – Customer approves delivery
  • Request cancellation – Customer wants to cancel
  • Process cancellation – Seller accepts/rejects cancel request
  • Resolve dispute – Admin makes final decision

Chat Management

  • Create chat – For an order or general inquiry
  • Send message – Post message to chat
  • Upload attachment – Attach files to message
  • List messages – Get chat history
  • Archive chat – Hide from chat list
  • Join chat – Add participant (admin feature)

Comment Management

  • Create comment – Review completed order
  • Reply to comment – Seller responds to review
  • List comments – Get reviews for a service
  • Get order comment – Find comment for specific order

Integration Points

With Users Domain

  • Order.sellerId and Order.customerId reference User.id
  • Authorization checks: only customer/seller/admin can view order
  • Notifications sent to users on state changes

With Services Domain

  • Order.serviceId references Service.id
  • Service data captured at order creation
  • Completed orders increment Service.salesCount
  • Comments affect Service.averageRating

With Payments Domain

  • Order.paymentId references Payment.id
  • Payment must be "received" before order creation
  • Order completion triggers payment "released" status

With Accounts Domain

  • Order completion triggers balance credit to seller
  • Commission amount credited to platform account
  • Refunds trigger balance debit

Key Workflows

Happy Path Order Flow

1. Customer initiates payment
2. Payment completed
3. Order created (state = "paid")
4. Seller accepts (state = "inprogress")
5. Chat created for communication
6. Seller delivers (state = "delivered")
7. Customer approves (state = "completed")
8. Payment released to seller
9. Customer leaves comment/rating

Cancellation Flow

1. Order in "inprogress"
2. Customer requests cancellation (state = "cancel_requested")
3. Seller receives notification
4a. Seller accepts cancel (state = "cancelled")
    Refund issued
OR
4b. Seller rejects cancel (state = "inprogress")
    Work continues
OR
4c. After 3 cancel requests (state = "disputing")
    Admin resolves

Correction Request Flow

1. Order state = "delivered"
2. Customer requests corrections (state = "correction_requested")
3. Seller makes corrections
4. Seller redelivers (state = "delivered")
5. Customer reviews again

Data Model

┌──────────────┐
│    Order     │
├──────────────┤
│ id           │
│ sellerId     │────► User
│ customerId   │────► User
│ serviceId    │────► Service
│ paymentId    │────► Payment
│ state        │
│ totalAmount  │
│ commission   │
│ events[]     │
└──────────────┘
       │ 1:1
┌──────────────┐
│    Chat      │
├──────────────┤
│ id           │
│ orderId      │
│ ownerId      │
└──────────────┘
       │ 1:N
┌──────────────┐
│   Message    │
├──────────────┤
│ id           │
│ chatId       │
│ senderId     │
│ content      │
│ attachments[]│
└──────────────┘

┌──────────────┐
│   Comment    │
├──────────────┤
│ id           │
│ orderId      │────► Order
│ serviceId    │────► Service
│ userId       │────► User
│ rating       │
│ content      │
│ replies[]    │
└──────────────┘

┌──────────────┐
│   Payment    │
├──────────────┤
│ id           │
│ amount       │
│ status       │
│ userId       │
└──────────────┘

Analytics

Order Metrics

  • Completion rate – completed / total orders
  • Average delivery time – Actual vs promised
  • Cancellation rate – cancelled / total orders
  • Dispute rate – disputes / total orders
  • Late orders – Count of isLate() orders

Seller Metrics

  • Total orders – As seller
  • Completion rate – completed / accepted
  • Average rating – From comments
  • Response time – Time to accept/reject orders

Customer Metrics

  • Total orders – As customer
  • Review count – Comments left
  • Cancellation requests – Total cancel requests made

Best Practices

✅ Do

  • Capture service data – Store title, price, delivery time at order creation
  • Record all events – Maintain audit trail
  • Use state machine – Enforce valid transitions
  • Notify participants – Alert on state changes
  • Check authorization – Verify user role before transitions
  • Handle disputes fairly – Admin review for escalations

❌ Don't

  • Don't modify service data – Order is snapshot at purchase time
  • Don't allow invalid transitions – Use state machine guards
  • Don't skip refunds – Always issue refunds for cancellations/rejections
  • Don't allow late deliveries without consequences – Track and report
  • Don't delete orders – Maintain history for accountability
  • Don't bypass dispute resolution – Let admin handle escalations

Validation Rules

State Transitions

  • Only seller can accept/reject orders
  • Only seller can deliver work
  • Only customer can approve/request corrections
  • Only admin can resolve disputes
  • Guards check user role before allowing transition

Comment Creation

  • Can only comment on completed orders
  • One comment per order
  • Rating must be 1-5 stars
  • Content: 10-1000 characters

Message Creation

  • Must be chat member to send message
  • Content required
  • Attachments: max 5MB each

Summary

The Orders domain provides:

  • Complex order workflow with state machine
  • Real-time chat for customer-seller communication
  • Review system for service quality feedback
  • Payment tracking from capture to release
  • Dispute resolution for problematic orders
  • Audit trail of all order events

This domain orchestrates the entire service fulfillment process from purchase through completion or cancellation.