# SPECIFICATIONS/06_API/06_03_AGENTS_ENDPOINTS.md

**PURPOSE:** Specifies the agent management API surface. Agent operations hit the unified `clients` table filtered by the `agent` flag.

> **Business rules enforced by these endpoints:** `../01_BUSINESS_CONTEXT/03_BUSINESS_RULES.md` → BR-001-1, BR-001-5
> **Computed field formulas:** `../05_ALGORITHMS/04_COMPUTED_FIELDS.md` → Section 5.4
> **Shares operations:** `06_09_SHARES_ENDPOINTS.md`
> **Data minimization rules:** `../../CONSTITUTIONS/07_BOUNDARY_LAYERS.md`

---

## GET /api/v1/agents

**Permission:** `agents.view`

**Inputs (Query Params):**

| Field | Type | Required | Validation |
|:---|:---|:---|:---|
| `search` | string | No | max 150 chars |
| `cursor` | string | No | Valid cursor |
| `per_page` | integer | No | Default 20, max 100 |

**Outputs:**
```json
{
    "success": true,
    "message": "string",
    "data": [
        {
            "id": 2,
            "name": "string",
            "phone": "string",
            "avatar_url": "string|null"
        }
    ],
    "meta": {
        "real_cursor": "string|null",
        "has_more": false,
        "per_page": 20
    }
}
```

**Behavior:**
- Filters clients where `agent` flag is present
- Search by name (partial match)
- Sorted alphabetically by name
- `client_type_flags` is strictly excluded from this response

---

## POST /api/v1/agents

**Permission:** `agents.create`

**Inputs:**

| Field | Type | Required | Validation |
|:---|:---|:---|:---|
| `client_id` | integer | No | exists in clients, nullable |
| `name` | string | Conditional* | — |
| `phone` | string | Conditional* | unique |
| `description` | text | No | nullable |
| `avatar` | file | No | image, jpg/jpeg/png/webp, max 5MB |

*Required only when `client_id` is not provided.

**Outputs:**
```json
{
    "success": true,
    "message": "string",
    "data": {
        "id": 1,
        "name": "string",
        "phone": "string",
        "description": "string|null",
        "avatar_url": "string|null"
    }
}
```

**Behavior:**
- **With `client_id`:** Updates provided fields on existing client, adds `agent` flag. Does NOT modify existing flags or reference number.
- **Without `client_id`:** Creates new client with `agent` flag assigned.
- If avatar provided: stored securely
- Shares are NOT handled here — see `06_09_SHARES_ENDPOINTS.md`
- `client_type_flags` is strictly excluded from this response

---

## GET /api/v1/agents/{id}

**Permission:** `agents.view`

**Inputs:** None (route param: `id`)

**Outputs:**
```json
{
    "success": true,
    "message": "string",
    "data": {
        "id": 1,
        "name": "string",
        "phone": "string",
        "description": "string|null",
        "avatar_url": "string|null",
        "financial_summary": {
            "total_installments_via_agent": "0.00",
            "total_collected_via_agent": "0.00",
            "total_remaining_via_agent": "0.00"
        },
        "referred_customers": [
            {
                "id": 1,
                "name": "string",
                "avatar_url": "string|null",
                "total_remaining": "0.00",
                "total_collected": "0.00"
            }
        ]
    }
}
```

**Behavior:**
- If client does not have `agent` flag → returns 404
- Financial totals calculated from agent's active/completed contracts only
- `referred_customers`: list of customers brought by this agent with their financial summaries

---

## PUT /api/v1/agents/{id}

**Permission:** `agents.update`

**Inputs:**

| Field | Type | Required | Validation |
|:---|:---|:---|:---|
| `name` | string | No | — |
| `phone` | string | No | unique (ignore current) |
| `description` | text | No | nullable |
| `avatar` | file | No | image, jpg/jpeg/png/webp, max 5MB |

**Outputs:** Same shape as POST create response

**Behavior:**
- If new avatar provided: old deleted securely, new stored
- Never modifies `client_type_flags`, `reference_number`, or shares
- At least one field must be provided

---

## DELETE /api/v1/agents/{id}

**This endpoint does not exist.**

Agents are hard immutable entities (BR-001-1). Deletion is prohibited at both code and database levels.