> For the complete documentation index, see [llms.txt](https://qbits-organization.gitbook.io/buildwise-doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://qbits-organization.gitbook.io/buildwise-doc/subcontractor-endpoints.md).

# Subcontractor Endpoints

### Create Subcontractor

Creates a new subcontractor for the specified organisation. The authenticated user must have appropriate permissions in the organisation.

#### Endpoint

```
POST /api/v1/subcontractor/organisation/{organisationId}
```

#### Path Parameters

* `organisationId` (UUID) - The organisation identifier where the subcontractor will be created

#### Request Body

```json
{
    "companyName": "ABC Construction Services",
    "email": "contact@abcconstruction.com",
    "phoneNumber": "+1234567890",
    "tin": "123456789",
    "address": "123 Construction Avenue, Builder City, BC 12345",
    "registrationNumber": "REG-2025-ABC-001",
    "specializations": ["Electrical", "Plumbing", "HVAC"]
}
```

#### Validation Rules

* `companyName`: Required, cannot be blank, must be unique within the organisation
* `email`: Required, valid email format, must be globally unique
* `phoneNumber`: Optional
* `tin`: Required, must be globally unique
* `address`: Optional
* `registrationNumber`: Required, must be globally unique
* `specializations`: Optional, array of strings

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractor created successfully",
    "action_time": "2025-06-02T14:30:15.123456",
    "data": {
        "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
        "companyName": "ABC Construction Services",
        "email": "contact@abcconstruction.com",
        "phoneNumber": "+1234567890",
        "tin": "123456789",
        "address": "123 Construction Avenue, Builder City, BC 12345",
        "registrationNumber": "REG-2025-ABC-001",
        "specializations": ["Electrical", "Plumbing", "HVAC"],
        "organisationName": "My Construction Company",
        "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
        "projects": [
            {
                "projectId": "123e4567-e89b-12d3-a456-426614174000",
                "name": "Website Redesign Project",
                "description": "Complete overhaul of company website",
                "budget": 50000.00,
                "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
                "organisationName": "My Construction Company",
                "status": "ACTIVE",
                "contractNumber": "WEB-2025-001",
                "createdAt": "2025-06-02T14:30:15.123456",
                "updatedAt": "2025-06-02T14:30:15.123456"
            }
        ],
        "createdAt": "2025-06-02T14:30:15.123456",
        "updatedAt": "2025-06-02T14:30:15.123456",
        "projectsCount": 1,
        "specializationsCount": 3
    }
}
```

#### Error Responses

* `404` - Organisation not found or project not found
* `400` - Duplicate registration number, email, TIN, or company name; missing required fields; invalid data provided
* `401` - Unauthorized (invalid token)
* `500` - An unexpected error occurred while creating the subcontractor

***

### Get Subcontractor By ID

Retrieves a subcontractor by its ID. The authenticated user must have appropriate permissions.

#### Endpoint

```
GET /api/v1/subcontractor/{subcontractorId}
```

#### Path Parameters

* `subcontractorId` (UUID) - The subcontractor identifier

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractor retrieved successfully",
    "action_time": "2025-06-02T14:35:20.654321",
    "data": {
        "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
        "companyName": "ABC Construction Services",
        "email": "contact@abcconstruction.com",
        "phoneNumber": "+1234567890",
        "tin": "123456789",
        "address": "123 Construction Avenue, Builder City, BC 12345",
        "registrationNumber": "REG-2025-ABC-001",
        "specializations": ["Electrical", "Plumbing", "HVAC"],
        "organisationName": "My Construction Company",
        "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
        "projects": [
            {
                "projectId": "123e4567-e89b-12d3-a456-426614174000",
                "name": "Website Redesign Project",
                "description": "Complete overhaul of company website",
                "budget": 50000.00,
                "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
                "organisationName": "My Construction Company",
                "status": "ACTIVE",
                "contractNumber": "WEB-2025-001",
                "createdAt": "2025-06-02T14:30:15.123456",
                "updatedAt": "2025-06-02T14:30:15.123456"
            }
        ],
        "createdAt": "2025-06-02T14:30:15.123456",
        "updatedAt": "2025-06-02T14:30:15.123456",
        "projectsCount": 1,
        "specializationsCount": 3
    }
}
```

#### Error Responses

* `404` - Subcontractor not found
* `401` - Unauthorized
* `500` - Internal server error

***

### Get All Subcontractors

Retrieves all subcontractors in the system. The authenticated user must have appropriate permissions.

#### Endpoint

```
GET /api/v1/subcontractor
```

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractors retrieved successfully",
    "action_time": "2025-06-02T15:00:30.789123",
    "data": [
        {
            "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
            "companyName": "ABC Construction Services",
            "email": "contact@abcconstruction.com",
            "phoneNumber": "+1234567890",
            "specializations": ["Electrical", "Plumbing", "HVAC"],
            "organisationName": "My Construction Company",
            "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
            "projectsCount": 2,
            "specializationsCount": 3,
            "createdAt": "2025-06-02T14:30:15.123456",
            "updatedAt": "2025-06-02T14:30:15.123456"
        }
    ]
}
```

#### Error Responses

* `401` - Unauthorized
* `500` - Internal server error

***

### Get Subcontractors by Organisation

Retrieves all subcontractors for a specific organisation. The authenticated user must be a member of the organisation.

#### Endpoint

```
GET /api/v1/subcontractor/organisation/{organisationId}
```

#### Path Parameters

* `organisationId` (UUID) - The organisation identifier

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractors retrieved successfully",
    "action_time": "2025-06-02T15:05:45.234567",
    "data": [
        {
            "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
            "companyName": "ABC Construction Services",
            "email": "contact@abcconstruction.com",
            "phoneNumber": "+1234567890",
            "specializations": ["Electrical", "Plumbing", "HVAC"],
            "organisationName": "My Construction Company",
            "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
            "projectsCount": 2,
            "specializationsCount": 3,
            "createdAt": "2025-06-02T14:30:15.123456",
            "updatedAt": "2025-06-02T14:30:15.123456"
        }
    ]
}
```

#### Error Responses

* `404` - Organisation not found
* `401` - Unauthorized
* `500` - Internal server error

***

### Update Subcontractor

Updates an existing subcontractor's details. The authenticated user must have appropriate permissions.

#### Endpoint

```
PUT /api/v1/subcontractor/{subcontractorId}
```

#### Path Parameters

* `subcontractorId` (UUID) - The subcontractor identifier to update

#### Request Body

```json
{
    "companyName": "Updated Construction Services",
    "email": "newemail@construction.com",
    "phoneNumber": "+0987654321",
    "tin": "987654321",
    "address": "456 New Construction Street, Builder City, BC 54321",
    "registrationNumber": "REG-2025-UPD-001",
    "specializations": ["Electrical", "Plumbing", "HVAC", "Carpentry"]
    }
```

#### Update Rules

* Only the provided fields are updated
* Empty or null values preserve existing data
* Email, TIN, and registration number must be unique if changed
* Company name must be unique within the organisation if changed
* Project IDs replace the existing project assignments

#### Success Response

<pre class="language-json"><code class="lang-json">{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractor updated successfully",
    "action_time": "2025-06-02T15:10:25.345678",
    "data": {
        "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
<strong>        "companyName": "Updated Construction Services",
</strong>        "email": "newemail@construction.com",
        "phoneNumber": "+0987654321",
        "tin": "987654321",
        "address": "456 New Construction Street, Builder City, BC 54321",
        "registrationNumber": "REG-2025-UPD-001",
        "specializations": ["Electrical", "Plumbing", "HVAC", "Carpentry"],
        "organisationName": "My Construction Company",
        "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
        "projects": [
            {
                "projectId": "123e4567-e89b-12d3-a456-426614174000",
                "name": "Website Redesign Project",
                "description": "Complete overhaul of company website",
                "budget": 50000.00,
                "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
                "organisationName": "My Construction Company",
                "status": "ACTIVE",
                "contractNumber": "WEB-2025-001",
                "createdAt": "2025-06-02T14:30:15.123456",
                "updatedAt": "2025-06-02T14:30:15.123456"
            }
        ],
        "createdAt": "2025-06-02T14:30:15.123456",
        "updatedAt": "2025-06-02T15:10:25.345678",
        "projectsCount": 1,
        "specializationsCount": 4
    }
}
</code></pre>

#### Error Responses

* `404` - Subcontractor not found or project not found
* `400` - Duplicate registration number, email, TIN, or company name; invalid data provided
* `401` - Unauthorized
* `500` - An unexpected error occurred while updating the subcontractor

***

### Delete Subcontractor

Permanently deletes a subcontractor and removes all project associations. The authenticated user must have appropriate permissions.

#### Endpoint

```
DELETE /api/v1/subcontractor/{subcontractorId}
```

#### Path Parameters

* `subcontractorId` (UUID) - The subcontractor identifier to delete

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractor deleted successfully",
    "action_time": "2025-06-02T15:15:30.789123",
    "data": null
}
```

#### Error Responses

* `404` - Subcontractor not found
* `401` - Unauthorized
* `500` - Failed to delete subcontractor

***

### Get Subcontractor Projects

Retrieves all projects assigned to a specific subcontractor.

#### Endpoint

```
GET /api/v1/subcontractor/{subcontractorId}/projects
```

#### Path Parameters

* `subcontractorId` (UUID) - The subcontractor identifier

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractor projects retrieved successfully",
    "action_time": "2025-06-02T15:20:45.234567",
    "data": [
        {
            "projectId": "123e4567-e89b-12d3-a456-426614174000",
            "name": "Website Redesign Project",
            "description": "Complete overhaul of company website",
            "budget": 50000.00,
            "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
            "organisationName": "My Construction Company",
            "status": "ACTIVE",
            "contractNumber": "WEB-2025-001",
            "createdAt": "2025-06-02T14:30:15.123456",
            "updatedAt": "2025-06-02T14:30:15.123456"
        }
    ]
}
```

#### Error Responses

* `404` - Subcontractor not found
* `401` - Unauthorized
* `500` - Internal server error

### Get Subcontractors by Specializations

Retrieves subcontractors that have any of the specified specializations.

#### Endpoint

```
GET /api/v1/subcontractor/specializations
```

#### Query Parameters

* `specializations` (List\<String>) - List of specialization names to filter by

#### Example Request

```
GET /api/v1/subcontractor/specializations?specializations=Electrical&specializations=Plumbing
```

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Subcontractors by specializations retrieved successfully",
    "action_time": "2025-06-02T15:40:45.789012",
    "data": [
        {
            "subcontractorId": "456e7890-e12b-34c5-d678-901234567890",
            "companyName": "ABC Construction Services",
            "email": "contact@abcconstruction.com",
            "phoneNumber": "+1234567890",
            "specializations": ["Electrical", "Plumbing", "HVAC"],
            "organisationName": "My Construction Company",
            "organisationId": "987fcdeb-51a2-43d1-9f12-123456789abc",
            "projectsCount": 2,
            "specializationsCount": 3,
            "createdAt": "2025-06-02T14:30:15.123456",
            "updatedAt": "2025-06-02T14:30:15.123456"
        }
    ]
}
```

#### Error Responses

* `400` - Invalid specializations parameter
* `401` - Unauthorized
* `500` - Internal server error

***

### Check Registration Number Availability

Checks if a registration number is already in use.

#### Endpoint

```
GET /api/v1/subcontractor/check/registration-number
```

#### Query Parameters

* `registrationNumber` (String) - The registration number to check

#### Example Request

```
GET /api/v1/subcontractor/check/registration-number?registrationNumber=REG-2025-ABC-001
```

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Registration number already exists",
    "action_time": "2025-06-02T15:45:30.234567",
    "data": true
}
```

#### Error Responses

* `400` - Missing or invalid registration number parameter
* `401` - Unauthorized
* `500` - Internal server error

***

### Check Email Availability

Checks if an email address is already in use.

#### Endpoint

```
GET /api/v1/subcontractor/check/email
```

#### Query Parameters

* `email` (String) - The email address to check

#### Example Request

```
GET /api/v1/subcontractor/check/email?email=contact@abcconstruction.com
```

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Email is available",
    "action_time": "2025-06-02T15:50:15.456789",
    "data": false
}
```

#### Error Responses

* `400` - Missing or invalid email parameter
* `401` - Unauthorized
* `500` - Internal server error

***

### Check TIN Availability

Checks if a TIN (Tax Identification Number) is already in use.

#### Endpoint

```
GET /api/v1/subcontractor/check/tin
```

#### Query Parameters

* `tin` (String) - The TIN to check

#### Example Request

```
GET /api/v1/subcontractor/check/tin?tin=123456789
```

#### Success Response

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "TIN already exists",
    "action_time": "2025-06-02T15:55:30.678901",
    "data": true
}
```

#### Error Responses

* `400` - Missing or invalid TIN parameter
* `401` - Unauthorized
* `500` - Internal server error

#### Common Error Responses

All endpoints may return:

* `401 Unauthorized` - Invalid or missing authentication token
* `500 Internal Server Error` - Unexpected server error

#### Response Format

All successful responses follow this structure:

```json
{
    "success": true,
    "httpStatus": "OK",
    "message": "Description of the operation",
    "action_time": "2025-06-02T15:45:30.123456",
    "data": { /* Response data or null */ }
}
```

### Additional Notes

#### Data Uniqueness Constraints

* **Registration Number**: Must be globally unique across all subcontractors
* **Email**: Must be globally unique across all subcontractors
* **TIN**: Must be globally unique across all subcontractors
* **Company Name**: Must be unique within each organisation

####

#### Specializations

* Specializations are stored as an array of strings
* Filtering by specializations uses an "IN" operation (matches any of the provided specializations)
* No predefined list of specializations - they are free-form text
