> 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/expense-management/api.md).

# API Documentation

## Overview

The Expense Management API provides comprehensive functionality for managing business expenses and expense categories within the Bee O'clock panel service. This module handles the complete expense lifecycle, including creation, updates, categorization, deletion, and detailed tracking of expense items with multi-currency support.

## Base Configuration

### Authentication

All endpoints require Bearer token authentication.

### Headers

* `Authorization: Bearer <token>` - Required for all endpoints
* `x-business-tenant-id: <tenant_id>` - Required for multi-tenancy support
* `Content-Type: application/json` - For POST/PUT requests

### Base URL

```
/api/v1/expense
```

## Expense Endpoints

### 1. Get Paginated Expenses

**Endpoint:** `GET /api/v1/expense/paged`

**Description:** Retrieves a paginated list of expenses with advanced filtering capabilities.

**Query Parameters:**

```typescript
{
  page?: number;           // Page number (default: 1)
  size?: number;           // Items per page (default: 10)
  phrase?: string;         // Search phrase for expense description
  start?: string;          // Start date filter (ISO string)
  end?: string;            // End date filter (ISO string)
  expenseCategories?: string[]; // Filter by expense categories
}
```

**Response:**

```typescript
{
  items: ExpenseDto[];
  totalSize: number;
}
```

**Example Request:**

```bash
GET /api/v1/expense/paged?page=1&size=10&phrase=office&start=2024-01-01T00:00:00.000Z&end=2024-12-31T23:59:59.999Z&expenseCategories[]=office-supplies&expenseCategories[]=utilities
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
```

**Example Response:**

```json
{
  "items": [
    {
      "_id": "64fa1c71b19d6d001c88a91f",
      "object": "ExpenseDto",
      "totalValue": {
        "object": "ExpenseValueDto",
        "amount": 450.75,
        "currency": "USD"
      },
      "expensedAt": "2024-07-26T10:00:00.000Z",
      "description": "Office supplies and equipment purchase",
      "items": [
        {
          "object": "ExpenseLineItemDto",
          "categories": [
            {
              "_id": "64fa1c71b19d6d001c88a920",
              "object": "ExpenseCategoryDto",
              "name": "office-supplies",
              "description": "General office supplies and materials"
            }
          ],
          "itemValue": {
            "object": "ExpenseValueDto",
            "amount": 275.50,
            "currency": "USD"
          },
          "description": "Desk chairs and office furniture",
          "source": {
            "object": "ExpenseSourceDto",
            "sourceId": "64fa1c71b19d6d001c88a921",
            "sourceType": "supplier",
            "name": "Office Depot",
            "description": "Office furniture supplier"
          }
        },
        {
          "object": "ExpenseLineItemDto",
          "categories": [
            {
              "_id": "64fa1c71b19d6d001c88a922",
              "object": "ExpenseCategoryDto",
              "name": "technology",
              "description": "Technology equipment and software"
            }
          ],
          "itemValue": {
            "object": "ExpenseValueDto",
            "amount": 175.25,
            "currency": "USD"
          },
          "description": "Computer peripherals and accessories",
          "source": {
            "object": "ExpenseSourceDto",
            "sourceId": "64fa1c71b19d6d001c88a923",
            "sourceType": "supplier",
            "name": "Best Buy",
            "description": "Technology equipment supplier"
          }
        }
      ],
      "createdAt": "2024-07-26T08:00:00.000Z",
      "updatedAt": "2024-07-26T08:30:00.000Z"
    }
  ],
  "totalSize": 45
}
```

### 2. Get Expense by ID

**Endpoint:** `GET /api/v1/expense/{id}`

**Description:** Retrieves a specific expense by its ID with permission validation.

**Path Parameters:**

* `id` (string, required) - Expense ID

**Response:** `ExpenseDto`

**Example Request:**

```bash
GET /api/v1/expense/64fa1c71b19d6d001c88a91f
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
```

**Example Response:**

```json
{
  "_id": "64fa1c71b19d6d001c88a91f",
  "object": "ExpenseDto",
  "totalValue": {
    "object": "ExpenseValueDto",
    "amount": 1250.00,
    "currency": "USD"
  },
  "expensedAt": "2024-07-26T10:00:00.000Z",
  "description": "Monthly salary payment for staff",
  "items": [
    {
      "object": "ExpenseLineItemDto",
      "categories": [
        {
          "_id": "64fa1c71b19d6d001c88a924",
          "object": "ExpenseCategoryDto",
          "name": "salary",
          "description": "Employee salary and compensation"
        }
      ],
      "itemValue": {
        "object": "ExpenseValueDto",
        "amount": 800.00,
        "currency": "USD"
      },
      "description": "Base salary for massage therapist",
      "source": {
        "object": "ExpenseSourceDto",
        "sourceId": "64fa1c71b19d6d001c88a925",
        "sourceType": "member",
        "name": "Jane Smith",
        "description": "Senior massage therapist"
      }
    },
    {
      "object": "ExpenseLineItemDto",
      "categories": [
        {
          "_id": "64fa1c71b19d6d001c88a924",
          "object": "ExpenseCategoryDto",
          "name": "salary",
          "description": "Employee salary and compensation"
        }
      ],
      "itemValue": {
        "object": "ExpenseValueDto",
        "amount": 450.00,
        "currency": "USD"
      },
      "description": "Part-time receptionist salary",
      "source": {
        "object": "ExpenseSourceDto",
        "sourceId": "64fa1c71b19d6d001c88a926",
        "sourceType": "member",
        "name": "Mike Johnson",
        "description": "Front desk receptionist"
      }
    }
  ],
  "createdAt": "2024-07-26T08:00:00.000Z",
  "updatedAt": "2024-07-26T08:30:00.000Z"
}
```

### 3. Create Expense

**Endpoint:** `POST /api/v1/expense`

**Description:** Creates a new expense with validation and permission checks.

**Request Body:** `ExpenseDto`

**Response:** `ExpenseDto`

**Example Request:**

```bash
POST /api/v1/expense
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
Content-Type: application/json

{
  "totalValue": {
    "amount": 320.50,
    "currency": "USD"
  },
  "expensedAt": "2024-07-26T14:00:00.000Z",
  "description": "Monthly utility bills payment",
  "items": [
    {
      "categories": [
        {
          "name": "utilities",
          "description": "Utility bills and services"
        }
      ],
      "itemValue": {
        "amount": 180.00,
        "currency": "USD"
      },
      "description": "Electricity bill for spa facility",
      "source": {
        "sourceId": "64fa1c71b19d6d001c88a927",
        "sourceType": "supplier",
        "name": "Electric Company",
        "description": "Local electricity provider"
      }
    },
    {
      "categories": [
        {
          "name": "utilities",
          "description": "Utility bills and services"
        }
      ],
      "itemValue": {
        "amount": 85.50,
        "currency": "USD"
      },
      "description": "Water and sewer services",
      "source": {
        "sourceId": "64fa1c71b19d6d001c88a928",
        "sourceType": "supplier",
        "name": "Water Department",
        "description": "Municipal water services"
      }
    },
    {
      "categories": [
        {
          "name": "utilities",
          "description": "Utility bills and services"
        }
      ],
      "itemValue": {
        "amount": 55.00,
        "currency": "USD"
      },
      "description": "Internet and phone services",
      "source": {
        "sourceId": "64fa1c71b19d6d001c88a929",
        "sourceType": "supplier",
        "name": "Telecom Provider",
        "description": "Business internet and phone services"
      }
    }
  ]
}
```

**Example Response:**

```json
{
  "_id": "64fa1c71b19d6d001c88a930",
  "object": "ExpenseDto",
  "totalValue": {
    "object": "ExpenseValueDto",
    "amount": 320.50,
    "currency": "USD"
  },
  "expensedAt": "2024-07-26T14:00:00.000Z",
  "description": "Monthly utility bills payment",
  "items": [
    {
      "object": "ExpenseLineItemDto",
      "categories": [
        {
          "_id": "64fa1c71b19d6d001c88a931",
          "object": "ExpenseCategoryDto",
          "name": "utilities",
          "description": "Utility bills and services"
        }
      ],
      "itemValue": {
        "object": "ExpenseValueDto",
        "amount": 180.00,
        "currency": "USD"
      },
      "description": "Electricity bill for spa facility",
      "source": {
        "object": "ExpenseSourceDto",
        "sourceId": "64fa1c71b19d6d001c88a927",
        "sourceType": "supplier",
        "name": "Electric Company",
        "description": "Local electricity provider"
      }
    }
  ],
  "createdAt": "2024-07-26T14:00:00.000Z",
  "updatedAt": "2024-07-26T14:00:00.000Z"
}
```

### 4. Update Expense

**Endpoint:** `PUT /api/v1/expense/{id}`

**Description:** Updates an existing expense with validation and permission checks.

**Path Parameters:**

* `id` (string, required) - Expense ID

**Request Body:** `ExpenseDto`

**Response:** `ExpenseDto`

**Example Request:**

```bash
PUT /api/v1/expense/64fa1c71b19d6d001c88a930
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
Content-Type: application/json

{
  "_id": "64fa1c71b19d6d001c88a930",
  "totalValue": {
    "amount": 340.75,
    "currency": "USD"
  },
  "expensedAt": "2024-07-26T14:00:00.000Z",
  "description": "Monthly utility bills payment - Updated",
  "items": [
    {
      "categories": [
        {
          "name": "utilities",
          "description": "Utility bills and services"
        }
      ],
      "itemValue": {
        "amount": 200.25,
        "currency": "USD"
      },
      "description": "Electricity bill for spa facility - Higher usage",
      "source": {
        "sourceId": "64fa1c71b19d6d001c88a927",
        "sourceType": "supplier",
        "name": "Electric Company",
        "description": "Local electricity provider"
      }
    }
  ]
}
```

### 5. Delete Expense

**Endpoint:** `DELETE /api/v1/expense/{id}`

**Description:** Deletes an expense with permission validation.

**Path Parameters:**

* `id` (string, required) - Expense ID

**Response:** `void` (204 No Content)

**Example Request:**

```bash
DELETE /api/v1/expense/64fa1c71b19d6d001c88a930
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
```

## Expense Category Endpoints

### 1. Get Paginated Expense Categories

**Endpoint:** `GET /api/v1/expense/category/paged`

**Description:** Retrieves a paginated list of expense categories.

**Query Parameters:**

```typescript
{
  page?: number;           // Page number (default: 1)
  size?: number;           // Items per page (default: 10)
}
```

**Response:**

```typescript
{
  items: ExpenseCategoryDto[];
  totalSize: number;
}
```

**Example Request:**

```bash
GET /api/v1/expense/category/paged?page=1&size=20
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
```

**Example Response:**

```json
{
  "items": [
    {
      "_id": "64fa1c71b19d6d001c88a931",
      "object": "ExpenseCategoryDto",
      "name": "salary",
      "description": "Employee salary and compensation expenses",
      "createdAt": "2024-07-26T08:00:00.000Z",
      "updatedAt": "2024-07-26T08:00:00.000Z"
    },
    {
      "_id": "64fa1c71b19d6d001c88a932",
      "object": "ExpenseCategoryDto",
      "name": "utilities",
      "description": "Utility bills and facility services",
      "createdAt": "2024-07-26T08:00:00.000Z",
      "updatedAt": "2024-07-26T08:00:00.000Z"
    },
    {
      "_id": "64fa1c71b19d6d001c88a933",
      "object": "ExpenseCategoryDto",
      "name": "office-supplies",
      "description": "General office supplies and materials",
      "createdAt": "2024-07-26T08:00:00.000Z",
      "updatedAt": "2024-07-26T08:00:00.000Z"
    }
  ],
  "totalSize": 15
}
```

### 2. Create Expense Category

**Endpoint:** `POST /api/v1/expense/category`

**Description:** Creates a new expense category with validation.

**Request Body:** `ExpenseCategoryDto`

**Response:** `void` (201 Created)

**Example Request:**

```bash
POST /api/v1/expense/category
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
Content-Type: application/json

{
  "name": "marketing",
  "description": "Marketing and advertising expenses"
}
```

### 3. Create Multiple Expense Categories

**Endpoint:** `POST /api/v1/expense/category/bulk`

**Description:** Creates multiple expense categories in a single request.

**Request Body:** `ExpenseCategoryDto[]`

**Response:** `void` (201 Created)

**Example Request:**

```bash
POST /api/v1/expense/category/bulk
Authorization: Bearer <token>
x-business-tenant-id: <tenant_id>
Content-Type: application/json

[
  {
    "name": "marketing",
    "description": "Marketing and advertising expenses"
  },
  {
    "name": "travel",
    "description": "Business travel and transportation expenses"
  },
  {
    "name": "training",
    "description": "Employee training and professional development"
  }
]
```

## Data Models

### ExpenseDto

```typescript
{
  _id?: string;                              // Expense ID
  object?: 'ExpenseDto';                     // Object type identifier
  totalValue: ExpenseValueDto;               // Total amount of the expense
  expensedAt: string;                        // Date of the expense (ISO string)
  description?: string;                      // Optional description
  items?: ExpenseItemDto[];                  // Array of expense line items
  createdAt?: string;                        // Creation timestamp
  updatedAt?: string;                        // Last update timestamp
}
```

### ExpenseValueDto

```typescript
{
  object?: 'ExpenseValueDto';                // Object type identifier
  amount: number;                            // Expense amount
  currency: CurrencyCodeEnum;                // Currency code (USD, EUR, etc.)
}
```

### ExpenseItemDto

```typescript
{
  object?: 'ExpenseLineItemDto';             // Object type identifier
  categories: ExpenseCategoryDto[];          // Array of categorizing tags
  itemValue: ExpenseValueDto;                // Total price for this line item
  description: string;                       // Description for this line item
  source: ExpenseSourceDto;                  // Associated product, resource, or member
}
```

### ExpenseSourceDto

```typescript
{
  object?: 'ExpenseSourceDto';               // Object type identifier
  sourceId: string;                          // ID of the source entity
  sourceType: ExpenseSourceTypeEnum;         // Type of the source
  name?: string;                             // Name of the entity
  description?: string;                      // Optional description
}
```

### ExpenseCategoryDto

```typescript
{
  _id?: string;                              // Category ID
  object?: 'ExpenseCategoryDto';             // Object type identifier
  name: string;                              // Category name
  description?: string;                      // Optional description
  createdAt?: string;                        // Creation timestamp
  updatedAt?: string;                        // Last update timestamp
}
```

### ExpensePaginationDto

```typescript
{
  page?: number;                             // Page number (default: 1)
  size?: number;                             // Items per page (default: 10)
  phrase?: string;                           // Search phrase for description
  start?: string;                            // Start date filter (ISO string)
  end?: string;                              // End date filter (ISO string)
  expenseCategories?: string[];              // Filter by expense categories
}
```

## Enums

### ExpenseSourceTypeEnum

```typescript
enum ExpenseSourceTypeEnum {
  member = 'member',                         // Employee/staff member
  resource = 'resource',                     // Business resource
  product = 'product',                       // Product or inventory item
  supplier = 'supplier'                      // External supplier/vendor
}
```

### CurrencyCodeEnum

```typescript
enum CurrencyCodeEnum {
  USD = 'USD',                               // US Dollar
  EUR = 'EUR',                               // Euro
  GBP = 'GBP',                               // British Pound
  CAD = 'CAD',                               // Canadian Dollar
  AUD = 'AUD',                               // Australian Dollar
  JPY = 'JPY',                               // Japanese Yen
  CHF = 'CHF',                               // Swiss Franc
  CNY = 'CNY',                               // Chinese Yuan
  INR = 'INR',                               // Indian Rupee
  BRL = 'BRL',                               // Brazilian Real
  MXN = 'MXN',                               // Mexican Peso
  ZAR = 'ZAR'                                // South African Rand
}
```

## Error Handling

### Common Error Responses

#### 400 Bad Request

```json
{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request",
  "details": [
    {
      "field": "totalValue.amount",
      "message": "Amount must be a positive number"
    },
    {
      "field": "expensedAt",
      "message": "Expense date is required"
    }
  ]
}
```

#### 401 Unauthorized

```json
{
  "statusCode": 401,
  "message": "Unauthorized",
  "error": "Authentication required"
}
```

#### 403 Forbidden

```json
{
  "statusCode": 403,
  "message": "Access denied",
  "error": "Insufficient permissions to access expense management"
}
```

#### 404 Not Found

```json
{
  "statusCode": 404,
  "message": "Expense not found",
  "error": "Expense with ID 64fa1c71b19d6d001c88a91f does not exist"
}
```

#### 409 Conflict

```json
{
  "statusCode": 409,
  "message": "Expense category creation conflict",
  "error": "Expense category with name 'salary' already exists"
}
```

#### 422 Unprocessable Entity

```json
{
  "statusCode": 422,
  "message": "Business validation failed",
  "error": "Cannot delete expense category that is currently used in active expenses"
}
```

## Business Rules

### Expense Creation

1. **Amount Validation**: Total expense amount must be positive and match sum of line items
2. **Date Validation**: Expense date is required and must be a valid ISO date string
3. **Currency Consistency**: All line items must use the same currency as the total
4. **Category Validation**: All categories must exist in the expense category collection
5. **Source Validation**: All sources must reference valid entities (members, products, suppliers)

### Expense Updates

1. **Amount Recalculation**: Total amount is automatically recalculated from line items
2. **Category Integrity**: Categories must remain valid and existing
3. **Source Integrity**: Source references must remain valid
4. **Audit Trail**: All changes are tracked for compliance and auditing
5. **Permission Validation**: User must have appropriate permissions for updates

### Expense Deletion

1. **Soft Delete**: Expenses are marked as deleted rather than physically removed
2. **Audit Preservation**: All historical data is maintained for compliance
3. **Reference Integrity**: Related data references are handled appropriately
4. **Permission Requirements**: User must have delete permissions

### Category Management

1. **Name Uniqueness**: Category names must be unique within the tenant
2. **Usage Tracking**: Cannot delete categories that are currently used in expenses
3. **Bulk Operations**: Support for efficient bulk category creation
4. **Predefined Categories**: System provides predefined categories for common expense types

### Permission Requirements

1. **Expense Operations**:
   * `READ_EXPENSE` - View expenses
   * `CREATE_EXPENSE` - Create new expenses
   * `EDIT_EXPENSE` - Update existing expenses
   * `DELETE_EXPENSE` - Delete expenses
2. **Category Operations**:
   * `READ_EXPENSE_CATEGORY` - View expense categories
   * `CREATE_EXPENSE_CATEGORY` - Create new categories
   * `EDIT_EXPENSE_CATEGORY` - Update existing categories
   * `DELETE_EXPENSE_CATEGORY` - Delete categories

## Performance Considerations

### Pagination

* Default page size: 10 items
* Maximum page size: 100 items
* Use pagination for large expense lists

### Filtering and Search

* Date range filtering optimized with database indexes
* Text search across expense descriptions
* Category-based filtering with array operations
* Multi-currency support for international businesses

### Caching

* Expense category data is heavily cached due to infrequent changes
* Recent expenses cached for dashboard displays
* Search result caching for common queries

### Database Optimization

* Compound indexes on date ranges and categories
* Text indexes for description search
* Optimized aggregation for expense totals and reports

## Rate Limiting

* **Read Operations**: 100 requests per minute per user
* **Write Operations**: 30 requests per minute per user
* **Bulk Operations**: 10 requests per minute per user

## Monitoring and Logging

### Request Logging

All API requests are logged with:

* Request ID for tracing
* User context and permissions
* Performance metrics
* Error details and stack traces

### Business Event Logging

* Expense creation, updates, and deletions
* Category management operations
* Permission validation events
* Financial data access and modifications

### Performance Monitoring

* Response time tracking for all endpoints
* Database query performance analysis
* Cache hit rates and effectiveness
* Error rate monitoring and alerting

## Security Considerations

### Input Validation

* Comprehensive validation of all financial data
* Amount validation to prevent negative or invalid values
* Date validation and format checking
* Source and category reference validation

### Access Control

* Role-based permission system with granular controls
* Tenant-based data isolation for multi-tenant security
* API rate limiting and abuse prevention
* Audit logging for all financial operations

### Financial Data Protection

* Encryption of sensitive financial information
* Secure handling of currency and amount data
* Compliance with financial data protection regulations
* Regular security audits and vulnerability assessments

## Integration Examples

### Creating a Comprehensive Expense

```typescript
const salaryExpense = {
  totalValue: {
    amount: 5500.00,
    currency: "USD"
  },
  expensedAt: "2024-07-26T10:00:00.000Z",
  description: "Monthly staff salary payment",
  items: [
    {
      categories: [
        {
          name: "salary",
          description: "Employee salary and compensation"
        }
      ],
      itemValue: {
        amount: 3000.00,
        currency: "USD"
      },
      description: "Senior massage therapist salary",
      source: {
        sourceId: "64fa1c71b19d6d001c88a925",
        sourceType: "member",
        name: "Jane Smith",
        description: "Senior massage therapist"
      }
    },
    {
      categories: [
        {
          name: "salary",
          description: "Employee salary and compensation"
        }
      ],
      itemValue: {
        amount: 2500.00,
        currency: "USD"
      },
      description: "Receptionist and administrative salary",
      source: {
        sourceId: "64fa1c71b19d6d001c88a926",
        sourceType: "member",
        name: "Mike Johnson",
        description: "Front desk receptionist"
      }
    }
  ]
};
```

### Advanced Expense Search

```typescript
// Search for expenses in a date range with specific categories
GET /api/v1/expense/paged?
  start=2024-07-01T00:00:00.000Z&
  end=2024-07-31T23:59:59.999Z&
  expenseCategories[]=salary&
  expenseCategories[]=utilities&
  phrase=monthly&
  page=1&
  size=25
```

### Bulk Category Creation

```typescript
const businessCategories = [
  {
    name: "rent",
    description: "Office and facility rental expenses"
  },
  {
    name: "insurance",
    description: "Business insurance premiums and coverage"
  },
  {
    name: "supplies",
    description: "General business supplies and materials"
  },
  {
    name: "maintenance",
    description: "Facility maintenance and repairs"
  },
  {
    name: "professional-services",
    description: "Legal, accounting, and consulting services"
  }
];

// Create all categories in one request
POST /api/v1/expense/category/bulk
Content-Type: application/json
Body: businessCategories
```
