# Employment Action Notification — Frontend API Reference

## Overview

In-app notification system for employees when HR approves/rejects their record changes (employment actions). Notifications are stored in the `employee_notifications` table (shared with ms-timekeeping) and retrieved via the V2 API.

---

## Endpoints

All endpoints are prefixed with `/api/v2` and require the standard API authentication (service token / JWT).

### 1. List Notifications

```
GET /api/v2/employee/{employee_id}/notifications?limit=50
```

Fetch notifications for an employee, ordered newest first.

**Parameters:**
| Name | Type | In | Description |
|------|------|----|-------------|
| `employee_id` | integer | path | Employee ID from the `employees` table |
| `limit` | integer | query | Max results (default: 50, max: 100) |

**Response `200 OK`:**
```json
{
  "success": true,
  "message": "Notifications retrieved successfully",
  "data": [
    {
      "id": 1,
      "employee_id": 123,
      "type": "work_experience_approved",
      "message": "Your work experience record has been approved.",
      "reference_type": "App\\Models\\WorkExperienceRecordHistory",
      "reference_id": 42,
      "is_read": false,
      "created_at": "2026-06-01T10:30:00.000000Z",
      "updated_at": "2026-06-01T10:30:00.000000Z"
    }
  ]
}
```

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

### 2. Get Unread Count

```
GET /api/v2/employee/{employee_id}/notifications/unread-count
```

Used by the frontend to show a badge indicator (e.g., red dot on bell icon).

**Response `200 OK`:**
```json
{
  "success": true,
  "message": "Unread count retrieved successfully",
  "data": {
    "unread_count": 3
  }
}
```

### 3. Mark Single Notification as Read

```
PATCH /api/v2/employee/{employee_id}/notifications/{id}/read
```

**Response `200 OK`:**
```json
{
  "success": true,
  "message": "Notification marked as read"
}
```

**Error `404`** (notification not found):
```json
{
  "success": false,
  "message": "Notification not found"
}
```

### 4. Mark All Notifications as Read

```
PATCH /api/v2/employee/{employee_id}/notifications/read-all
```

Marks every unread notification for this employee as read.

**Response `200 OK`:**
```json
{
  "success": true,
  "message": "5 notification(s) marked as read",
  "data": {
    "updated_count": 5
  }
}
```

---

## Notification Types

The `type` field identifies what triggered the notification. The frontend can use this to show custom icons or colors per type.

| Type | Triggered When | Icon Suggestion |
|------|---------------|----------------|
| `educational_record_approved` | Educational record approved | ✅ / 🎓 |
| `educational_record_rejected` | Educational record rejected | ❌ / 🎓 |
| `eligibility_record_approved` | Eligibility/CSC record approved | ✅ / 📜 |
| `eligibility_record_rejected` | Eligibility/CSC record rejected | ❌ / 📜 |
| `work_experience_approved` | Work experience record approved | ✅ / 💼 |
| `work_experience_rejected` | Work experience record rejected | ❌ / 💼 |
| `voluntary_work_approved` | Voluntary work record approved | ✅ / 🤝 |
| `voluntary_work_rejected` | Voluntary work record rejected | ❌ / 🤝 |
| `learning_development_approved` | L&D record approved | ✅ / 📚 |
| `learning_development_rejected` | L&D record rejected | ❌ / 📚 |
| `other_information_approved` | Other info record approved | ✅ / 📋 |
| `other_information_rejected` | Other info record rejected | ❌ / 📋 |
| `employee_deactivated` | Account deactivated | 🔒 |
| `employee_activated` | Account reactivated | 🔓 |

---

## Notification Lifecycle

1. **Creation** — Notification is inserted when HR performs approval/rejection via the HR dashboard or activate/deactivate actions.
2. **Unread state** (`is_read: false`) — The notification badge shows the count of unread items.
3. **Read state** (`is_read: true`) — After the employee views the notification (either individually or "mark all as read").
4. **No expiry/deletion** — Notifications persist indefinitely. The frontend may choose to only show recent N items and paginate older ones.

---

## Field Reference

| Field | Type | Description |
|-------|------|-------------|
| `id` | int | Primary key |
| `employee_id` | integer | Maps to `employees.id` in ms-pds |
| `type` | string | Notification type (see table above) |
| `message` | string | Human-readable message |
| `reference_type` | string? | Fully-qualified class name of the history record (e.g., `App\Models\WorkExperienceRecordHistory`) |
| `reference_id` | int? | ID of the history record |
| `is_read` | boolean | `false` = unread, `true` = read |
| `created_at` | timestamp | When the notification was created (effective date) |
| `updated_at` | timestamp | Last update timestamp |

---

## Frontend Integration Checklist

- [ ] Call `GET .../notifications` on employee profile/landing page load
- [ ] Call `GET .../notifications/unread-count` for badge display in nav/header
- [ ] Call `PATCH .../notifications/{id}/read` when user clicks/taps a notification
- [ ] Call `PATCH .../notifications/read-all` from a "Mark all as read" button
- [ ] Use `type` field to show contextual icons (see Notification Types table)
- [ ] Poll `unread-count` periodically (e.g., every 30-60s) or use the WebSocket event if available

---

## Notification Triggers (Backend)

| Action | Notification Created |
|--------|---------------------|
| HR approves educational record | `educational_record_approved` |
| HR rejects educational record | `educational_record_rejected` |
| HR approves eligibility record | `eligibility_record_approved` |
| HR rejects eligibility record | `eligibility_record_rejected` |
| HR approves work experience | `work_experience_approved` |
| HR rejects work experience | `work_experience_rejected` |
| HR approves voluntary work | `voluntary_work_approved` |
| HR rejects voluntary work | `voluntary_work_rejected` |
| HR approves L&D record | `learning_development_approved` |
| HR rejects L&D record | `learning_development_rejected` |
| HR approves other info record | `other_information_approved` |
| HR rejects other info record | `other_information_rejected` |
| Admin deactivates employee | `employee_deactivated` |
| Admin reactivates employee | `employee_activated` |
