> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipeshub.com/llms.txt
> Use this file to discover all available pages before exploring further.

# User management

# User Management API

The User Management API provides comprehensive functionality for managing users, organizations, user groups, and teams within your application. This service handles organizational structure, user profiles, permissions, and team collaboration features.

## Base URL

All endpoints are prefixed with `/api/v1`

## Authentication

Most endpoints require authentication via Bearer token:

```http theme={null}
Authorization: Bearer YOUR_TOKEN
```

**Scoped Tokens:** Internal endpoints use scoped token authentication for service-to-service communication:

* `USER_LOOKUP` - For internal user lookups and email existence checks
* `FETCH_CONFIG` - For configuration updates

**Admin Requirements:** Many endpoints require admin privileges, enforced through `userAdminCheck` middleware that validates user group membership.

## Architecture Overview

The User Management Service is built on Node.js with MongoDB for data persistence. It uses Inversify for dependency injection and integrates with several external services:

* **Authentication Service** - Validates user credentials and authentication methods
* **Mail Service** - Sends invitations and notifications via SMTP
* **Configuration Manager** - Manages application settings and SMTP configuration
* **Event Service** - Publishes entity lifecycle events via Kafka
* **AI Connector Backend** - Handles teams and graph-based user operations
* **Prometheus Service** - Records metrics and activities

## Data Models

### Organizations

Top-level entities containing users and configuration:

* Organization metadata and settings
* Account types (individual/business)
* Onboarding status tracking
* Logo management with automatic compression

### Users

Individual accounts within organizations:

* Profile information and contact details
* Authentication status and login history
* Organization membership and roles
* Display picture management with automatic compression

### User Groups

Role-based access control within organizations:

* Predefined types: admin, standard, everyone, custom
* User membership management
* Permission inheritance
* System-managed groups cannot be deleted

### Teams

Collaborative workspaces managed through connector backend:

* Team metadata and descriptions
* User membership with permissions
* External system integration via AI connector service

## API Endpoints

<AccordionGroup>
  <Accordion title="Organization Management">
    The Organization Management API handles organization-level settings, branding, and configuration.

    <AccordionGroup>
      <Accordion title="GET /org/exists - Check Organization Existence">
        Checks if any organization exists in the system.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/org/exists`

            **Authentication:** None required

            **Middleware Chain:**

            * `attachContainerMiddleware` - Provides Inversify container access

            **Description:** Used during initial setup to determine if the system has been initialized with an organization.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "exists": true
            }
            ```

            **Response Fields:**

            * `exists` (boolean) - Whether any organization exists in the system
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /org - Create Organization">
        Creates a new organization with an admin user and sets up the entire system.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/org`

            **Authentication:** None required (initial setup only)

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `ValidationMiddleware.validate(OrgCreationValidationSchema)`

            **Request Body Parameters:**

            | Parameter        | Type    | Required | Description                                      |
            | ---------------- | ------- | -------- | ------------------------------------------------ |
            | accountType      | string  | Yes      | 'individual' or 'business'                       |
            | contactEmail     | string  | Yes      | Primary contact email (becomes admin email)      |
            | registeredName   | string  | Yes\*    | Official name (\*required for business accounts) |
            | shortName        | string  | No       | Display name for the organization                |
            | adminFullName    | string  | Yes      | Full name of the admin user (min 1 char)         |
            | password         | string  | Yes      | Admin password (min 8 chars with complexity)     |
            | sendEmail        | boolean | No       | Whether to send welcome email                    |
            | phoneNumber      | string  | No       | Organization phone number                        |
            | permanentAddress | object  | No       | Organization address details                     |

            **Validation Rules:**

            * Business accounts must provide `registeredName`
            * Password must contain: uppercase, lowercase, number, special character
            * Email domain becomes organization domain
            * Only one organization can exist per system

            ```json theme={null}
            {
              "accountType": "business",
              "contactEmail": "admin@example.com",
              "registeredName": "Example Corporation",
              "shortName": "ExampleCorp",
              "adminFullName": "John Administrator",
              "password": "SecurePass123!",
              "sendEmail": true,
              "phoneNumber": "+1-555-123-4567",
              "permanentAddress": {
                "addressLine1": "123 Business Ave",
                "city": "Tech City",
                "state": "Innovation State",
                "country": "United States",
                "postCode": "12345"
              }
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c85",
              "slug": "org-1001",
              "registeredName": "Example Corporation",
              "shortName": "ExampleCorp",
              "domain": "example.com",
              "contactEmail": "admin@example.com",
              "accountType": "business",
              "phoneNumber": "+1-555-123-4567",
              "permanentAddress": {
                "addressLine1": "123 Business Ave",
                "city": "Tech City",
                "state": "Innovation State",
                "country": "United States",
                "postCode": "12345"
              },
              "onBoardingStatus": "notConfigured",
              "isDeleted": false,
              "createdAt": "2025-04-27T12:00:00.000Z",
              "updatedAt": "2025-04-27T12:00:00.000Z"
            }
            ```

            **Side Effects:**

            * Creates admin user with hashed password credentials
            * Creates default user groups: admin, everyone, standard
            * Sets up organization authentication configuration
            * Uses MongoDB transactions when replica sets available
            * Publishes `OrgCreatedEvent` and `NewUserEvent` via Kafka
            * Records activity in Prometheus metrics
            * Sends welcome email if `sendEmail: true`
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /org - Get Organization">
        Retrieves the authenticated user's organization details.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/org`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Access Control:** Any authenticated user within the organization
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c85",
              "slug": "org-1001",
              "registeredName": "Example Corporation",
              "shortName": "ExampleCorp",
              "domain": "example.com",
              "contactEmail": "admin@example.com",
              "accountType": "business",
              "phoneNumber": "+1-555-123-4567",
              "permanentAddress": {
                "addressLine1": "123 Business Ave",
                "city": "Tech City",
                "state": "Innovation State",
                "country": "United States",
                "postCode": "12345"
              },
              "onBoardingStatus": "configured",
              "isDeleted": false,
              "createdAt": "2025-04-27T12:00:00.000Z",
              "updatedAt": "2025-04-27T14:30:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /org - Update Organization">
        Updates organization details.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/org`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `userAdminCheck` - Admin access required

            **Request Body Parameters:**

            | Parameter        | Type   | Required | Description              |
            | ---------------- | ------ | -------- | ------------------------ |
            | contactEmail     | string | No       | Primary contact email    |
            | registeredName   | string | No       | Official registered name |
            | shortName        | string | No       | Display name             |
            | permanentAddress | object | No       | Address details          |

            ```json theme={null}
            {
              "contactEmail": "new-admin@example.com",
              "shortName": "NewExampleCorp",
              "permanentAddress": {
                "addressLine1": "456 New Street",
                "city": "Updated City",
                "state": "New State",
                "country": "United States",
                "postCode": "67890"
              }
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Organization updated successfully",
              "data": {
                "_id": "60d21b4667d0d8992e610c85",
                "contactEmail": "new-admin@example.com",
                "shortName": "NewExampleCorp",
                "permanentAddress": {
                  "addressLine1": "456 New Street",
                  "city": "Updated City",
                  "state": "New State",
                  "country": "United States",
                  "postCode": "67890"
                },
                "updatedAt": "2025-04-27T14:30:00.000Z"
              }
            }
            ```

            **Side Effects:**

            * Publishes `OrgUpdatedEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /org - Delete Organization">
        Soft-deletes the organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/org`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `userAdminCheck` - Admin access required
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Organization marked as deleted successfully",
              "data": {
                "_id": "60d21b4667d0d8992e610c85",
                "isDeleted": true,
                "deletedByUser": "user456",
                "updatedAt": "2025-04-27T15:00:00.000Z"
              }
            }
            ```

            **Side Effects:**

            * Publishes `OrgDeletedEvent` via Kafka
            * Organization becomes inaccessible
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /org/logo - Upload Organization Logo">
        Uploads and automatically compresses an organization logo.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/org/logo`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`
            * `Content-Type: multipart/form-data`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `FileProcessorFactory.createBufferUploadProcessor()` with:
              * Field name: 'file'
              * Allowed types: PNG, JPEG, JPG, WebP, GIF
              * Max files: 1
              * Max size: 1MB
              * Processing type: BUFFER
              * Strict upload: true
            * `metricsMiddleware`
            * `userAdminCheck` - Admin access required

            **Form Data:**

            * `file`: Image file

            **File Processing:**

            * Automatically compressed using Sharp library
            * Converted to JPEG format
            * Quality reduced until under 100KB (minimum quality: 10%)
            * Stored as base64 string in database
          </Tab>

          <Tab title="Response">
            **Status:** `201 Created`

            **Content-Type:** `image/jpeg`

            Returns the compressed image data directly.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /org/logo - Remove Organization Logo">
        Removes the organization's logo.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/org/logo`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `userAdminCheck` - Admin access required
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "orgId": "60d21b4667d0d8992e610c85",
              "logo": null,
              "logoUrl": null,
              "mimeType": null
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /org/logo - Get Organization Logo">
        Retrieves the organization's logo.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/org/logo`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `metricsMiddleware`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK` (if logo exists)
            **Status:** `204 No Content` (if no logo)

            **Content-Type:** `image/jpeg` (when logo exists)

            Returns the logo image data directly.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /org/onboarding-status - Get Onboarding Status">
        Retrieves the organization's onboarding status.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/org/onboarding-status`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "status": "configured"
            }
            ```

            **Possible Status Values:**

            * `notConfigured` - Initial state after organization creation
            * `configured` - Onboarding completed
            * `skipped` - User chose to skip onboarding
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /org/onboarding-status - Update Onboarding Status">
        Updates the organization's onboarding status.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/org/onboarding-status`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `attachContainerMiddleware`
            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required
            * `ValidationMiddleware.validate(OnboardingStatusUpdateValidationSchema)`

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description                                 |
            | --------- | ------ | -------- | ------------------------------------------- |
            | status    | string | Yes      | 'configured', 'notConfigured', or 'skipped' |

            ```json theme={null}
            {
              "status": "configured"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Onboarding status updated successfully",
              "status": "configured"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /org/health - Health Check">
        Health check endpoint for the organization service.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/org/health`

            **Authentication:** None required

            **Middleware Chain:**

            * `attachContainerMiddleware`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "status": "healthy",
              "timestamp": "2025-04-27T12:00:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>
    </AccordionGroup>
  </Accordion>

  <Accordion title="User Management">
    The User Management API provides comprehensive user management functionality including profile management, invitations, and access control.

    <AccordionGroup>
      <Accordion title="GET /users - Get All Users">
        Retrieves all active users in the authenticated user's organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Access Control:** Any authenticated user
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c86",
                "slug": "user-1002", 
                "fullName": "John Doe",
                "firstName": "John",
                "lastName": "Doe",
                "email": "john.doe@example.com",
                "mobile": "+12345678901",
                "hasLoggedIn": true,
                "designation": "Manager",
                "address": {
                  "addressLine1": "123 Main St",
                  "city": "San Francisco",
                  "state": "CA",
                  "postCode": "94105",
                  "country": "US"
                },
                "orgId": "60d21b4667d0d8992e610c85",
                "isDeleted": false,
                "createdAt": "2025-04-27T12:00:00.000Z",
                "updatedAt": "2025-04-27T12:05:00.000Z"
              }
            ]
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/fetch/with-groups - Get Users With Groups">
        Retrieves all users with their group memberships using MongoDB aggregation.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/fetch/with-groups`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`

            **Description:** Uses MongoDB aggregation pipeline to join users with their group memberships efficiently.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c86",
                "userId": "user-1002",
                "orgId": "60d21b4667d0d8992e610c85",
                "fullName": "John Doe",
                "email": "john.doe@example.com",
                "hasLoggedIn": true,
                "groups": [
                  {
                    "name": "admin",
                    "type": "admin"
                  },
                  {
                    "name": "everyone",
                    "type": "everyone"
                  }
                ]
              }
            ]
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/:id - Get User By ID">
        Retrieves a specific user by their ID.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/:id`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `ValidationMiddleware.validate(UserIdValidationSchema)`
            * `metricsMiddleware`
            * `userExists` - Validates user exists and is not deleted

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId matching `/^[a-fA-F0-9]{24}$/`)
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c86",
              "slug": "user-1002",
              "fullName": "John Doe",
              "firstName": "John",
              "lastName": "Doe",
              "middleName": "William",
              "email": "john.doe@example.com",
              "mobile": "+12345678901",
              "hasLoggedIn": true,
              "designation": "Manager",
              "address": {
                "addressLine1": "123 Main St",
                "city": "San Francisco",
                "state": "CA",
                "postCode": "94105",
                "country": "US"
              },
              "orgId": "60d21b4667d0d8992e610c85",
              "isDeleted": false,
              "createdAt": "2025-04-27T12:00:00.000Z",
              "updatedAt": "2025-04-27T12:05:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /users/by-ids - Get Users By IDs">
        Retrieves multiple users by their IDs.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/users/by-ids`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `ValidationMiddleware.validate(MultipleUserValidationSchema)`
            * `metricsMiddleware`

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                                       |
            | --------- | --------- | -------- | ------------------------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs (MongoDB ObjectIds, min 1 item) |

            **Validation:**

            * Each userIds element must match `/^[a-fA-F0-9]{24}$/`
            * Array must contain at least one userId

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c86",
                "fullName": "John Doe",
                "email": "john.doe@example.com",
                "orgId": "60d21b4667d0d8992e610c85"
              },
              {
                "_id": "60d21b4667d0d8992e610c87",
                "fullName": "Jane Smith",
                "email": "jane.smith@example.com",
                "orgId": "60d21b4667d0d8992e610c85"
              }
            ]
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/email/exists - Check User Exists By Email">
        Checks if users exist with the given email address. Internal service endpoint.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/email/exists`

            **Headers:**

            * `Authorization: Bearer SCOPED_TOKEN` (USER\_LOOKUP scope required)

            **Middleware Chain:**

            * `metricsMiddleware`
            * `authMiddleware.scopedTokenValidator(TokenScopes.USER_LOOKUP)`
            * `ValidationMiddleware.validate(emailIdValidationSchema)`

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description         |
            | --------- | ------ | -------- | ------------------- |
            | email     | string | Yes      | Valid email address |

            **Note:** This is a GET request that expects a request body, which is unusual but documented as implemented.

            ```json theme={null}
            {
              "email": "john.doe@example.com"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c86",
                "email": "john.doe@example.com",
                "fullName": "John Doe",
                "isDeleted": false
              }
            ]
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/internal/:id - Internal Get User">
        Internal service endpoint for user retrieval with scoped authentication.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/internal/:id`

            **Headers:**

            * `Authorization: Bearer SCOPED_TOKEN` (USER\_LOOKUP scope required)

            **Middleware Chain:**

            * `authMiddleware.scopedTokenValidator(TokenScopes.USER_LOOKUP)`
            * `ValidationMiddleware.validate(UserIdValidationSchema)`
            * `metricsMiddleware`

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Description:** Used for service-to-service user lookups without full authentication. Directly queries database in route handler.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c86",
              "fullName": "John Doe",
              "email": "john.doe@example.com",
              "orgId": "60d21b4667d0d8992e610c85",
              "hasLoggedIn": true,
              "isDeleted": false
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /users - Create User">
        Creates a new user in the organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(createUserValidationSchema)`
            * `userAdminCheck` - Admin access required

            **Request Body Parameters:**

            | Parameter   | Type   | Required | Description                              |
            | ----------- | ------ | -------- | ---------------------------------------- |
            | fullName    | string | Yes      | Full name (min 1 character)              |
            | email       | string | Yes      | Valid email address                      |
            | mobile      | string | No       | Mobile number (10-15 digits, optional +) |
            | designation | string | No       | Job title or role                        |

            **Validation Rules:**

            * Mobile must match `/^\+?[0-9]{10,15}$/` if provided
            * Email must be valid email format

            ```json theme={null}
            {
              "fullName": "Alice Johnson",
              "email": "alice.johnson@example.com",
              "mobile": "+12345678902",
              "designation": "Product Manager"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `201 Created`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "slug": "user-1003",
              "fullName": "Alice Johnson",
              "email": "alice.johnson@example.com",
              "mobile": "+12345678902",
              "designation": "Product Manager",
              "orgId": "60d21b4667d0d8992e610c85",
              "hasLoggedIn": false,
              "isDeleted": false,
              "createdAt": "2025-04-27T14:30:00.000Z",
              "updatedAt": "2025-04-27T14:30:00.000Z"
            }
            ```

            **Side Effects:**

            * User automatically added to "everyone" group
            * Publishes `NewUserEvent` via Kafka
            * Auto-generates unique slug
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /users/:id/fullname - Update Full Name">
        Updates a user's full name only.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/users/:id/fullname`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserFullNameValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description                     |
            | --------- | ------ | -------- | ------------------------------- |
            | fullName  | string | Yes      | Full name (minimum 1 character) |

            ```json theme={null}
            {
              "fullName": "Alice Marie Johnson"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "fullName": "Alice Marie Johnson",
              "email": "alice.johnson@example.com",
              "updatedAt": "2025-04-27T14:50:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /users/:id/firstName - Update First Name">
        Updates a user's first name only.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/users/:id/firstName`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserFirstNameValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description |
            | --------- | ------ | -------- | ----------- |
            | firstName | string | Yes      | First name  |

            ```json theme={null}
            {
              "firstName": "Alexandra"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "firstName": "Alexandra",
              "fullName": "Alice Marie Johnson",
              "updatedAt": "2025-04-27T14:52:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /users/:id/lastName - Update Last Name">
        Updates a user's last name only.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/users/:id/lastName`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserLastNameValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description |
            | --------- | ------ | -------- | ----------- |
            | lastName  | string | Yes      | Last name   |

            ```json theme={null}
            {
              "lastName": "Smith-Johnson"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "lastName": "Smith-Johnson",
              "fullName": "Alice Marie Johnson",
              "updatedAt": "2025-04-27T14:54:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /users/dp - Upload User Display Picture">
        Uploads and compresses a profile picture for the authenticated user.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/users/dp`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`
            * `Content-Type: multipart/form-data`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `FileProcessorFactory.createBufferUploadProcessor()` (spread as array) with:
              * Field name: 'file'
              * Allowed types: PNG, JPEG, JPG, WebP, GIF
              * Max files: 1
              * Max size: 1MB
              * Processing type: BUFFER
              * Strict upload: true
            * `metricsMiddleware`

            **Form Data:**

            * `file`: Image file

            **Image Processing:**

            * Compressed using Sharp library with dynamic quality adjustment
            * Converted to JPEG format
            * Quality reduced from 100% to minimum 10% until under 100KB
            * Stored as base64 with MIME type
            * Uses upsert operation for user display picture record
          </Tab>

          <Tab title="Response">
            **Status:** `201 Created`

            **Content-Type:** `image/jpeg`

            Returns the compressed image data directly.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /users/dp - Remove User Display Picture">
        Removes the authenticated user's profile picture.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/users/dp`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Description:** Sets `pic` and `mimeType` fields to null but preserves the record.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "userId": "60d21b4667d0d8992e610c86",
              "orgId": "60d21b4667d0d8992e610c85",
              "pic": null,
              "mimeType": null
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/dp - Get User Display Picture">
        Retrieves the authenticated user's profile picture.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/dp`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK` (if picture exists)

            **Content-Type:** Image MIME type from database

            Returns the profile picture image data directly.

            **Status:** `200 OK` (if no picture)

            ```json theme={null}
            {
              "errorMessage": "User pic not found"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /users/:id/designation - Update Designation">
        Updates a user's job designation.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/users/:id/designation`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserDesignationValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter   | Type   | Required | Description       |
            | ----------- | ------ | -------- | ----------------- |
            | designation | string | Yes      | Job title or role |

            ```json theme={null}
            {
              "designation": "VP of Product"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "designation": "VP of Product",
              "fullName": "Alice Marie Johnson",
              "updatedAt": "2025-04-27T14:56:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PATCH /users/:id/email - Update Email">
        Updates a user's email address.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PATCH /api/v1/users/:id/email`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserEmailValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description         |
            | --------- | ------ | -------- | ------------------- |
            | email     | string | Yes      | Valid email address |

            ```json theme={null}
            {
              "email": "alice.smith-johnson@example.com"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "email": "alice.smith-johnson@example.com",
              "fullName": "Alice Marie Johnson",
              "updatedAt": "2025-04-27T14:58:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /users/:id - Update User">
        Updates comprehensive user information.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/users/:id`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateUserValidationSchema)`
            * `userAdminOrSelfCheck` - Admin or self access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter   | Type    | Required | Description         |
            | ----------- | ------- | -------- | ------------------- |
            | fullName    | string  | No       | Full name           |
            | email       | string  | Yes      | Valid email address |
            | mobile      | string  | No       | Mobile number       |
            | designation | string  | No       | Job title or role   |
            | firstName   | string  | No       | First name          |
            | lastName    | string  | No       | Last name           |
            | middleName  | string  | No       | Middle name         |
            | address     | object  | No       | Address details     |
            | hasLoggedIn | boolean | No       | Login status        |

            **Restricted Fields:** `orgId`, `_id`, `slug` are excluded from updates.

            ```json theme={null}
            {
              "fullName": "Alice Johnson",
              "email": "alice.johnson@example.com",
              "designation": "Senior Product Manager",
              "firstName": "Alice",
              "lastName": "Johnson",
              "address": {
                "addressLine1": "456 Oak Street",
                "city": "New York",
                "state": "NY",
                "postCode": "10001",
                "country": "US"
              }
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c88",
              "fullName": "Alice Johnson",
              "firstName": "Alice",
              "lastName": "Johnson",
              "email": "alice.johnson@example.com",
              "designation": "Senior Product Manager",
              "address": {
                "addressLine1": "456 Oak Street",
                "city": "New York",
                "state": "NY",
                "postCode": "10001",
                "country": "US"
              },
              "orgId": "60d21b4667d0d8992e610c85",
              "updatedAt": "2025-04-27T14:45:00.000Z"
            }
            ```

            **Side Effects:**

            * Publishes `UpdateUserEvent` via Kafka with conditional fields
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /users/:id - Delete User">
        Soft-deletes a user from the organization with comprehensive cleanup.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/users/:id`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(UserIdValidationSchema)`
            * `userAdminCheck` - Admin access required
            * `userExists` - Validates user exists

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Restrictions:**

            * Cannot delete admin users (checked via group membership)
            * User must exist and not already be deleted
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "User deleted successfully"
            }
            ```

            **Side Effects:**

            * User removed from all user groups via `$pull` operation
            * User credentials completely cleared (password removed)
            * User marked as deleted and logged out (`hasLoggedIn: false`)
            * `deletedBy` field set to requesting user ID
            * Publishes `DeleteUserEvent` via Kafka
            * User becomes inaccessible for normal operations
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/:id/adminCheck - Check Admin Access">
        Verifies if the authenticated user has admin access.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/:id/adminCheck`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(UserIdValidationSchema)`
            * `userAdminCheck` - Admin access required (the actual check)

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Description:** This endpoint serves as an admin access verification. The middleware validates admin status.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "User has admin access"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /users/bulk/invite - Bulk Invite Users">
        Invites multiple users to the organization with comprehensive email handling.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/users/bulk/invite`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `smtpConfigCheck(config.cmBackend)` - SMTP configuration required
            * `userAdminCheck` - Admin access required
            * `accountTypeCheck` - Business accounts only

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                        |
            | --------- | --------- | -------- | ---------------------------------- |
            | emails    | string\[] | Yes      | Array of email addresses to invite |
            | groupIds  | string\[] | No       | Array of group IDs to add users to |

            **Complex Behavior:**

            * Creates new accounts for emails not in system
            * Restores deleted accounts if they exist with same email and orgId
            * Validates all emails before processing any
            * Adds all users (new and restored) to specified groups and "everyone" group
            * Sends different email templates for new vs restored users
            * Handles both password and non-password authentication methods

            ```json theme={null}
            {
              "emails": [
                "new.user1@example.com",
                "new.user2@example.com",
                "existing.deleted.user@example.com"
              ],
              "groupIds": [
                "60d21b4667d0d8992e610c89",
                "60d21b4667d0d8992e610c90"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Invite sent successfully"
            }
            ```

            **Error Responses:**

            ```json theme={null}
            {
              "errorMessage": "All provided emails already have active accounts"
            }
            ```

            ```json theme={null}
            {
              "message": "Error sending mail invite. Check your SMTP configuration."
            }
            ```

            **Side Effects:**

            * Publishes `NewUserEvent` for each new/restored user
            * Sends invitation emails with password reset tokens or sign-in links
            * Updates group memberships for all affected users
            * Email validation includes regex check: `/^[^\s@]+@[^\s@]+\.[^\s@]+$/`
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /users/:id/resend-invite - Resend User Invite">
        Resends an invitation to a specific user who hasn't logged in yet.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/users/:id/resend-invite`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(UserIdValidationSchema)`
            * `smtpConfigCheck(config.cmBackend)` - SMTP configuration required
            * `userAdminCheck` - Admin access required
            * `accountTypeCheck` - Business accounts only

            **Path Parameters:**

            * `id`: User ID (24-character MongoDB ObjectId)

            **Restrictions:**

            * User must not have logged in yet (`hasLoggedIn: false`)
            * User must exist and not be deleted
            * Adapts email content based on authentication method (password vs non-password)
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Invite sent successfully"
            }
            ```

            **Error Response:**

            ```json theme={null}
            {
              "message": "User has already accepted the invite"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/health - Health Check">
        Health check endpoint for the users service.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/health`

            **Authentication:** None required
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "status": "healthy",
              "timestamp": "2025-04-27T12:00:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /users/updateAppConfig - Update App Configuration">
        Internal endpoint for updating application configuration with service rebinding.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/users/updateAppConfig`

            **Headers:**

            * `Authorization: Bearer SCOPED_TOKEN` (FETCH\_CONFIG scope required)

            **Middleware Chain:**

            * `authMiddleware.scopedTokenValidator(TokenScopes.FETCH_CONFIG)`

            **Description:**

            * Reloads application configuration
            * Rebinds Inversify container services with updated config
            * Recreates MailService, AuthService, and controllers with new configuration
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "User configuration updated successfully",
              "config": {
                "authBackend": "https://auth.example.com",
                "communicationBackend": "https://comms.example.com",
                "frontendUrl": "https://app.example.com"
              }
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/graph/list - List Users (Graph)">
        Retrieves users list through connector backend service with pagination.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/graph/list`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Query Parameters:**

            * `page`: Page number for pagination
            * `limit`: Number of users per page
            * `search`: Search term for filtering users

            **Description:** Proxies request to AI connector backend service for graph-based user operations.

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/user/list`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to get users")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /users/teams/list - Get User Teams (Users Endpoint)">
        Retrieves teams that the authenticated user belongs to via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/users/teams/list`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Query Parameters:**

            * `page`: Page number for pagination
            * `limit`: Number of teams per page
            * `search`: Search term for filtering teams

            **Description:** Proxies request to AI connector backend for team membership data.

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/user/teams`

            **Note:** This is different from the teams endpoint `/user/teams`. This endpoint is managed by the UserController and has different query parameter handling.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to get user teams")`.
          </Tab>
        </Tabs>
      </Accordion>
    </AccordionGroup>
  </Accordion>

  <Accordion title="User Groups Management">
    The User Groups API manages role-based access control within organizations through group membership.

    <AccordionGroup>
      <Accordion title="POST /userGroups - Create User Group">
        Creates a new user group in the organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/userGroups`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `ValidationMiddleware.validate(groupValidationSchema)`
            * `userAdminCheck` - Admin access required

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description                         |
            | --------- | ------ | -------- | ----------------------------------- |
            | name      | string | Yes      | Name of the group (min 1 character) |
            | type      | string | Yes      | Group type: 'standard' or 'custom'  |

            **Restrictions:**

            * Cannot create 'admin' type groups (throws BadRequestError)
            * Group names must be unique within organization
            * Available types from `groupTypes`: \['admin', 'standard', 'everyone', 'custom']
            * 'admin' and 'everyone' are system-managed

            ```json theme={null}
            {
              "name": "Developers",
              "type": "custom"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `201 Created`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c91",
              "slug": "usergroup-1002",
              "name": "Developers",
              "type": "custom",
              "orgId": "60d21b4667d0d8992e610c85",
              "users": [],
              "isDeleted": false,
              "createdAt": "2025-04-27T12:00:00.000Z",
              "updatedAt": "2025-04-27T12:00:00.000Z"
            }
            ```

            **Side Effects:**

            * Auto-generates unique slug using counter
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups - Get All User Groups">
        Retrieves all user groups in the organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required

            **Description:** Returns all non-deleted groups for the organization using lean query for performance.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c90",
                "slug": "usergroup-1000",
                "name": "admin",
                "type": "admin",
                "orgId": "60d21b4667d0d8992e610c85",
                "users": ["60d21b4667d0d8992e610c86"],
                "isDeleted": false,
                "createdAt": "2025-04-27T12:00:00.000Z",
                "updatedAt": "2025-04-27T12:00:00.000Z"
              },
              {
                "_id": "60d21b4667d0d8992e610c91",
                "slug": "usergroup-1002",
                "name": "Developers",
                "type": "custom",
                "orgId": "60d21b4667d0d8992e610c85",
                "users": [],
                "isDeleted": false,
                "createdAt": "2025-04-27T12:00:00.000Z",
                "updatedAt": "2025-04-27T12:00:00.000Z"
              }
            ]
            ```

            **Group Types:**

            * `admin` - Administrative privileges (system-managed)
            * `everyone` - All users automatically added (system-managed)
            * `standard` - Standard user privileges
            * `custom` - Custom groups with specific permissions
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups/:groupId - Get User Group By ID">
        Retrieves a specific user group by its ID.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups/:groupId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `ValidationMiddleware.validate(UserGroupIdValidationSchema)`

            **Path Parameters:**

            * `groupId`: Group ID (24-character MongoDB ObjectId matching `/^[0-9a-fA-F]{24}$/`)

            **Description:** Uses lean query for performance optimization.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c91",
              "slug": "usergroup-1002",
              "name": "Developers",
              "type": "custom",
              "orgId": "60d21b4667d0d8992e610c85",
              "users": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ],
              "isDeleted": false,
              "createdAt": "2025-04-27T12:00:00.000Z",
              "updatedAt": "2025-04-27T12:00:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /userGroups/:groupId - Update User Group">
        Updates a user group's name.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/userGroups/:groupId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required
            * `ValidationMiddleware.validate(UserGroupIdValidationSchema)`

            **Path Parameters:**

            * `groupId`: Group ID (24-character MongoDB ObjectId)

            **Request Body Parameters:**

            | Parameter | Type   | Required | Description            |
            | --------- | ------ | -------- | ---------------------- |
            | name      | string | Yes      | New name for the group |

            **Restrictions:**

            * Cannot update 'admin' or 'everyone' groups (throws ForbiddenError)
            * Only custom and standard groups can be modified

            ```json theme={null}
            {
              "name": "Senior Developers"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c91",
              "slug": "usergroup-1002",
              "name": "Senior Developers",
              "type": "custom",
              "orgId": "60d21b4667d0d8992e610c85",
              "users": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ],
              "updatedAt": "2025-04-27T14:30:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /userGroups/:groupId - Delete User Group">
        Soft-deletes a user group.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/userGroups/:groupId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required
            * `ValidationMiddleware.validate(UserGroupIdValidationSchema)`

            **Path Parameters:**

            * `groupId`: Group ID (24-character MongoDB ObjectId)

            **Restrictions:**

            * Only 'custom' groups can be deleted (throws ForbiddenError for others)
            * System groups (admin, everyone, standard) are protected
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "_id": "60d21b4667d0d8992e610c91",
              "name": "Senior Developers",
              "type": "custom",
              "isDeleted": true,
              "deletedBy": "60d21b4667d0d8992e610c86",
              "updatedAt": "2025-04-27T15:00:00.000Z"
            }
            ```

            **Side Effects:**

            * Sets `isDeleted: true` and `deletedBy` field
            * Soft delete preserves group data for audit purposes
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /userGroups/add-users - Add Users to Groups">
        Adds multiple users to multiple groups using atomic operations.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/userGroups/add-users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                                        |
            | --------- | --------- | -------- | -------------------------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs (MongoDB ObjectIds, min 1 item)  |
            | groupIds  | string\[] | Yes      | Array of group IDs (MongoDB ObjectIds, min 1 item) |

            **Operation Details:**

            * Uses `$addToSet` with `$each` to add users to multiple groups
            * Atomic operation - either all additions succeed or none
            * Prevents duplicate memberships automatically
            * Only operates on non-deleted groups

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ],
              "groupIds": [
                "60d21b4667d0d8992e610c91",
                "60d21b4667d0d8992e610c92"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Users added to groups successfully"
            }
            ```

            **Error Response:**

            ```json theme={null}
            {
              "message": "No groups found or updated"
            }
            ```

            **Side Effects:**

            * Each user added to all specified groups
            * Existing memberships preserved
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /userGroups/remove-users - Remove Users from Groups">
        Removes multiple users from multiple groups using atomic operations.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/userGroups/remove-users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `userAdminCheck` - Admin access required

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                       |
            | --------- | --------- | -------- | --------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs to remove       |
            | groupIds  | string\[] | Yes      | Array of group IDs to remove from |

            **Operation Details:**

            * Uses `$pullAll` to remove users from multiple groups
            * Atomic operation across all specified groups
            * Gracefully handles users not in groups

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c86"
              ],
              "groupIds": [
                "60d21b4667d0d8992e610c91"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "message": "Users removed from groups successfully"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups/:groupId/users - Get Users in Group">
        Retrieves all user IDs in a specific group.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups/:groupId/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `ValidationMiddleware.validate(UserGroupIdValidationSchema)`

            **Path Parameters:**

            * `groupId`: Group ID (24-character MongoDB ObjectId)
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "users": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ]
            }
            ```

            **Note:** Returns array of user ObjectIds, not full user objects.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups/users/:userId - Get Groups for User">
        Retrieves all groups that a specific user belongs to.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups/users/:userId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`

            **Path Parameters:**

            * `userId`: User ID (MongoDB ObjectId)

            **Description:** Uses `$in` query to find groups containing the user, selecting only name and type fields.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "60d21b4667d0d8992e610c90",
                "name": "admin",
                "type": "admin"
              },
              {
                "_id": "60d21b4667d0d8992e610c91",
                "name": "everyone",
                "type": "everyone"
              },
              {
                "_id": "60d21b4667d0d8992e610c92",
                "name": "Developers",
                "type": "custom"
              }
            ]
            ```
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups/stats/list - Get Group Statistics">
        Retrieves aggregated statistics about all groups in the organization.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups/stats/list`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`

            **Description:** Uses MongoDB aggregation pipeline to calculate statistics grouped by group name.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            [
              {
                "_id": "admin",
                "count": 1,
                "totalUsers": 2,
                "avgUsers": 2
              },
              {
                "_id": "everyone", 
                "count": 1,
                "totalUsers": 15,
                "avgUsers": 15
              },
              {
                "_id": "Developers",
                "count": 1,
                "totalUsers": 8,
                "avgUsers": 8
              }
            ]
            ```

            **Statistics Fields:**

            * `_id` - Group name (aggregation key)
            * `count` - Number of groups with this name
            * `totalUsers` - Total users across all groups with this name
            * `avgUsers` - Average users per group with this name
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /userGroups/health - Health Check">
        Health check endpoint for the user groups service.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/userGroups/health`

            **Authentication:** None required
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            ```json theme={null}
            {
              "status": "healthy",
              "timestamp": "2025-04-27T12:00:00.000Z"
            }
            ```
          </Tab>
        </Tabs>
      </Accordion>
    </AccordionGroup>
  </Accordion>

  <Accordion title="Teams Management">
    The Teams API manages collaborative workspaces through the connector backend service. All team operations are proxied to the AI connector backend.

    <AccordionGroup>
      <Accordion title="POST /teams - Create Team">
        Creates a new team via the connector backend service.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/teams`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(createTeamValidationSchema)`

            **Request Body Parameters:**

            | Parameter   | Type      | Required | Description                      |
            | ----------- | --------- | -------- | -------------------------------- |
            | name        | string    | Yes      | Team name (min 1 character)      |
            | description | string    | No       | Team description                 |
            | userIds     | string\[] | No       | Array of user IDs to add to team |
            | role        | string    | No       | Default role for team members    |

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team`

            ```json theme={null}
            {
              "name": "Product Development Team",
              "description": "Responsible for product development and roadmap",
              "userIds": [
                "60d21b4667d0d8992e610c86",
                "60d21b4667d0d8992e610c87"
              ],
              "role": "member"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `201 Created`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to create team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /teams - List Teams">
        Retrieves all teams with pagination via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/teams`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(listTeamsValidationSchema)`

            **Query Parameters:**

            * `page`: Page number (number, min 1, default 1, preprocessed from string)
            * `limit`: Items per page (number, min 1, max 100, default 10, preprocessed from string)
            * `search`: Search term for team names/descriptions (string, optional)

            **Proxy Behavior:** Query parameters passed to `${config.connectorBackend}/api/v1/entity/team/list`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to get teams")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /teams/:teamId - Get Team">
        Retrieves a specific team by ID via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/teams/:teamId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(getTeamValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to get team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /teams/:teamId - Update Team">
        Updates team information via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/teams/:teamId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateTeamValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Request Body Parameters:**

            | Parameter   | Type   | Required | Description              |
            | ----------- | ------ | -------- | ------------------------ |
            | name        | string | No       | Updated team name        |
            | description | string | No       | Updated team description |

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}`

            ```json theme={null}
            {
              "name": "Advanced Product Development Team",
              "description": "Leading product innovation and development"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to update team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /teams/:teamId - Delete Team">
        Deletes a team via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/teams/:teamId`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(deleteTeamValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to delete team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /teams/:teamId/users - Get Team Users">
        Retrieves all users in a specific team via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/teams/:teamId/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(getTeamUsersValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}/users`
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to get team users")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="POST /teams/:teamId/users - Add Users to Team">
        Adds users to a team via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `POST /api/v1/teams/:teamId/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(addUsersToTeamValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                           |
            | --------- | --------- | -------- | ------------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs to add (min 1 item) |

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}/users`

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c88",
                "60d21b4667d0d8992e610c89"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to add users to team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="DELETE /teams/:teamId/users - Remove Users from Team">
        Removes users from a team via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `DELETE /api/v1/teams/:teamId/users`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(removeUsersFromTeamValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                              |
            | --------- | --------- | -------- | ---------------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs to remove (min 1 item) |

            **Note:** Request body is optional in the validation schema, but userIds are required when the body is provided.

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}/users`

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c88"
              ]
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to remove user from team")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="PUT /teams/:teamId/users/permissions - Update Team User Permissions">
        Updates permissions for team members via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `PUT /api/v1/teams/:teamId/users/permissions`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`
            * `ValidationMiddleware.validate(updateTeamUsersPermissionsValidationSchema)`

            **Path Parameters:**

            * `teamId`: Team ID (string, min 1 character, required)

            **Request Body Parameters:**

            | Parameter | Type      | Required | Description                              |
            | --------- | --------- | -------- | ---------------------------------------- |
            | userIds   | string\[] | Yes      | Array of user IDs to update (min 1 item) |
            | role      | string    | No       | New role for the users                   |

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/team/${teamId}/users/permissions`

            ```json theme={null}
            {
              "userIds": [
                "60d21b4667d0d8992e610c87"
              ],
              "role": "lead"
            }
            ```
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend returns a non-200 status, this endpoint throws `BadRequestError("Failed to update team users permissions")`.
          </Tab>
        </Tabs>
      </Accordion>

      <Accordion title="GET /teams/user/teams - Get User Teams (Teams Endpoint)">
        Retrieves all teams that the authenticated user belongs to via connector backend.

        <Tabs>
          <Tab title="Request">
            **Endpoint:** `GET /api/v1/teams/user/teams`

            **Headers:**

            * `Authorization: Bearer YOUR_TOKEN`

            **Middleware Chain:**

            * `authMiddleware.authenticate`
            * `metricsMiddleware`

            **Proxy Behavior:** Request forwarded to `${config.connectorBackend}/api/v1/entity/user/teams`

            **Error Handling:** If connector backend returns non-200 status, returns empty array `[]` instead of throwing an error.
          </Tab>

          <Tab title="Response">
            **Status:** `200 OK`

            The response format depends on the connector backend implementation. If the backend is unavailable or returns an error, this endpoint returns an empty array.
          </Tab>
        </Tabs>
      </Accordion>
    </AccordionGroup>
  </Accordion>
</AccordionGroup>

## Schema Definitions

<Tabs>
  <Tab title="Organization Schema">
    ```typescript theme={null}
    interface IOrg extends Document {
      slug: string;                    // Auto-generated: "org-{counter}"
      registeredName: string;          // Required for business accounts with validation
      shortName?: string;              // Optional display name
      domain: string;                  // Extracted from contactEmail, required
      contactEmail: string;            // Required, lowercase, becomes admin email
      accountType: 'individual' | 'business';  // Required enum
      phoneNumber?: string;
      permanentAddress?: Address;      // Optional address object
      isDeleted: boolean;              // Default: false, soft delete flag
      deletedByUser?: string;
      onBoardingStatus: 'configured' | 'notConfigured' | 'skipped';  // Required enum
      // Timestamps added automatically
      createdAt?: Date;
      updatedAt?: Date;
    }

    interface Address {
      addressLine1?: string;
      city?: string;
      state?: string;
      postCode?: string;
      country?: string;               // Validated against jurisdictions enum
    }

    // Validation function for business accounts
    const orgSchemaValidation = (data) => {
      if (data.accountType === 'business') {
        return !!data.registeredName;
      }
      return true;
    };
    ```
  </Tab>

  <Tab title="User Schema">
    ```typescript theme={null}
    interface User extends Document, Address {
      slug?: string;                  // Auto-generated: "user-{counter}", unique
      orgId: Types.ObjectId;          // Required organization reference
      fullName?: string;              // Optional, trimmed
      firstName?: string;             // Optional, trimmed
      lastName?: string;              // Optional, trimmed
      middleName?: string;            // Optional, trimmed
      email: string;                  // Required, unique, lowercase, validated
      mobile?: string;                // Optional phone number
      hasLoggedIn?: boolean;          // Default: false, tracks first login
      designation?: string;           // Optional job title, trimmed
      address?: Address;              // Optional address object
      isDeleted?: boolean;            // Default: false, soft delete flag
      deletedBy?: string;             // User ID who deleted this user
      // Timestamps added automatically
      createdAt?: Date;
      updatedAt?: Date;
    }

    // Pre-save middleware generates slug if not present
    userSchema.pre<User>('save', async function (next) {
      if (!this.slug) {
        this.slug = await generateUniqueSlug('User');
      }
      next();
    });
    ```
  </Tab>

  <Tab title="User Group Schema">
    ```typescript theme={null}
    interface UserGroup extends Document {
      slug?: string;                          // Auto-generated: "usergroup-{counter}", unique
      name: string;                          // Required, group name
      type: 'admin' | 'standard' | 'custom' | 'everyone';  // Required enum
      orgId: Types.ObjectId;                 // Required organization reference
      users: Array<Types.ObjectId>;         // Array of user references
      isDeleted?: boolean;                   // Default: false, soft delete flag
      deletedBy?: Types.ObjectId;           // User who deleted this group
      // Timestamps added automatically
      createdAt?: Date;
      updatedAt?: Date;
    }

    // Available group types constant
    export const groupTypes = ['admin', 'standard', 'everyone', 'custom'];

    // Pre-save middleware generates slug
    userGroupsSchema.pre<UserGroup>('save', async function (next) {
      if (!this.slug) {
        this.slug = await generateUniqueSlug('UserGroup');
      }
      next();
    });
    ```
  </Tab>

  <Tab title="User Display Picture Schema">
    ```typescript theme={null}
    interface IuserDp extends Document {
      userId?: Types.ObjectId;        // User reference
      orgId?: Types.ObjectId;         // Organization reference
      pic?: string | null;            // Base64 encoded image data
      picUrl?: string | null;         // URL to image (if hosted externally)
      mimeType?: string | null;       // Image MIME type (e.g., 'image/jpeg')
    }

    // Collection name: 'user-dps'
    export const UserDisplayPicture = mongoose.model<IuserDp>(
      'user-dps',
      userDisplayPictureSchema,
      'user-dps',
    );
    ```
  </Tab>

  <Tab title="Organization Logo Schema">
    ```typescript theme={null}
    interface IorgLogo extends Document {
      orgId?: Types.ObjectId;         // Organization reference
      logo?: string | null;           // Base64 encoded logo data
      logoUrl?: string | null;        // URL to logo (if hosted externally)
      mimeType?: string | null;       // Image MIME type (e.g., 'image/jpeg')
    }

    // Collection name: 'org-logos'
    export const OrgLogos = model<IorgLogo>("org-logos", orgLogoSchema, "org-logos");
    ```
  </Tab>

  <Tab title="Counter Schema">
    ```typescript theme={null}
    interface CounterUser {
      _id: string;                    // Counter name (e.g., 'User', 'Org', 'UserGroup')
      name?: string;                  // Optional display name
      seq: number;                    // Current sequence number, default: 1000
    }

    // Used for generating unique slugs
    const generateUniqueSlug = async (name: string) => {
      const slug = require("slug");
      const counter = await getNextSequence(name);
      return slug(`${name}-${counter}`);
    };

    const getNextSequence = async (name: string): Promise<number> => {
      const counter = await Counter.findOneAndUpdate(
        { name: name },
        { $inc: { seq: 1 } },
        { new: true, upsert: true }
      );
      return counter.seq;
    };
    ```
  </Tab>
</Tabs>

## Validation Schemas

<Tabs>
  <Tab title="User Validation">
    ```typescript theme={null}
    // Create User Validation
    const createUserBody = z.object({
      fullName: z.string().min(1, 'Full name is required'),
      email: z.string().email('Invalid email'),
      mobile: z.string().optional().refine((val) => 
        !val || /^\+?[0-9]{10,15}$/.test(val), {
        message: 'Invalid mobile number'
      }),
      designation: z.string().optional(),
    });

    // Update User Validation (comprehensive)
    const updateUserBody = z.object({
      fullName: z.string().optional(),
      email: z.string().email('Invalid email'),  // Required field
      mobile: z.string().optional().refine((val) => 
        !val || /^\+?[0-9]{10,15}$/.test(val), {
        message: 'Invalid mobile number'
      }),
      designation: z.string().optional(),
      firstName: z.string().optional(),
      lastName: z.string().optional(),
      address: z.object({
        addressLine1: z.string().optional(),
        city: z.string().optional(),
        state: z.string().optional(),
        postCode: z.string().optional(),
        country: z.string().optional(),
      }).optional(),
      hasLoggedIn: z.boolean().optional(),
    });

    // Specific field updates
    const updateFullNameBody = z.object({
      fullName: z.string().min(1, 'fullName must have at least one character'),
    });

    const updateFirstNameBody = z.object({
      firstName: z.string().min(1, 'firstName is required'),
    });

    // MongoDB ObjectId validation
    const UserIdUrlParams = z.object({
      id: z.string().regex(/^[a-fA-F0-9]{24}$/, 'Invalid UserId'),
    });

    // Multiple users validation
    const MultipleUserBody = z.object({
      userIds: z.array(
        z.string().regex(/^[a-fA-F0-9]{24}$/, 'Invalid MongoDB ObjectId')
      ).min(1, 'At least one userId is required'),
    });
    ```
  </Tab>

  <Tab title="Organization Validation">
    ```typescript theme={null}
    const OrgCreationBody = z.object({
      accountType: z.enum(['individual', 'business']),
      shortName: z.string().optional(),
      contactEmail: z.string().email('Invalid email format'),
      registeredName: z.string().optional(), // Conditional validation below
      adminFullName: z.string().min(1, 'Admin full name required'),
      password: z.string().min(8, 'Minimum 8 characters password required'),
      sendEmail: z.boolean().optional(),
      permanentAddress: z.object({
        addressLine1: z.string().optional(),
        city: z.string().optional(),
        state: z.string().optional(),
        country: z.string().optional(),
        postCode: z.string().optional(),
      }).optional(),
    }).refine((data) => {
      // Business accounts require registeredName
      return data.accountType === 'business' ? !!data.registeredName : true;
    }, {
      message: 'Registered Name is required for business accounts',
      path: ['registeredName'],
    });

    // Onboarding status validation
    const OnboardingStatusUpdateBody = z.object({
      status: z.enum(['configured', 'notConfigured', 'skipped']),
    });

    // Password complexity validation function
    function passwordValidator(password: string): boolean {
      // Minimum 8 characters with at least one uppercase, 
      // one lowercase, one number and one special character
      const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
      return passwordRegex.test(password);
    }
    ```
  </Tab>

  <Tab title="User Group Validation">
    ```typescript theme={null}
    // User Group Creation Validation
    const groupValidationSchema = z.object({
      body: z.object({
        type: z.string().min(1, 'type is required'),
        name: z.string().min(1, 'name is required'),
      }),
      query: z.object({}),
      params: z.object({}),
      headers: z.object({}),
    });

    // Group ID validation for URL parameters
    const UserGroupIdUrlParams = z.object({
      groupId: z.string().min(1, "Group ID is required")
        .regex(/^[0-9a-fA-F]{24}$/, "Invalid group ID format")
    });

    const UserGroupIdValidationSchema = z.object({
      body: z.object({}),
      query: z.object({}),
      params: UserGroupIdUrlParams,
      headers: z.object({}),
    });

    // Available group types constant
    export const groupTypes = ['admin', 'standard', 'everyone', 'custom'];
    ```
  </Tab>

  <Tab title="Teams Validation">
    ```typescript theme={null}
    // Create Team Validation
    const createTeamValidationSchema = z.object({
      body: z.object({
        name: z.string().min(1, 'Name is required'),
        description: z.string().optional(),
        userIds: z.array(z.string()).optional(),
        role: z.string().optional(),
      }),
    });

    // List Teams Validation with pagination
    const listTeamsValidationSchema = z.object({
      query: z.object({
        search: z.string().optional(),
        limit: z.preprocess(
          (arg) => Number(arg), 
          z.number().min(1).max(100).default(10)
        ).optional(),
        page: z.preprocess(
          (arg) => Number(arg), 
          z.number().min(1).default(1)
        ).optional(),
      }),
    });

    // Team operations validation
    const getTeamValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
    });

    const updateTeamValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
      body: z.object({
        name: z.string().optional(),
        description: z.string().optional(),
      }),
    });

    const deleteTeamValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
    });

    const addUsersToTeamValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
      body: z.object({
        userIds: z.array(z.string()).min(1, 'User IDs are required'),
      }),
    });

    const removeUsersFromTeamValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
      body: z.object({
        userIds: z.array(z.string()).min(1, 'User IDs are required'),
      }).optional(),
    });

    const updateTeamUsersPermissionsValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
      body: z.object({
        userIds: z.array(z.string()).min(1, 'User IDs are required'),
        role: z.string().optional(),
      }),
    });

    const getTeamUsersValidationSchema = z.object({
      params: z.object({
        teamId: z.string().min(1, 'Team ID is required'),
      }),
    });
    ```
  </Tab>

  <Tab title="File Upload Validation">
    ```typescript theme={null}
    // File upload constraints used in FileProcessorFactory
    const FileUploadConfig = {
      allowedMimeTypes: [
        'image/png',
        'image/jpeg', 
        'image/jpg',
        'image/webp',
        'image/gif'
      ],
      maxFileSize: 1024 * 1024, // 1MB
      maxFilesAllowed: 1,
      isMultipleFilesAllowed: false,
      processingType: FileProcessingType.BUFFER,
      strictFileUpload: true
    };

    // Image compression settings using Sharp
    const CompressionConfig = {
      initialQuality: 100,
      minQuality: 10,
      qualityStep: 10,
      targetSize: 100 * 1024, // 100KB target after compression
      outputFormat: 'image/jpeg'
    };

    // Compression algorithm
    const compressImage = async (imageBuffer: Buffer): Promise<Buffer> => {
      let quality = 100;
      let compressedImageBuffer = await sharp(imageBuffer)
        .jpeg({ quality })
        .toBuffer();
        
      while (compressedImageBuffer.length > 100 * 1024 && quality > 10) {
        quality -= 10;
        compressedImageBuffer = await sharp(imageBuffer)
          .jpeg({ quality })
          .toBuffer();
      }
      
      if (compressedImageBuffer.length > 100 * 1024) {
        throw new LargePayloadError('File too large, limit: 100KB after compression');
      }
      
      return compressedImageBuffer;
    };
    ```
  </Tab>
</Tabs>

## Error Handling

All endpoints return structured error responses:

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": "Email is required and must be a valid email address"
  },
  "timestamp": "2025-04-27T13:20:00.000Z",
  "path": "/users",
  "method": "POST"
}
```

**Common Error Codes:**

* `VALIDATION_ERROR` - Invalid request parameters
* `NOT_FOUND` - Resource not found
* `UNAUTHORIZED` - Authentication required
* `FORBIDDEN` - Insufficient privileges
* `BAD_REQUEST` - Invalid operation
* `INTERNAL_ERROR` - Server error

**HTTP Status Codes:**

* `200` - Success
* `201` - Created
* `400` - Bad Request (validation errors)
* `401` - Unauthorized
* `403` - Forbidden (insufficient privileges)
* `404` - Not Found
* `500` - Internal Server Error

## Important Notes

1. **Route Paths:** All route paths shown are relative to how the routers are mounted in the main application

2. **MongoDB ObjectIds:** All ID fields use 24-character hexadecimal strings matching `/^[a-fA-F0-9]{24}$/`

3. **Soft Deletes:** Users, organizations, and groups use soft deletion (`isDeleted: true`) rather than physical removal

4. **Admin Restrictions:**
   * Admin users cannot be deleted (checked via group membership)
   * Only custom user groups can be deleted (admin, everyone, standard are protected)

5. **SMTP Dependencies:** Email features require valid SMTP configuration checked via Configuration Manager service

6. **Account Type Restrictions:**
   * Bulk user invitations limited to business accounts
   * Individual accounts have restricted functionality

7. **Automatic Group Memberships:**
   * All users automatically added to "everyone" group
   * Admin users added to "admin" group during organization creation

8. **Image Processing:**
   * Uploaded images automatically compressed using Sharp library
   * Converted to JPEG format with dynamic quality adjustment
   * Target size: under 100KB after compression

9. **Event Publishing:**
   * All entity changes publish events via Kafka for system integration
   * Events include organization and user lifecycle changes

10. **Transaction Support:**
    * Uses MongoDB transactions when replica sets available
    * Falls back to individual operations for single-node deployments

11. **Teams Functionality:**
    * All teams operations are proxied to AI connector backend
    * Routes forward requests to `${config.connectorBackend}/api/v1/entity/team/*`
    * Error handling returns appropriate responses for failed backend calls
    * Response formats depend entirely on connector backend implementation

12. **Unique Constraints:**
    * Email addresses must be unique across the system
    * Group names must be unique within organization
    * Slugs auto-generated with counter-based uniqueness

13. **Middleware Processing:**
    * FileProcessorFactory methods return arrays that are spread into middleware chains
    * Validation schemas include complete request structure (body, query, params, headers)

14. **Service Integration:**
    * Configuration updates dynamically rebind services in dependency injection container
    * Health endpoints available on all router modules
    * Metrics recorded via Prometheus service for monitoring

15. **Access Control:**
    * Scoped tokens for service-to-service communication (USER\_LOOKUP, FETCH\_CONFIG)
    * Role-based access through user group membership
    * Admin-only operations clearly enforced through middleware

16. **Duplicate User Teams Endpoints:**
    * `/teams/user/teams` (managed by TeamsController) - Returns empty array on backend errors
    * `/users/teams/list` (managed by UserController) - Throws BadRequestError on backend errors
    * Both proxy to connector backend but have different error handling strategies

17. **File Upload Middleware:**
    * `FileProcessorFactory.createBufferUploadProcessor()` returns an object with `getMiddleware` array
    * Middleware is spread using the spread operator (`...middleware.getMiddleware`)
    * All uploaded images undergo automatic compression regardless of original format

18. **Validation Preprocessing:**
    * Query parameters for pagination are preprocessed from strings to numbers using `z.preprocess()`
    * Default values are applied during validation for optional pagination parameters

19. **Container Integration:**
    * Inversify container provides dependency injection throughout the application
    * Services are dynamically rebound when configuration updates occur
    * Container disposal handles cleanup of connections and resources

20. **Email Behavior Variations:**
    * Different email templates sent for new vs restored user invitations
    * Authentication method (password vs non-password) affects email content
    * SMTP configuration validation occurs before any email sending operations
