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

# API Documentation

## Overview

The Member Management API provides comprehensive team member management capabilities for the Bee O'clock platform. This API handles member registration, profile management, role assignments, service assignments, and team administration within business contexts.

## Base URL

```
{baseUrl}/api/v1/member
```

## Authentication

All endpoints require authentication via:

* **Bearer Token**: Firebase JWT token in Authorization header
* **Business Tenant ID**: Required in `x-business-tenant-id` header for tenant isolation

## API Endpoints

### 1. Get Paginated Members

**Endpoint:** `GET /member/paged`

**Description:** Retrieves a paginated list of team members with search and filtering capabilities.

**Request Parameters:**

```typescript
interface MemberPaginationDto {
  page?: number;           // Page number (default: 1)
  pageSize?: number;       // Items per page (default: 10, max: 100)
  search?: string;         // Search term for name/email
  role?: RoleEnum;         // Filter by member role
  profileStatus?: MemberProfileStatusEnum; // Filter by profile status
  sortBy?: string;         // Sort field (default: 'createdAt')
  sortDirection?: 'asc' | 'desc'; // Sort direction (default: 'desc')
}
```

**Query Parameters:**

* `page` (optional): Page number starting from 1
* `pageSize` (optional): Number of items per page (1-100)
* `search` (optional): Search in firstName, lastName, email
* `role` (optional): Filter by role (ADMIN, SPECIALIST, RECEPTION)
* `profileStatus` (optional): Filter by status (active, inactive, pending)
* `sortBy` (optional): Field to sort by
* `sortDirection` (optional): Sort direction

**Response:**

```typescript
{
  items: MemberDto[];
  pagination: {
    page: number;
    pageSize: number;
    total: number;
    totalPages: number;
    hasNextPage: boolean;
    hasPreviousPage: boolean;
  }
}
```

**Example Request:**

```bash
GET /api/v1/member/paged?page=1&pageSize=20&search=john&role=SPECIALIST&profileStatus=active
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
```

**Example Response:**

```json
{
  "items": [
    {
      "_id": "648f8f2e1234567890abcdef",
      "object": "MemberDto",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john.doe@example.com",
      "phone": "+1234567890",
      "role": "SPECIALIST",
      "profileStatus": "active",
      "assignments": {
        "service": {
          "full": false,
          "include": [
            {
              "service": "service-id-123",
              "serviceId": "service-123"
            }
          ]
        }
      },
      "createdAt": "2023-06-18T10:30:00.000Z",
      "updatedAt": "2023-06-18T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
  }
}
```

***

### 2. Get Member by ID

**Endpoint:** `GET /member/:id`

**Description:** Retrieves detailed information for a specific team member.

**Path Parameters:**

* `id` (required): Member ID (ObjectId format)

**Response:**

```typescript
MemberDto
```

**Example Request:**

```bash
GET /api/v1/member/648f8f2e1234567890abcdef
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
```

**Example Response:**

```json
{
  "_id": "648f8f2e1234567890abcdef",
  "object": "MemberDto",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "phone": "+1234567890",
  "avatar": {
    "_id": "avatar-id-123",
    "uri": "https://storage.example.com/avatar.jpg",
    "mediaType": "IMAGE"
  },
  "role": "SPECIALIST",
  "roles": [
    {
      "_id": "role-id-123",
      "name": "Service Provider",
      "permissions": ["READ_SERVICE", "UPDATE_SERVICE"]
    }
  ],
  "profileStatus": "active",
  "language": "en",
  "assignments": {
    "service": {
      "full": false,
      "include": [
        {
          "service": "service-id-123",
          "serviceId": "service-123"
        }
      ]
    }
  },
  "referal": {
    "code": "REF123",
    "source": "website"
  },
  "createdAt": "2023-06-18T10:30:00.000Z",
  "updatedAt": "2023-06-18T15:45:00.000Z"
}
```

***

### 3. Create New Member

**Endpoint:** `POST /member`

**Description:** Creates a new team member and sends invitation.

**Request Body:**

```typescript
interface MemberDto {
  firstName?: string;
  lastName?: string;
  email: string;          // Required - unique within business
  phone?: string;
  role?: RoleEnum;        // Default: SPECIALIST
  profileStatus?: MemberProfileStatusEnum; // Default: active
  assignments?: AssignmentsDto;
  language?: LanguageCodeEnum; // Default: en
  referal?: ReferalDto;
}
```

**Response:**

```typescript
MemberDto // Created member details
```

**Validation Rules:**

* `email`: Required, valid email format, unique within business
* `firstName` or `lastName`: At least one is recommended
* `role`: Must be valid role enum value
* `phone`: Valid phone format if provided

**Example Request:**

```bash
POST /api/v1/member
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
Content-Type: application/json

{
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com",
  "phone": "+1987654321",
  "role": "SPECIALIST",
  "language": "en"
}
```

**Example Response:**

```json
{
  "_id": "648f8f2e1234567890abcdef",
  "object": "MemberDto",
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com",
  "phone": "+1987654321",
  "role": "SPECIALIST",
  "profileStatus": "active",
  "language": "en",
  "assignments": {
    "service": {
      "full": false,
      "include": []
    }
  },
  "createdAt": "2023-06-18T10:30:00.000Z",
  "updatedAt": "2023-06-18T10:30:00.000Z"
}
```

***

### 4. Update Member

**Endpoint:** `PUT /member/:memberId`

**Description:** Updates an existing team member's information.

**Path Parameters:**

* `memberId` (required): Member ID to update

**Request Body:**

```typescript
interface MemberDto {
  firstName?: string;
  lastName?: string;
  email?: string;         // Must be unique if changed
  phone?: string;
  role?: RoleEnum;
  profileStatus?: MemberProfileStatusEnum;
  language?: LanguageCodeEnum;
  referal?: ReferalDto;
}
```

**Response:**

```typescript
MemberDto // Updated member details
```

**Business Rules:**

* Email must remain unique within business if changed
* Role changes require appropriate permissions
* Cannot update email to existing member's email
* Profile status changes affect member access

**Example Request:**

```bash
PUT /api/v1/member/648f8f2e1234567890abcdef
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
Content-Type: application/json

{
  "firstName": "Jane",
  "lastName": "Doe-Smith",
  "phone": "+1555123456",
  "profileStatus": "active"
}
```

**Example Response:**

```json
{
  "_id": "648f8f2e1234567890abcdef",
  "object": "MemberDto",
  "firstName": "Jane",
  "lastName": "Doe-Smith",
  "email": "jane.smith@example.com",
  "phone": "+1555123456",
  "role": "SPECIALIST",
  "profileStatus": "active",
  "language": "en",
  "updatedAt": "2023-06-18T16:20:00.000Z"
}
```

***

### 5. Update Member Service Assignments

**Endpoint:** `PATCH /member/:memberId/assignments`

**Description:** Updates service assignments for a team member.

**Path Parameters:**

* `memberId` (required): Member ID to update assignments

**Request Body:**

```typescript
interface AssignmentsDto {
  service: {
    full: boolean;        // If true, member can handle all services
    include?: AssignedServiceDto[]; // Specific services if full=false
  }
}

interface AssignedServiceDto {
  service?: string;       // Service ObjectId reference
  serviceId?: string;     // Service identifier
}
```

**Response:**

```typescript
MemberDto // Updated member with new assignments
```

**Assignment Rules:**

* `full: true`: Member can provide all business services
* `full: false`: Member can only provide services in `include` array
* Empty `include` array with `full: false` means no service assignments
* Service references must exist and belong to the business

**Example Request:**

```bash
PATCH /api/v1/member/648f8f2e1234567890abcdef/assignments
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
Content-Type: application/json

{
  "service": {
    "full": false,
    "include": [
      {
        "service": "648f8f2e1234567890service1",
        "serviceId": "haircut-basic"
      },
      {
        "service": "648f8f2e1234567890service2",
        "serviceId": "haircut-premium"
      }
    ]
  }
}
```

**Example Response:**

```json
{
  "_id": "648f8f2e1234567890abcdef",
  "object": "MemberDto",
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com",
  "role": "SPECIALIST",
  "assignments": {
    "service": {
      "full": false,
      "include": [
        {
          "service": "648f8f2e1234567890service1",
          "serviceId": "haircut-basic"
        },
        {
          "service": "648f8f2e1234567890service2",
          "serviceId": "haircut-premium"
        }
      ]
    }
  },
  "updatedAt": "2023-06-18T16:45:00.000Z"
}
```

***

### 6. Delete Member

**Endpoint:** `DELETE /member/:memberId`

**Description:** Soft deletes a team member (marks as deleted while preserving data).

**Path Parameters:**

* `memberId` (required): Member ID to delete

**Response:**

```typescript
void // No content (204 status)
```

**Business Rules:**

* Performs soft delete (preserves historical data)
* Member cannot delete themselves
* Requires DELETE\_MEMBER permission
* Checks for active orders before deletion
* Maintains audit trail of deletion

**Deletion Validations:**

1. **Self-deletion protection**: Members cannot delete themselves
2. **Active orders check**: Cannot delete members with pending/active orders
3. **Permission validation**: Requires appropriate deletion permissions
4. **Role validation**: May have restrictions based on member role

**Example Request:**

```bash
DELETE /api/v1/member/648f8f2e1234567890abcdef
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
```

**Example Response:**

```
HTTP 204 No Content
```

***

## Member Media Management

### 7. Upload Member Avatar

**Endpoint:** `POST /member-media/:memberId/avatar`

**Description:** Uploads or updates a member's profile avatar image.

**Path Parameters:**

* `memberId` (required): Member ID for avatar upload

**Request Body:**

```typescript
FormData {
  file: File; // Image file (JPG, PNG, WebP)
}
```

**Response:**

```typescript
{
  avatarId: string;     // Media ID of uploaded avatar
  avatarUrl: string;    // Public URL of avatar image
}
```

**File Requirements:**

* **Formats**: JPG, JPEG, PNG, WebP
* **Size**: Maximum 5MB
* **Dimensions**: Recommended 400x400px (will be auto-resized)

**Example Request:**

```bash
POST /api/v1/member-media/648f8f2e1234567890abcdef/avatar
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
Content-Type: multipart/form-data

FormData:
  file: [image file]
```

**Example Response:**

```json
{
  "avatarId": "648f8f2e1234567890media123",
  "avatarUrl": "https://storage.example.com/avatars/member-avatar-123.jpg"
}
```

***

### 8. Delete Member Avatar

**Endpoint:** `DELETE /member-media/:memberId/avatar`

**Description:** Removes a member's profile avatar image.

**Path Parameters:**

* `memberId` (required): Member ID for avatar deletion

**Response:**

```typescript
void // No content (204 status)
```

**Example Request:**

```bash
DELETE /api/v1/member-media/648f8f2e1234567890abcdef/avatar
Authorization: Bearer <firebase-jwt>
x-business-tenant-id: <tenant-id>
```

**Example Response:**

```
HTTP 204 No Content
```

***

## Data Transfer Objects

### MemberDto

```typescript
interface MemberDto {
  _id?: string;
  object?: 'MemberDto';
  firstName?: string;
  lastName?: string;
  email: string;                    // Required, unique within business
  phone?: string;
  avatar?: MediaDto;
  role?: RoleEnum;                  // Default: SPECIALIST
  roles?: RoleDto[];                // Advanced role system
  profileStatus?: MemberProfileStatusEnum; // Default: active
  assignments?: AssignmentsDto;
  language?: LanguageCodeEnum;      // Default: en
  referal?: ReferalDto;
  createdAt?: string;               // ISO date string
  updatedAt?: string;               // ISO date string
}
```

### AssignmentsDto

```typescript
interface AssignmentsDto {
  service: {
    full: boolean;                  // Can handle all services
    include?: AssignedServiceDto[]; // Specific service assignments
  }
}

interface AssignedServiceDto {
  service?: string;                 // Service ObjectId reference
  serviceId?: string;               // Service identifier
}
```

### MemberPaginationDto

```typescript
interface MemberPaginationDto {
  page?: number;                    // Page number (default: 1)
  pageSize?: number;                // Items per page (default: 10)
  search?: string;                  // Search term
  role?: RoleEnum;                  // Role filter
  profileStatus?: MemberProfileStatusEnum; // Status filter
  sortBy?: string;                  // Sort field
  sortDirection?: 'asc' | 'desc';   // Sort direction
}
```

## Enumerations

### RoleEnum

```typescript
enum RoleEnum {
  ADMIN = 'ADMIN',                  // Full business administration
  SPECIALIST = 'SPECIALIST',        // Service provider
  RECEPTION = 'RECEPTION'           // Front desk operations
}
```

### MemberProfileStatusEnum

```typescript
enum MemberProfileStatusEnum {
  active = 'active',                // Active and available
  inactive = 'inactive',            // Temporarily inactive
  pending = 'pending'               // Awaiting activation
}
```

### LanguageCodeEnum

```typescript
enum LanguageCodeEnum {
  en = 'en',                        // English
  es = 'es',                        // Spanish
  fr = 'fr',                        // French
  de = 'de',                        // German
  it = 'it',                        // Italian
  pt = 'pt',                        // Portuguese
  // Additional languages supported
}
```

## Permission Requirements

All member management endpoints require appropriate permissions:

### Required Permissions

| Operation          | Permission        | Description                |
| ------------------ | ----------------- | -------------------------- |
| Get Members        | `READ_MEMBER`     | View member information    |
| Create Member      | `CREATE_MEMBER`   | Add new team members       |
| Update Member      | `EDIT_MEMBER`     | Modify member details      |
| Delete Member      | `DELETE_MEMBER`   | Remove team members        |
| Manage Assignments | `ASSIGN_SERVICES` | Update service assignments |
| Upload Avatar      | `EDIT_MEMBER`     | Manage member media        |

### Permission Scopes

* **OWN**: Can only access own member data
* **ANY**: Can access all members within the business
* **ADMIN**: Full administrative access

## Error Responses

### Standard Error Format

```typescript
interface ApiError {
  statusCode: number;
  message: string;
  error: string;
  timestamp: string;
  path: string;
}
```

### Common Error Responses

#### 400 Bad Request

```json
{
  "statusCode": 400,
  "message": "Validation failed: Email is required",
  "error": "Bad Request",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member"
}
```

#### 401 Unauthorized

```json
{
  "statusCode": 401,
  "message": "Invalid or missing authentication token",
  "error": "Unauthorized",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member"
}
```

#### 403 Forbidden

```json
{
  "statusCode": 403,
  "message": "Insufficient permissions for this operation",
  "error": "Forbidden",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member"
}
```

#### 404 Not Found

```json
{
  "statusCode": 404,
  "message": "Member not found",
  "error": "Not Found",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member/invalid-id"
}
```

#### 409 Conflict

```json
{
  "statusCode": 409,
  "message": "Email already exists in this business",
  "error": "Conflict",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member"
}
```

#### 422 Unprocessable Entity

```json
{
  "statusCode": 422,
  "message": "Cannot delete member with active orders",
  "error": "Unprocessable Entity",
  "timestamp": "2023-06-18T10:30:00.000Z",
  "path": "/api/v1/member/648f8f2e1234567890abcdef"
}
```

### Member-Specific Errors

#### Member Not Found

```json
{
  "statusCode": 404,
  "message": "Member not found: 648f8f2e1234567890abcdef",
  "error": "MemberNotFoundException"
}
```

#### Email Already Exists

```json
{
  "statusCode": 409,
  "message": "Member with email 'john@example.com' already exists",
  "error": "MemberEmailExistsException"
}
```

#### Cannot Delete Self

```json
{
  "statusCode": 422,
  "message": "Members cannot delete themselves",
  "error": "MemberCannotDeleteItselfException"
}
```

#### Has Active Orders

```json
{
  "statusCode": 422,
  "message": "Cannot delete member with active orders or appointments",
  "error": "MemberHasActiveEventsException"
}
```

#### Tariff Plan Limit Reached

```json
{
  "statusCode": 422,
  "message": "Maximum number of team members reached for current plan",
  "error": "TenantTariffPlanMaxMembersReachedException"
}
```

## Rate Limiting

API endpoints are rate-limited to prevent abuse:

* **General endpoints**: 100 requests per minute per IP
* **File upload endpoints**: 10 requests per minute per user
* **Bulk operations**: 5 requests per minute per user

Rate limit headers are included in responses:

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1623456789
```

## Caching

Member data is cached for performance optimization:

* **Member details**: Cached for 5 minutes
* **Member lists**: Cached for 1 minute
* **Search results**: Cached for 3 minutes

Cache headers indicate freshness:

```
Cache-Control: public, max-age=300
ETag: "member-12345-v2"
Last-Modified: Wed, 18 Jun 2023 10:30:00 GMT
```

## API Versioning

The API uses URL-based versioning:

* Current version: `/api/v1/`
* Version format: `v{major}`
* Backward compatibility maintained within major versions

## Integration Examples

### JavaScript/TypeScript Client

```typescript
class MemberApiClient {
  constructor(private baseUrl: string, private token: string, private tenantId: string) {}

  async getMembers(params?: MemberPaginationDto): Promise<PaginationResponseDto<MemberDto>> {
    const queryString = new URLSearchParams(params as any).toString();
    const response = await fetch(`${this.baseUrl}/api/v1/member/paged?${queryString}`, {
      headers: {
        'Authorization': `Bearer ${this.token}`,
        'x-business-tenant-id': this.tenantId
      }
    });
    return response.json();
  }

  async createMember(member: Partial<MemberDto>): Promise<MemberDto> {
    const response = await fetch(`${this.baseUrl}/api/v1/member`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.token}`,
        'x-business-tenant-id': this.tenantId,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(member)
    });
    return response.json();
  }
}
```

### cURL Examples

```bash
# Get paginated members
curl -X GET \
  "${API_BASE_URL}/api/v1/member/paged?page=1&pageSize=10" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-business-tenant-id: ${TENANT_ID}"

# Create new member
curl -X POST \
  "${API_BASE_URL}/api/v1/member" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-business-tenant-id: ${TENANT_ID}" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "role": "SPECIALIST"
  }'

# Update member assignments
curl -X PATCH \
  "${API_BASE_URL}/api/v1/member/${MEMBER_ID}/assignments" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-business-tenant-id: ${TENANT_ID}" \
  -H "Content-Type: application/json" \
  -d '{
    "service": {
      "full": false,
      "include": [
        {"serviceId": "haircut-basic"},
        {"serviceId": "haircut-premium"}
      ]
    }
  }'
```

## Best Practices

### API Usage Guidelines

1. **Pagination**: Always use pagination for member lists to avoid performance issues
2. **Caching**: Implement client-side caching with appropriate TTL
3. **Error Handling**: Handle all error responses gracefully
4. **Rate Limiting**: Respect rate limits and implement exponential backoff
5. **Validation**: Validate data on client side before API calls

### Security Considerations

1. **Token Management**: Secure storage and rotation of authentication tokens
2. **HTTPS Only**: Always use HTTPS in production environments
3. **Input Validation**: Validate and sanitize all inputs
4. **Tenant Isolation**: Always include tenant ID header
5. **Permission Checking**: Verify user permissions before UI actions

### Performance Optimization

1. **Selective Loading**: Only request needed fields using field selection
2. **Batch Operations**: Group related API calls when possible
3. **Lazy Loading**: Load member details on demand
4. **Image Optimization**: Compress avatar images before upload
5. **Connection Pooling**: Reuse HTTP connections for multiple requests

***

For additional information about member management workflows and business logic, see the [Use Case Documentation](/services/member-management/usecase.md) and [Interface Documentation](/services/member-management/interface.md).
