# Employee Attendance Break APIs

These authenticated APIs let the employee app retrieve break settings for the
employee's active client assignment, then start and end attendance breaks.

## Base URL

```text
https://fwg-malaysia.dextragroups.com
```

Use a single slash between the host and `/api`; for example,
`https://fwg-malaysia.dextragroups.com/api/v1/...`.

## Authentication

All endpoints in this document require the employee's Laravel Sanctum bearer
token:

```http
Authorization: Bearer <employee-token>
Accept: application/json
```

Obtain a token using the employee login flow documented in
[Employee_Patrol_Login_API.md](./Employee_Patrol_Login_API.md).

## 1. Get break details

```http
GET /api/v1/employee/attendance/break-details
```

The optional `clientCode` query parameter selects one of the employee's active
client assignments. When omitted, the API continues to use the employee's
first active assignment.

```http
GET /api/v1/employee/attendance/break-details?clientCode=FwgC000013
```

The API passes that assignment's client code to the .NET `GetClientBreakList`
API and returns only its configured breaks. A requested client code that is
not linked to the employee's active assignments is rejected.

### Test with Postman

1. Obtain an employee bearer token using the employee login API. Use the same
   employee whose active assignment is linked to the client you want to test.
2. Create a `GET` request to:

   ```text
   https://fwg-malaysia.dextragroups.com/api/v1/employee/attendance/break-details?clientCode=FwgC000013
   ```

   Replace the host with your environment's base URL and replace
   `FwgC000013` with the assigned client's actual code. For local development,
   for example, use
   `http://127.0.0.1:8000/api/v1/employee/attendance/break-details?clientCode=FwgC000013`.
3. Set **Authorization** to **Bearer Token** and paste the employee token.
   Alternatively, add these headers:

   ```http
   Authorization: Bearer <employee-token>
   Accept: application/json
   ```

4. Send the request. A successful response is HTTP 200 and includes
   `data.client_code` and only that client's configured `data.breaks`.

To test the default assignment selection, omit `?clientCode=...`; the API uses
the employee's first active assignment. Never use a client code that is not
linked to the employee when testing this employee endpoint.

### Live deployment checklist

- Deploy the application code containing the selected-client endpoint change.
- Confirm the employee has an active assignment with the correct `client_code`,
  or a linked client record whose `code` matches it. The assignment must be
  within its start and end dates.
- Ensure the live application server can reach the configured upstream
  `GetClientBreakList` URL. The default URL is
  `http://124.217.236.37:63399/api/master/GetClientBreakList`; if the
  environment uses a different URL, set `DOTNET_CLIENT_BREAKS_API_URL` and
  clear/reload Laravel's cached configuration after changing it.
- Repeat the Postman request against the live host using a valid live employee
  token. Local test data and local code changes do not update the live server.

### Successful response

**HTTP 200**

```json
{
  "success": true,
  "data": {
    "client_code": "FwgC000013",
    "breaks": [
      {
        "sort_order": 1,
        "name": "Break 1",
        "break_type": "lunch",
        "break_hours": 0.5,
        "duration_minutes": 30,
        "duration_hours": 0,
        "duration_remainder_minutes": 30
      },
      {
        "sort_order": 2,
        "name": "Break 2",
        "break_type": "break_1",
        "break_hours": 1,
        "duration_minutes": 60,
        "duration_hours": 1,
        "duration_remainder_minutes": 0
      }
    ]
  }
}
```

Only breaks present in the upstream response are returned. The upstream
response contains `SortOrder` and `BreakHours` but no break name, so the API
uses `Break {SortOrder}` as the display name (or an upstream name if supplied).
Breaks are sorted by `sort_order`. `break_type` retains its established value
for compatibility with existing break-start and break-end requests.
`duration_minutes` is the total duration; `duration_hours` and
`duration_remainder_minutes` split that duration into hours and remaining
minutes. Use the returned `break_type` when starting and ending a break.

The upstream API currently supplies duration and order, not scheduled start or
end clock times.

### Errors

| HTTP status | Meaning |
|---|---|
| 401 | Missing or invalid bearer token. |
| 403 | No active client assignment, or the selected client is not assigned to this employee. |
| 422 | Invalid `clientCode`, or the matching assignment has no client code. |
| 502 | The upstream break API is unavailable or returned invalid data. |

If the request without `clientCode` returns HTTP 422, the employee has an
active assignment but it has no client code and is not linked to a client with
a code. Have an OBMS administrator correct the assignment, then retry. If a
request with `clientCode` returns HTTP 403, verify that the exact code belongs
to one of the employee's active assignments.

## 2. Start a break

```http
POST /api/v1/employee/attendance/break-start
Content-Type: application/json
```

### Request body

| Field | Type | Required | Description |
|---|---|---:|---|
| `latitude` | number | Yes | Current latitude, from -90 through 90. |
| `longitude` | number | Yes | Current longitude, from -180 through 180. |
| `accuracy` | number | No | Location accuracy in meters; must be zero or greater. |
| `break_type` | string | Yes | `lunch`, `break_1`, `break_2`, `break_3`, or legacy `break`. |
| `remarks` | string | No | Notes, maximum 255 characters. |

Use the matching `break_type` returned from **Get break details**. For example:

```json
{
  "latitude": 3.139,
  "longitude": 101.6869,
  "accuracy": 10,
  "break_type": "lunch",
  "remarks": "Lunch"
}
```

### Successful response

**HTTP 200**

```json
{
  "success": true,
  "message": "Break started successfully",
  "data": {
    "break_id": 123,
    "break_type": "lunch",
    "start_time": "2026-10-22T12:30:00.000000Z"
  }
}
```

The employee must have clocked in and must not already have an open break.
Starting a break after clock-out is not allowed.

## 3. End a break

```http
POST /api/v1/employee/attendance/break-end
Content-Type: application/json
```

The request body uses the same fields and validation as **Start a break**.
Send the break's `break_type` with the employee's current location. For
example:

```json
{
  "latitude": 3.139,
  "longitude": 101.6869,
  "accuracy": 10,
  "break_type": "lunch"
}
```

### Successful response

**HTTP 200**

```json
{
  "success": true,
  "message": "Break ended successfully",
  "data": {
    "break_id": 123,
    "break_type": "lunch",
    "start_time": "2026-10-22T12:30:00.000000Z",
    "end_time": "2026-10-22T13:00:00.000000Z",
    "duration_minutes": 30
  }
}
```

An active break must exist, and the employee must not have clocked out.
`break_type` is required and recorded with the break event.

## Common error responses

**HTTP 422 — invalid or missing request fields**

```json
{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "break_type": [
      "The selected break type is invalid."
    ]
  }
}
```

**HTTP 400 — attendance state prevents the operation**

The `message` explains the condition, for example:

```json
{
  "success": false,
  "message": "You must clock in before starting a break"
}
```

For ending a break, an example is:

```json
{
  "success": false,
  "message": "No active break found. Please start a break first."
}
```

## Example: call the break-details endpoint in PowerShell

After obtaining a token through employee login:

```powershell
$token = "<employee-token>"

Invoke-RestMethod `
  -Uri "https://fwg-malaysia.dextragroups.com/api/v1/employee/attendance/break-details" `
  -Method Get `
  -Headers @{
    Authorization = "Bearer $token"
    Accept = "application/json"
  } |
  ConvertTo-Json -Depth 8
```
