# Research History API — Curl / Postman

**Controller:** `DiverseResearchController`
**Method:** `getResearchHistory`
**Route name:** `research-history-index`
**Middleware:** `jwt.auth`, `check.token`, `dynamic.permission`
(assign this route to the back-office user's role in route-API permissions first)

Base URL (XAMPP local):

```text
http://localhost/fintraBackend/fi_adm/public/api
```

Replace `YOUR_JWT_TOKEN` with the `access_token` from login.

---

## 0. Login (get JWT)

```bash
curl --location --request POST "http://localhost/fintraBackend/fi_adm/public/api/auth/login" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data-raw "{
    \"email\": \"your.backoffice@email.com\",
    \"password\": \"your_password\"
  }"
```

---

## 1. All reports (default)

Powers the "All Reports" tab. Returns page 1 with 15 rows per page.

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

## 2. Filter by category tab

Pass the `research_categories.id` of the selected tab. `category=all` (or omitting it) returns every report.

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index?category=1" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index?category=all" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

## 3. Global search

Matches `report_title`, `sub_heading`, the report type name, and tag names.

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index?search=budget" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

Search inside a single tab (both filters combine):

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index?category=2&search=pharma" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

## 4. Pagination

```bash
curl --location --request GET "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-history-index?per_page=25&page=2" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

---

## Query parameter reference

| Parameter | Required | Type | Notes |
|---|---|---|---|
| `category` | No | int or `all` | A `research_categories.id`. `all`, an empty value, or omitting it skips the filter. |
| `search` | No | string | Max 255. Matches `report_title`, `sub_heading`, report type name, tag name. |
| `per_page` | No | int | Min 1, max 100. Defaults to `15`. |
| `page` | No | int | Standard Laravel pagination page number. |

Notes:

* There is no `category_slug`; `research_categories` has no slug column, so filter by id.
* `uploaded_by.avatar_url` is always `null` — `fintra_back_users` has no avatar column yet. The key is present so the frontend contract does not change when one is added.
* `pdf_previews.english_pdf_url` / `bangla_pdf_url` are `null` when that language was never uploaded (the store methods save an empty string for a skipped PDF), so the UI can grey out the missing chip.
* `report_name` is the generated `report_title` verbatim, without a `.pdf` suffix.
* `category_counts` honours `search` but **ignores** `category`, so every tab keeps its badge while one tab is selected. Categories with zero reports are still listed.

---

## Success response (200)

```json
{
  "status": true,
  "data": [
    {
      "id": 7,
      "report_name": "BATBC_Q4_2026_2026-09-11",
      "sub_heading": "Robust FY26 financial performance led by strong volume growth.",
      "report_type": null,
      "category": { "id": 1, "name": "Company Analysis" },
      "uploaded_at": "11 Sep 2026, 10:45 PM",
      "uploaded_by": { "id": 5, "name": "Saad Arnob", "avatar_url": null },
      "pdf_previews": {
        "english_pdf_url": "http://localhost/fintraBackend/fi_adm/public/storage/research_reports/abc123.pdf",
        "bangla_pdf_url": "http://localhost/fintraBackend/fi_adm/public/storage/research_reports/def456.pdf"
      },
      "tags": ["#equity", "#tobacco", "#dividend"]
    },
    {
      "id": 4,
      "report_name": "Weekly Market Wrap-up_2026-09-06",
      "sub_heading": null,
      "report_type": { "id": 3, "name": "Weekly Market Wrap-up" },
      "category": { "id": 3, "name": "Market Updates" },
      "uploaded_at": "07 Sep 2026, 12:00 AM",
      "uploaded_by": { "id": 5, "name": "Saad Arnob", "avatar_url": null },
      "pdf_previews": {
        "english_pdf_url": "http://localhost/fintraBackend/fi_adm/public/storage/research_reports/ghi789.pdf",
        "bangla_pdf_url": null
      },
      "tags": ["#weekly", "#wrapup", "#dsex"]
    }
  ],
  "category_counts": {
    "all": 7,
    "categories": [
      { "id": 1, "name": "Company Analysis", "count": 1 },
      { "id": 2, "name": "Sector Analysis", "count": 1 },
      { "id": 3, "name": "Market Updates", "count": 1 },
      { "id": 4, "name": "Daily News", "count": 1 },
      { "id": 5, "name": "Macro Analysis", "count": 2 },
      { "id": 6, "name": "Special Feature", "count": 1 }
    ]
  },
  "pagination": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 15,
    "total": 7
  }
}
```

An empty result still returns `200` with `data: []` and the full `category_counts` block, so an unmatched search does not break the tabs.

---

## Validation error (422)

```json
{
  "status": false,
  "message": "Validation failed",
  "errors": {
    "category": ["The selected research category is invalid."],
    "per_page": ["Per page must not exceed 100."]
  }
}
```

## Server error (500)

```json
{
  "status": false,
  "message": "Failed to fetch research history",
  "error": "..."
}
```

---

## Postman setup

1. Method: **GET**
2. URL: `{{base_url}}/research-company/research-history-index`
3. Authorization: **Bearer Token** -> paste JWT
4. Headers: `Accept: application/json`
5. Params (all optional):

| Key | Example value |
|---|---|
| `category` | `1` or `all` |
| `search` | `budget` |
| `per_page` | `25` |
| `page` | `2` |

---

## route_apis insert query

```sql
INSERT INTO `route_apis` (`api_id`, `name`, `url`, `controller`, `function`, `prefix`, `method`, `details`, `api_activity_flag`, `created_by`, `create_date`, `create_time`, `update_by`, `update_date`, `update_time`, `created_at`, `updated_at`) VALUES
(NULL, 'research-history-index', 'research-history-index', 'DiverseResearchController', 'getResearchHistory', 'research-company', 'GET', 'research-history-index API', 'R', '5', '2026-09-28', '12:40:00', NULL, NULL, NULL, '2026-09-28 12:40:00', '2026-09-28 12:40:00');
```
