# Projects API Contract

This document defines the API contract for the Projects module. It aligns the Frontend (FE) and Backend (BE) to ensure a perfectly matched shape.

## General Information

### Headers (Required on all calls)
- `Authorization`: `Bearer <token>`
- `X-Company-Id`: `<company_id>`
- `Accept`: `application/json`
- `Content-Type`: `application/json` (for POST/PUT)

### Response Envelope
All API responses follow a standardized envelope structure.

#### Success Response
```json
{
  "success": true,
  "message": "Operation successful",
  "data": { ... } // or [...] for lists
}
```

#### Paginated Success Response
For lists that support pagination.
```json
{
  "success": true,
  "message": "Projects fetched successfully",
  "data": [ ... ],
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 5,
    "per_page": 10,
    "to": 10,
    "total": 50
  },
  "links": {
    "first": "...",
    "last": "...",
    "prev": null,
    "next": "..."
  }
}
```

#### Error Response (422 Unprocessable Entity)
When validation fails, the API returns a `422` status code with the following structure:
```json
{
  "success": false,
  "message": "The given data was invalid.",
  "errors": {
    "name": [
      "The name field is required."
    ],
    "start_date": [
      "The start date must be a valid date."
    ]
  }
}
```

---

## Permissions
- `project.projects-*` (or specific CRUD permissions like `project.projects-create`, etc. depending on your role setup)

---

## Endpoints

### 1. List Projects
`GET /api/v1/project/projects`

**Query Parameters:**
| Parameter | Type | Required | Description |
|---|---|---|---|
| `page` | integer | No | Page number (default: 1) |
| `per_page` | integer | No | Items per page (default: 10) |
| `status` | string | No | Filter by status (e.g., `active`, `draft`) |
| `client_id` | integer | No | Filter by Client ID |
| `search` | string | No | Search term for project name |
| `project_type_id` | integer | No | Filter by Project Type ID |
| `project_category_id` | integer | No | Filter by Project Category ID |

**Response (200 OK):**
*Follows the **Paginated Success Response** envelope containing project objects.*

---

### 2. Create Project
`POST /api/v1/project/projects`

**Business Rules:**
- **BR-01**: `client_id`, `project_type_id`, `project_category_id`, and `project_subcategory_id` must belong to the active company. 
- Date validation: `expected_end_date` must be greater than or equal to `start_date`.

**Request Body:**
```json
{
  "client_id": 1,
  "name": "New Project 2026",
  "project_type_id": 1,
  "project_category_id": 1,
  "project_subcategory_id": 2,
  "description": "Details about the new project engagement",
  "start_date": "2026-09-01",
  "expected_end_date": "2026-12-31",
  "status": "draft",
  "owner_user_id": 1
}
```

**Response (201 Created):**
```json
{
  "success": true,
  "message": "Project created successfully",
  "data": {
    "id": 100,
    "company_id": 1,
    "client_id": 1,
    "client": { "id": 1, "name": "ABC Corporation" },
    "name": "New Project 2026",
    "project_type_id": 1,
    "project_type": { "id": 1, "name": "Retainer Project" },
    "project_category_id": 1,
    "project_category": { "id": 1, "name": "Digital Marketing" },
    "project_subcategory_id": 2,
    "project_subcategory": { "id": 2, "name": "SEO" },
    "description": "Details about the new project engagement",
    "start_date": "2026-09-01",
    "expected_end_date": "2026-12-31",
    "status": "draft",
    "owner_user_id": 1,
    "created_at": "2026-09-16T10:00:00+00:00",
    "updated_at": "2026-09-16T10:00:00+00:00"
  }
}
```

---

### 3. Show Project
`GET /api/v1/project/projects/{id}`

**Response (200 OK):**
```json
{
  "success": true,
  "message": "Project fetched successfully",
  "data": {
    "id": 100,
    "company_id": 1,
    "client_id": 1,
    "client": { "id": 1, "name": "ABC Corporation" },
    "name": "New Project 2026",
    "project_type_id": 1,
    "project_type": { "id": 1, "name": "Retainer Project" },
    "project_category_id": 1,
    "project_category": { "id": 1, "name": "Digital Marketing" },
    "project_subcategory_id": 2,
    "project_subcategory": { "id": 2, "name": "SEO" },
    "description": "Details about the new project engagement",
    "start_date": "2026-09-01",
    "expected_end_date": "2026-12-31",
    "status": "draft",
    "owner_user_id": 1,
    "created_at": "2026-09-16T10:00:00+00:00",
    "updated_at": "2026-09-16T10:00:00+00:00"
  }
}
```

---

### 4. Update Project
`PUT /api/v1/project/projects/{id}`

**Request Body:**
```json
{
  "name": "Updated Project 2026",
  "status": "active"
}
```
*(Note: Fields can vary depending on what is being updated. Include all relevant updateable fields)*

**Response (200 OK):**
```json
{
  "success": true,
  "message": "Project updated successfully",
  "data": {
    "id": 100,
    "company_id": 1,
    "client_id": 1,
    "client": { "id": 1, "name": "ABC Corporation" },
    "name": "Updated Project 2026",
    "project_type_id": 1,
    "project_type": { "id": 1, "name": "Retainer Project" },
    "project_category_id": 1,
    "project_category": { "id": 1, "name": "Digital Marketing" },
    "project_subcategory_id": 2,
    "project_subcategory": { "id": 2, "name": "SEO" },
    "description": "Details about the new project engagement",
    "start_date": "2026-09-01",
    "expected_end_date": "2026-12-31",
    "status": "active",
    "owner_user_id": 1,
    "created_at": "2026-09-16T10:00:00+00:00",
    "updated_at": "2026-09-16T10:30:00+00:00"
  }
}
```

---

### 5. Destroy Project
`DELETE /api/v1/project/projects/{id}`

**Response (200 OK):**
```json
{
  "success": true,
  "message": "Project deleted successfully",
  "data": null
}
```
