# Research Report Delete API — Curl / Postman

**Controller:** `DiverseResearchController`
**Method:** `destroy`
**Route name:** `research-report-delete/{id}`
**Middleware:** `jwt.auth`, `check.token`, `dynamic.permission`
(assign this route to the back-office user's role in route-API permissions first, or the request is rejected even for a valid admin)

Base URL (XAMPP local):

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

---

## Behaviour

* **Hard delete.** The `research_reports` row is removed permanently; there is no soft delete and no restore.
* **Pivot rows cascade.** `report_security`, `report_sector` and `report_tags` entries are removed by their `onDelete('cascade')` foreign keys.
* **Tags are kept.** Only the `report_tags` links go; the `tags` records stay available for other reports.
* **Uploaded files are removed** from the `public` disk: `featured_image_url`, `english_pdf_url`, `bangla_pdf_url`. Files are deleted **after** the database delete is committed, so a rolled-back transaction can never leave a surviving report whose PDFs are already gone.
* **Every deletion is recorded twice**: a row in `research_report_delete_log` and a line in `storage/logs/ResearchReportDelete.log`.

---

## 1. Delete a report

```bash
curl --location --request DELETE "http://localhost/fintraBackend/fi_adm/public/api/research-company/research-report-delete/17" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_JWT_TOKEN"
```

### Success (200)

```json
{
  "status": true,
  "message": "Research report deleted successfully",
  "data": {
    "report_id": 17,
    "report_title": "Monetary Policy Review_2026-09-28",
    "deleted_by": 59,
    "deleted_by_name": "Bijoy",
    "report_deleted_at": "2026-09-30 10:05:00"
  }
}
```

### Not found (404)

```json
{
  "status": false,
  "message": "Research report not found"
}
```

### Server error (500)

The transaction is rolled back, so the report and its files are left untouched.

```json
{
  "status": false,
  "message": "Failed to delete research report",
  "error": "..."
}
```

---

## Who deleted what

`deleted_by` comes from `$request->users_id`, the same authenticated back-office user id the store methods use for `created_by`. The name is looked up from `fintra_back_users` rather than taken from the request, so a spoofed `name` query parameter cannot poison the audit trail.

Neither `deleted_by` nor `report_created_by` has a foreign key, deliberately: the audit row must survive the user being deleted from `fintra_back_users`, which is the same reasoning used for `research_reports.created_by`.

### Audit table row

```sql
SELECT report_id, report_title, category_name, report_type_name,
       report_created_by, deleted_by, deleted_by_name, report_deleted_at
FROM research_report_delete_log
ORDER BY report_deleted_at DESC;
```

| Column | Notes |
|---|---|
| `report_id` | id of the deleted report (no FK — the row is gone) |
| `report_title` | title as it was at deletion time |
| `category_id` / `category_name` | snapshot, so renaming a category later does not rewrite history |
| `report_type_id` / `report_type_name` | snapshot, nullable |
| `deleted_files` | comma-separated storage paths that were removed |
| `report_created_by` | `fintra_back_users.user_id` who uploaded it |
| `deleted_by` / `deleted_by_name` | `fintra_back_users.user_id` who deleted it, and their name |
| `report_deleted_at` | when the delete happened |

### Log file

`storage/logs/ResearchReportDelete.log`, via the `researchReportDelete` channel added to `config/logging.php`:

```text
[2026-09-30 10:05:00] local.INFO: Research report deleted {"report_id":17,"report_title":"Monetary Policy Review_2026-09-28","category_id":3,"category_name":"Macro Analysis","report_type_id":5,"report_type_name":"Monetary Policy Statement Notes","deleted_files":"research_reports/Vlht...pdf","report_created_by":5,"deleted_by":59,"deleted_by_name":"Bijoy","report_deleted_at":"2026-09-30T10:05:00.000000Z"}
```

---

## Postman setup

1. Method: **DELETE**
2. URL: `{{base_url}}/research-company/research-report-delete/17`
3. Authorization: **Bearer Token** -> paste JWT
4. Headers: `Accept: application/json`
5. No body required.

---

## Create the audit table

Migration file: `database/migrations/2026_09_30_000001_create_research_report_delete_log_table.php`.

Run it with:

```bash
php artisan migrate --path=database/migrations/2026_09_30_000001_create_research_report_delete_log_table.php
```

Or apply it by hand:

```sql
CREATE TABLE `research_report_delete_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `report_id` BIGINT UNSIGNED NOT NULL,
  `report_title` VARCHAR(255) NULL,
  `category_id` BIGINT UNSIGNED NULL,
  `category_name` VARCHAR(255) NULL,
  `report_type_id` BIGINT UNSIGNED NULL,
  `report_type_name` VARCHAR(255) NULL,
  `deleted_files` TEXT NULL COMMENT 'storage paths removed with the report',
  `report_created_by` INT UNSIGNED NULL COMMENT 'fintra_back_users.user_id who uploaded',
  `deleted_by` INT UNSIGNED NULL COMMENT 'fintra_back_users.user_id who deleted',
  `deleted_by_name` VARCHAR(255) NULL,
  `report_deleted_at` TIMESTAMP NOT NULL,
  `created_at` TIMESTAMP NULL,
  `updated_at` TIMESTAMP NULL,
  PRIMARY KEY (`id`),
  KEY `research_report_delete_log_report_id_index` (`report_id`),
  KEY `research_report_delete_log_deleted_by_index` (`deleted_by`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

---

## 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-report-delete/{id}', 'research-report-delete/{id}', 'DiverseResearchController', 'destroy', 'research-company', 'DELETE', 'research-report-delete/{id} API', 'R', '5', '2026-09-30', '10:00:00', NULL, NULL, NULL, '2026-09-30 10:00:00', '2026-09-30 10:00:00');
```
