# Employee Feedback & Suggestions — Frontend Integration Guide

## Overview

Two feedback flows share the same `feedbacks` table but serve different purposes:

| Flow | Description | Endpoints |
|---|---|---|
| **Service Rating** (existing) | Employee rates a specific HR service transaction (CSAT) | `v1/feedbacks` |
| **Suggestion / General Feedback** (new) | Employee submits free-form suggestions/complaints to HR | `v2/employee/{employee_no}/feedbacks` |

This guide covers the **Suggestion / General Feedback** flow.

---

## Employee-Facing (ESS) — V2 Endpoints

### Submit Feedback

```http
POST /api/v2/employee/{employee_no}/feedbacks
```

**Request body:**

| Field | Type | Required | Description |
|---|---|---|---|
| `subject` | string | **yes** | Short title of the feedback |
| `incident_details` | string | **yes** | Main feedback content / message body |
| `recommendation` | string | no | Optional suggestion or proposed solution |
| `is_anonymous` | boolean | no (default: false) | When `true`, HR sees content but NOT the submitter name |

**Example request (anonymous):**

```json
{
  "subject": "Parking concerns",
  "incident_details": "The parking lot is too small for the number of employees.",
  "recommendation": "Consider allocating more space or implementing a shifting schedule.",
  "is_anonymous": true
}
```

**Example request (non-anonymous):**

```json
{
  "subject": "Suggestion for office supplies",
  "incident_details": "We need more whiteboard markers in Conference Room B."
}
```

**Success response (200):**

```json
{
  "success": true,
  "message": "Feedback submitted successfully"
}
```

**Error response (404 — unknown employee number):**

```json
{
  "success": false,
  "message": "Employee not found"
}
```

**Validation error (422):**

```json
{
  "message": "The subject field is required.",
  "errors": {
    "subject": ["The subject field is required."],
    "incident_details": ["The incident details field is required."]
  }
}
```

---

## HR-Facing (Admin) — V2 Endpoints

All HR endpoints are under `v2/employee/all/`.

### List All Feedback

```http
GET /api/v2/employee/all/feedbacks
```

**Response (200):**

```json
{
  "success": true,
  "message": "Data retrieved",
  "data": [
    {
      "id": 1,
      "employee_id": 42,
      "is_anonymous": false,
      "subject": "Suggestion for improvement",
      "incident_details": "I think we should have a better parking area.",
      "recommendation": "Consider allocating more space.",
      "status": "pending",
      "actioned_by": null,
      "actioned_at": null,
      "action_notes": null,
      "created_at": "2026-05-21T10:00:00.000000Z",
      "updated_at": "2026-05-21T10:00:00.000000Z",
      "service_type_id": 1,
      "other_service_type": null,
      "hr_officer_id": null,
      "transaction_date": null,
      "transaction_time": null,
      "service_timelines": null,
      "service_quality": null,
      "attitude": null,
      "overall_satisfaction": null
    }
  ]
}
```

**Anonymous feedback behavior:** When `is_anonymous` is `true`, the response still includes `employee_id` (internal audit) — your frontend should **hide the employee name/identity** when rendering feedbacks with `is_anonymous === true`. The API returns employee data inline; there is no additional employee resource endpoint in the feedback response.

### View Single Feedback

```http
GET /api/v2/employee/all/feedbacks/{id}
```

Returns the same shape as above, scoped to one record.

### Mark as Reviewed

```http
PATCH /api/v2/employee/all/feedbacks/{id}/review
```

No request body needed.

**Success (200):**

```json
{
  "success": true,
  "message": "Feedback marked as reviewed"
}
```

**Status guard (400 — already actioned):**

```json
{
  "success": false,
  "message": "Cannot review feedback with status 'actioned'"
}
```

### Mark as Actioned

```http
PATCH /api/v2/employee/all/feedbacks/{id}/action
```

**Request body:**

| Field | Type | Required | Description |
|---|---|---|---|
| `actioned_by` | integer (employee_id) | no | Which HR employee actioned it |
| `action_notes` | string | no | HR notes about the action taken |

**Success (200):**

```json
{
  "success": true,
  "message": "Feedback marked as actioned"
}
```

**Status guard (400 — already actioned):**

```json
{
  "success": false,
  "message": "Feedback is already actioned"
}
```

---

## V1 Endpoints (New Additions)

The existing v1 `feedbacks` resource got new methods:

| Method | Route | Purpose |
|---|---|---|
| GET | `/api/v1/feedbacks/employee/{employeeId}` | Get feedbacks by employee ID |
| PATCH | `/api/v1/feedbacks/{id}/review` | Mark as reviewed |
| PATCH | `/api/v1/feedbacks/{id}/action` | Mark as actioned |

These follow the same request/response shape as their V2 equivalents above.

---

## Status Lifecycle

```
pending  ──►  reviewed  ──►  actioned
  ▲                              ▲
  └────  cannot go back  ───────┘
```

- **pending** — Newly submitted, not yet seen by HR
- **reviewed** — HR has seen/acknowledged it
- **actioned** — HR has taken action (terminal state)

Once `actioned`, it cannot be reviewed or actioned again.

---

## Frontend UI Requirements

### ESS — Employee Feedback Form

1. **Subject** — text input (max 255 chars, required)
2. **Message / Details** — textarea (required)
3. **Recommendation** — textarea (optional)
4. **Anonymous toggle** — checkbox or switch; when enabled, show a notice: *"Your identity will be hidden from HR"*
5. **Submit button** — shows confirmation message on success: *"Feedback submitted successfully"*
6. **Validation** — client-side for `subject` and `incident_details` required fields

### ESS — My Feedback History (optional enhancement)

Use `GET /api/v1/feedbacks/employee/{employeeId}` to show the employee their past submissions and their current status.

### HR — Feedback Management View

1. **Inbox / List** — shows all feedbacks with columns: Subject, Status, Anonymous (badge), Submitted Date
2. **Detail view** — full feedback content. If `is_anonymous === true`, hide the employee name/label
3. **Review button** — marks status → `reviewed`
4. **Action form** — opens with notes textarea, marks status → `actioned`
5. **Status indicator** — show current status with color coding (pending=gray, reviewed=blue, actioned=green)

### Anonymous Display Rule

| is_anonymous | Show employee name? | Show content? |
|---|---|---|
| `false` | Yes | Yes |
| `true` | **No** — show "Anonymous" instead | Yes |

---

## Response Shape Reference

All endpoints return:

```json
{
  "success": true|false,
  "message": "...",
  "data": { ... } | [ ... ]     // omitted on errors
}
```

HTTP status codes:
- `200` — success
- `400` — business logic error (check `success` field)
- `404` — resource not found
- `422` — validation error
- `500` — server error

---

## Database Fields Reference

New/added fields on the `feedbacks` table:

| Column | Type | Default | Purpose |
|---|---|---|---|
| `is_anonymous` | boolean | `false` | Hides submitter identity from HR |
| `subject` | string | nullable | Short title of the feedback |
| `status` | string(50) | `'pending'` | pending → reviewed → actioned |
| `actioned_by` | integer FK | nullable | Who in HR actioned it |
| `actioned_at` | timestamp | nullable | When it was actioned |
| `action_notes` | text | nullable | HR internal action notes |
