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

# API Documentation

## Overview

The Customer Management API provides comprehensive endpoints for managing customer information, relationships, and interactions within the Bee O'clock panel service. This API enables businesses to maintain customer records, handle attendee management, and support order-customer relationships with robust validation and data integrity.

## Base URL

```
{base_url}/v1/customer
```

## Authentication

All endpoints require authentication via Bearer token and business tenant ID header.

```http
Authorization: Bearer {access_token}
x-business-tenant-id: {tenant_id}
```

## Core Endpoints

### 1. Get Paginated Customers

Retrieves a paginated list of customers for the authenticated business.

**Endpoint:** `GET /paged`

**Headers:**

```http
Authorization: Bearer {access_token}
x-business-tenant-id: {tenant_id}
```

**Query Parameters:**

```typescript
{
  page?: number;           // Page number (default: 1)
  limit?: number;          // Items per page (default: 10, max: 100)
  sortBy?: string;         // Sort field (firstName, lastName, email, createdAt)
  sortDirection?: 'asc' | 'desc'; // Sort direction (default: 'desc')
  search?: string;         // Search term for name or email
  customerType?: CustomerTypeEnum; // Filter by customer type
}
```

**Response:**

```typescript
{
  items: CustomerDto[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasNext: boolean;
    hasPrev: boolean;
  };
  meta?: {
    searchTerm?: string;
    filters?: Record<string, any>;
  };
}
```

**Example Request:**

```bash
curl -X GET "https://api.beeoclock.com/v1/customer/paged?page=1&limit=20&search=john&sortBy=firstName" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "x-business-tenant-id: 614d1c4c5f1b2c001f5a7b23"
```

**Example Response:**

```json
{
  "items": [
    {
      "object": "CustomerDto",
      "_id": "67b8ac9d4b39c2fd27431017",
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+1234567890",
      "note": "Regular customer, prefers morning appointments",
      "customerType": "regular",
      "state": "active",
      "createdAt": "2025-02-21T16:40:41.031Z",
      "updatedAt": "2025-02-22T12:13:24.745Z"
    }
  ],
  "totalSize": 20,
}
```

**Error Responses:**

```typescript
// 400 Bad Request
{
  "statusCode": 400,
  "message": "Invalid pagination parameters",
  "error": "Bad Request"
}

// 403 Forbidden
{
  "statusCode": 403,
  "message": "Insufficient permissions to read customers",
  "error": "Forbidden"
}
```

***

### 2. Get Customer by ID

Retrieves detailed information for a specific customer.

**Endpoint:** `GET /{id}`

**Path Parameters:**

* `id` (string, required): Customer ID

**Response:**

```typescript
CustomerDto
```

**Example Request:**

```bash
curl -X GET "https://api.beeoclock.com/v1/customer/67b8ac9d4b39c2fd27431017" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "x-business-tenant-id: 614d1c4c5f1b2c001f5a7b23"
```

**Example Response:**

```json
{
  "object": "CustomerDto",
  "_id": "67b8ac9d4b39c2fd27431017",
  "firstName": "John",
  "lastName": "Smith",
  "email": "john.smith@example.com",
  "phone": "+1234567890",
  "note": "Regular customer, prefers morning appointments",
  "customerType": "regular",
  "state": "active",
  "stateHistory": [
    {
      "state": "active",
      "setAt": "2025-02-21T16:40:41.031Z",
      "reason": "Customer created"
    }
  ],
  "createdAt": "2025-02-21T16:40:41.031Z",
  "updatedAt": "2025-02-22T12:13:24.745Z",
  "_version": "2"
}
```

**Error Responses:**

```typescript
// 404 Not Found
{
  "statusCode": 404,
  "message": "Customer not found",
  "error": "Not Found"
}
```

***

### 3. Create Customer

Creates a new customer record with validation.

**Endpoint:** `POST /`

**Request Body:**

```typescript
CustomerDto {
  firstName?: string;      // Customer first name
  lastName?: string;       // Customer last name
  email?: string;          // Customer email (validated)
  phone?: string;          // Customer phone (validated and normalized)
  note?: string;           // Internal notes about customer
  customerType?: CustomerTypeEnum; // Customer type (default: 'regular')
}
```

**Validation Rules:**

* At least one of: `firstName`, `lastName`, `email`, or `phone` must be provided
* Email must be valid format if provided
* Phone must be valid format if provided (automatically normalized)
* Customer type defaults to 'regular'

**Response:**

```typescript
CustomerDto // Complete customer object with generated ID
```

**Example Request:**

```bash
curl -X POST "https://api.beeoclock.com/v1/customer" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "x-business-tenant-id: 614d1c4c5f1b2c001f5a7b23" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane.doe@example.com",
    "phone": "+1987654321",
    "note": "Prefers text message reminders"
  }'
```

**Example Response:**

```json
{
  "object": "CustomerDto",
  "_id": "67b8ac9d4b39c2fd27431018",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "phone": "1987654321",
  "note": "Prefers text message reminders",
  "customerType": "regular",
  "state": "active",
  "stateHistory": [
    {
      "state": "active",
      "setAt": "2025-02-25T10:30:15.123Z",
      "reason": "Customer created"
    }
  ],
  "createdAt": "2025-02-25T10:30:15.123Z",
  "updatedAt": "2025-02-25T10:30:15.123Z",
  "_version": "1"
}
```

**Error Responses:**

```typescript
// 400 Bad Request - Validation Error
{
  "statusCode": 400,
  "message": "At least one field must be filled: phone, email, first name or last name.",
  "error": "Bad Request"
}

// 400 Bad Request - Email Format Error
{
  "statusCode": 400,
  "message": "Invalid email format: invalid-email",
  "error": "Bad Request"
}

// 409 Conflict - Duplicate Customer
{
  "statusCode": 409,
  "message": "Customer with this email already exists",
  "error": "Conflict"
}
```

***

### 4. Update Customer

Updates an existing customer record with partial updates supported.

**Endpoint:** `PUT /{id}`

**Path Parameters:**

* `id` (string, required): Customer ID to update

**Request Body:**

```typescript
CustomerDto // Partial update object
```

**Response:**

```typescript
CustomerDto // Updated customer object
```

**Example Request:**

```bash
curl -X PUT "https://api.beeoclock.com/v1/customer/67b8ac9d4b39c2fd27431017" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "x-business-tenant-id: 614d1c4c5f1b2c001f5a7b23" \
  -H "Content-Type: application/json" \
  -d '{
    "note": "Updated note: Customer prefers afternoon appointments",
    "phone": "+1234567891"
  }'
```

**Example Response:**

```json
{
  "object": "CustomerDto",
  "_id": "67b8ac9d4b39c2fd27431017",
  "firstName": "John",
  "lastName": "Smith",
  "email": "john.smith@example.com",
  "phone": "1234567891",
  "note": "Updated note: Customer prefers afternoon appointments",
  "customerType": "regular",
  "state": "active",
  "stateHistory": [
    {
      "state": "active",
      "setAt": "2025-02-21T16:40:41.031Z",
      "reason": "Customer created"
    }
  ],
  "createdAt": "2025-02-21T16:40:41.031Z",
  "updatedAt": "2025-02-25T11:45:30.456Z",
  "_version": "3"
}
```

***

### 5. Delete Customer

Soft deletes a customer record (sets state to inactive).

**Endpoint:** `DELETE /{id}`

**Path Parameters:**

* `id` (string, required): Customer ID to delete

**Response:**

```typescript
void // No content returned
```

**Example Request:**

```bash
curl -X DELETE "https://api.beeoclock.com/v1/customer/67b8ac9d4b39c2fd27431017" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "x-business-tenant-id: 614d1c4c5f1b2c001f5a7b23"
```

**Success Response:**

```http
HTTP/1.1 200 OK
```

**Error Responses:**

```typescript
// 404 Not Found
{
  "statusCode": 404,
  "message": "Customer not found",
  "error": "Not Found"
}

// 409 Conflict - Customer has active orders
{
  "statusCode": 409,
  "message": "Cannot delete customer with active orders",
  "error": "Conflict"
}
```

***

## Data Transfer Objects

### CustomerDto

```typescript
interface CustomerDto {
  object?: 'CustomerDto';
  _id?: string;              // Auto-generated MongoDB ObjectId
  firstName?: string;        // Customer first name (max 100 chars)
  lastName?: string;         // Customer last name (max 100 chars)
  phone?: string;           // Normalized phone number (numbers only)
  email?: string;           // Validated email address
  note?: string;            // Internal business notes (max 1000 chars)
  customerType?: CustomerTypeEnum; // Customer classification
  state?: string;           // Entity state (active, inactive)
  stateHistory?: StateHistoryEntry[]; // State change audit trail
  createdAt?: string;       // ISO date string
  updatedAt?: string;       // ISO date string
  _version?: string;        // Optimistic locking version
}
```

### CustomerPaginationDto

```typescript
interface CustomerPaginationDto {
  page?: number;            // Page number (min: 1, default: 1)
  limit?: number;           // Items per page (min: 1, max: 100, default: 10)
  sortBy?: string;          // Sort field
  sortDirection?: 'asc' | 'desc'; // Sort direction
  search?: string;          // Search term
  customerType?: CustomerTypeEnum; // Filter by type
}
```

## Enumerations

### CustomerTypeEnum

```typescript
enum CustomerTypeEnum {
  regular = 'regular',        // Regular registered customer
  unregistered = 'unregistered', // Unregistered customer
  new = 'new',               // First-time customer
  anonymous = 'anonymous'     // Anonymous customer (public orders)
}
```

## Customer-Order Relationships

### Order Integration

Customers are integrated with orders through the attendee system:

```typescript
// Customer as order attendee
interface AttendantDto {
  object: 'AttendantDto';
  customer: CustomerDto;     // Customer snapshot
  firstTime: boolean;        // First visit indicator
}

// Order contains customer references
interface OrderDto {
  customer: CustomerDto;     // Primary customer (payer)
  services: OrderServiceDto[]; // Services with attendees
}

// Each service has appointment details with attendees
interface OrderAppointmentDetailsDto {
  attendees: AttendantDto[]; // Multiple attendees per service
  // ... other appointment details
}
```

### Payment Integration

Customers are captured in payment records:

```typescript
interface PaymentDto {
  payer: CustomerDto;        // Customer who made payment
  orderId: string;           // Associated order
  // ... payment details
}
```

## Validation Rules

### Customer Creation Validation

1. **Mandatory Fields**: At least one of `firstName`, `lastName`, `email`, or `phone` required
2. **Email Validation**: Must match regex pattern for valid email format
3. **Phone Validation**: Must match international phone number pattern
4. **Phone Normalization**: Automatically extracts and stores only numbers
5. **Duplicate Prevention**: Prevents duplicate customers based on email/phone combination

### Business Rules

1. **Customer Types**:
   * `regular`: Standard registered customers with full profile
   * `unregistered`: Customers without full registration
   * `new`: First-time customers
   * `anonymous`: Anonymous public order customers
2. **Data Integrity**:
   * Customer data is snapshotted in orders and payments
   * Updates to customer records don't affect historical data
   * Soft deletion preserves data for reporting and history
3. **Multi-tenancy**:
   * All operations are tenant-scoped
   * Customers are isolated per business tenant
   * No cross-tenant data access

## Error Handling

### Common Error Codes

| Status Code | Error Type            | Description                                         |
| ----------- | --------------------- | --------------------------------------------------- |
| 400         | Validation Error      | Invalid request data or missing required fields     |
| 401         | Unauthorized          | Invalid or missing authentication token             |
| 403         | Forbidden             | Insufficient permissions for operation              |
| 404         | Not Found             | Customer not found                                  |
| 409         | Conflict              | Duplicate customer or business rule violation       |
| 422         | Unprocessable Entity  | Valid request but business logic prevents execution |
| 500         | Internal Server Error | Unexpected server error                             |

### Error Response Format

```typescript
interface ErrorResponse {
  statusCode: number;
  message: string;
  error: string;
  details?: string[];     // Additional validation errors
  timestamp?: string;     // Error timestamp
  path?: string;         // Request path
}
```

## Security Considerations

### Authentication & Authorization

* **Bearer Token Required**: All endpoints require valid JWT token
* **Tenant Isolation**: Strict tenant-based data separation
* **Permission Validation**: Role-based access control for operations
* **Audit Logging**: All customer operations are logged for security

### Data Protection

* **PII Handling**: Customer data treated as Personally Identifiable Information
* **GDPR Compliance**: Support for data portability and deletion rights
* **Encryption**: Sensitive data encrypted at rest and in transit
* **Access Logging**: Customer data access is logged and monitored

### Rate Limiting

* **API Rate Limits**: Standard rate limiting applied to all endpoints
* **Bulk Operations**: Special consideration for pagination and bulk retrieval
* **Search Optimization**: Search queries optimized to prevent performance issues

## Performance Considerations

### Database Optimization

* **Indexing**: Optimized indexes on frequently queried fields
* **Pagination**: Efficient cursor-based pagination for large datasets
* **Caching**: Redis caching for frequently accessed customer data
* **Query Optimization**: Selective field projection for list operations

### Caching Strategy

```typescript
// Cache keys
const CACHE_KEYS = {
  CUSTOMER_BY_ID: 'customer:id:{customerId}',
  PAGED_CUSTOMERS: 'customers:paged:{tenantId}:{hash}',
  CUSTOMER_SEARCH: 'customers:search:{tenantId}:{query}'
};

// Cache TTL
const CACHE_TTL = {
  CUSTOMER_DETAILS: 300,    // 5 minutes
  CUSTOMER_LIST: 60,        // 1 minute
  SEARCH_RESULTS: 180       // 3 minutes
};
```

## Integration Examples

### Customer Creation Flow

```typescript
// Step 1: Validate customer data
const customerData = {
  firstName: 'John',
  lastName: 'Doe',
  email: 'john.doe@example.com',
  phone: '+1-555-123-4567'
};

// Step 2: Create customer
const response = await fetch('/v1/customer', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'x-business-tenant-id': tenantId,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(customerData)
});

const customer = await response.json();

// Step 3: Customer ID available for orders
const customerId = customer._id;
```

### Order Attendee Integration

```typescript
// Using customer in order creation
const orderService = {
  serviceSnapshot: { /* service details */ },
  orderAppointmentDetails: {
    start: '2025-03-01T10:00:00Z',
    end: '2025-03-01T11:00:00Z',
    attendees: [{
      customer: customer,      // CustomerDto
      firstTime: false
    }]
  }
};
```

### Customer Search and Selection

```typescript
// Search customers for appointment booking
const searchResponse = await fetch(
  `/v1/customer/paged?search=${encodeURIComponent(searchTerm)}&limit=10`,
  {
    headers: {
      'Authorization': `Bearer ${token}`,
      'x-business-tenant-id': tenantId
    }
  }
);

const { items: customers } = await searchResponse.json();

// Present customer list for selection
customers.forEach(customer => {
  console.log(`${customer.firstName} ${customer.lastName} (${customer.email})`);
});
```

## Testing Examples

### Unit Testing

```typescript
describe('Customer API', () => {
  test('should create customer with valid data', async () => {
    const customerData = {
      firstName: 'Test',
      lastName: 'User',
      email: 'test@example.com'
    };

    const response = await request(app)
      .post('/v1/customer')
      .set('Authorization', `Bearer ${authToken}`)
      .set('x-business-tenant-id', tenantId)
      .send(customerData)
      .expect(200);

    expect(response.body.firstName).toBe('Test');
    expect(response.body.email).toBe('test@example.com');
    expect(response.body._id).toBeDefined();
  });

  test('should validate email format', async () => {
    const invalidData = {
      firstName: 'Test',
      email: 'invalid-email'
    };

    await request(app)
      .post('/v1/customer')
      .set('Authorization', `Bearer ${authToken}`)
      .set('x-business-tenant-id', tenantId)
      .send(invalidData)
      .expect(400);
  });
});
```

***

## Summary

The Customer Management API provides a robust foundation for managing customer relationships within the Bee O'clock ecosystem. Key features include:

* **Comprehensive CRUD Operations** with validation and error handling
* **Advanced Search and Pagination** for efficient customer discovery
* **Strong Data Validation** ensuring data quality and consistency
* **Integration Support** for orders, payments, and appointments
* **Multi-tenant Architecture** with proper data isolation
* **Performance Optimization** through caching and efficient querying
* **Security Compliance** with authentication, authorization, and audit logging

The API supports complex business scenarios including customer-order relationships, payment processing, and historical data preservation while maintaining high performance and data integrity standards.
