# Complete API Endpoints Reference Guide

This is a comprehensive guide of all available API endpoints for the Attendance Management System, organized by functionality and authentication requirements.

## Table of Contents
1. [Authentication & Response Format](#authentication--response-format)
2. [Public Endpoints (No Authentication)](#public-endpoints-no-authentication)
3. [Protected Endpoints (JWT Authentication Required)](#protected-endpoints-jwt-authentication-required)
4. [Data Models & Relationships](#data-models--relationships)
5. [Error Handling](#error-handling)
6. [Mobile Integration Guide](#mobile-integration-guide)

---

## Authentication & Response Format

### Authentication Method
- **Type**: JWT (JSON Web Token)
- **Guard**: `api`
- **Header Format**: `Authorization: Bearer {token}`

### Standard Response Format

**Success Response:**
```json
{
  "success": true,
  "message": "Operation successful",
  "data": {
    // Response data here
  }
}
```

**Error Response:**
```json
{
  "success": false,
  "message": "Error message",
  "data": null
}
```

---

## PUBLIC ENDPOINTS (No Authentication)

### Authentication

#### POST /login
**Description**: Authenticate user and receive JWT token
**Authentication**: None
**Request Body**:
```json
{
  "email": "admin@example.com",
  "password": "password"
}
```
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Successfully login",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}
```

---

### Attendance (Mobile App - Public)

#### POST /public/attendance/join
**Description**: Record check-in or check-out attendance with fingerprint verification
**Authentication**: None (Public - Fingerprint-based)
**Content-Type**: `multipart/form-data`
**Request Parameters**:
- `email` (required, string): Employee email
- `fingerprint_data` (required, string): Base64-encoded fingerprint data
- `type` (optional, string): `check_in` (default) or `check_out`
- `photo` (optional, file): Image file (jpeg, png, jpg, max 5MB)
- `location_latitude` (optional, number): GPS latitude
- `location_longitude` (optional, number): GPS longitude

**Response**: 201 Created
```json
{
  "success": true,
  "message": "Check-in successful",
  "data": {
    "attendance": {
      "id": 1,
      "id_employee": 1,
      "date": "2025-11-11",
      "check_in": "08:30:45",
      "check_out": null,
      "status": "present",
      "location_in": "-6.1234,106.5678",
      "location_out": null,
      "photo_check_in": "attendances/1/filename.jpg",
      "photo_check_out": null
    },
    "working_hours": {
      "within_hours": true,
      "current_time": "08:30:45",
      "work_start": "08:00:00",
      "work_end": "17:00:00",
      "message": "Within working hours"
    },
    "fingerprint_similarity": "98%"
  }
}
```

**Error Cases**:
- `400`: Already checked in/out
- `401`: Fingerprint verification failed
- `403`: Employee not enabled for attendance
- `404`: Employee not found
- `500`: Server error

---

#### POST /public/attendance/register-fingerprint
**Description**: Register employee fingerprint for first-time setup
**Authentication**: None
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "email": "john@example.com",
  "fingerprint_data": "YWJjZGVmZ2hpamtsbW5vcA=="
}
```

**Response**: 201 Created
```json
{
  "success": true,
  "message": "Fingerprint registered",
  "data": {
    "employee_id": 1,
    "fingerprint_registered": true,
    "message": "Fingerprint registered successfully"
  }
}
```

**Error Cases**:
- `400`: Validation failed
- `404`: Employee not found
- `500`: Server error

---

#### GET /public/employee
**Description**: Get employee information by email (for mobile app setup)
**Authentication**: None
**Query Parameters**:
- `email` (required, string): Employee email

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Employee found",
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "company": "ABC Company",
    "department": "IT",
    "fingerprint_registered": true
  }
}
```

**Error Cases**:
- `400`: Validation failed
- `404`: Employee not found
- `500`: Server error

---

## PROTECTED ENDPOINTS (JWT Authentication Required)

All protected endpoints require the header: `Authorization: Bearer {jwt_token}`

---

### Authentication Management

#### GET /me
**Description**: Get current authenticated user information
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Successfully fetched user data",
  "data": {
    "id": 1,
    "email": "admin@example.com",
    "name": "Admin User",
    "created_at": "2025-11-01T10:00:00Z"
  }
}
```

---

#### POST /logout
**Description**: Logout and invalidate JWT token
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Successfully logged out",
  "data": null
}
```

---

#### POST /refresh
**Description**: Refresh JWT token
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Token refreshed successfully",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}
```

---

### Attendance Management

#### GET /attendance
**Description**: List all attendance records with filtering and pagination
**Authentication**: JWT (required)
**Query Parameters**:
- `page` (optional, integer): Page number (default: 1)
- `per_page` (optional, integer): Records per page (default: 10)
- `search` (optional, string): Search by employee name/email
- `date_from` (optional, string): Filter from date (YYYY-MM-DD)
- `date_to` (optional, string): Filter to date (YYYY-MM-DD)
- `id_employee` (optional, integer): Filter by employee ID
- `status` (optional, string): Filter by status (present, absent, late, approved_by_admin)

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Attendances fetched successfully",
  "data": {
    "data": [
      {
        "id": 1,
        "id_employee": 1,
        "date": "2025-11-11",
        "check_in": "08:30:45",
        "check_out": "17:30:00",
        "status": "present",
        "location_in": "-6.1234,106.5678",
        "location_out": "-6.1240,106.5685",
        "photo_check_in": "attendances/1/photo1.jpg",
        "photo_check_out": "attendances/1/photo2.jpg",
        "employee": {
          "id": 1,
          "name": "John Doe",
          "email": "john@example.com",
          "company": {
            "id": 1,
            "name": "ABC Company"
          },
          "department": {
            "id": 1,
            "name": "IT"
          }
        },
        "created_at": "2025-11-11T08:30:45Z"
      }
    ],
    "current_page": 1,
    "total": 150,
    "per_page": 10,
    "last_page": 15
  }
}
```

---

#### GET /attendance/{id}
**Description**: Get single attendance record details
**Authentication**: JWT (required)
**URL Parameters**:
- `id` (required, integer): Attendance record ID

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Attendance fetched successfully",
  "data": {
    "id": 1,
    "id_employee": 1,
    "date": "2025-11-11",
    "check_in": "08:30:45",
    "check_out": "17:30:00",
    "status": "present",
    "location_in": "-6.1234,106.5678",
    "location_out": "-6.1240,106.5685",
    "photo_check_in": "attendances/1/photo1.jpg",
    "photo_check_out": "attendances/1/photo2.jpg",
    "employee": {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "company": {
        "id": 1,
        "name": "ABC Company"
      },
      "department": {
        "id": 1,
        "name": "IT"
      }
    }
  }
}
```

**Error Cases**:
- `404`: Attendance not found

---

#### POST /attendance/bypass
**Description**: Create or modify attendance record by admin (bypass fingerprint)
**Authentication**: JWT (required)
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "id_employee": 1,
  "date": "2025-11-09",
  "type": "full",
  "manual_check_in": "08:00:00",
  "manual_check_out": "17:00:00",
  "reason": "Late registration due to system error"
}
```

**Parameters**:
- `id_employee` (required, integer): Employee ID
- `date` (required, string): Attendance date (YYYY-MM-DD)
- `type` (required, string): `check_in`, `check_out`, or `full`
- `manual_check_in` (optional, string): Check-in time (HH:MM:SS)
- `manual_check_out` (optional, string): Check-out time (HH:MM:SS)
- `reason` (optional, string): Reason for bypass (max 500 chars)

**Response**: 201 Created
```json
{
  "success": true,
  "message": "Attendance bypass recorded successfully",
  "data": {
    "attendance": {
      "id": 2,
      "id_employee": 1,
      "date": "2025-11-09",
      "check_in": "08:00:00",
      "check_out": "17:00:00",
      "status": "approved_by_admin"
    },
    "bypass": {
      "id": 1,
      "id_employee": 1,
      "id_attendance": 2,
      "id_admin": 1,
      "type": "full",
      "reason": "Late registration due to system error",
      "status": "approved"
    }
  }
}
```

---

### Dashboard & Analytics

#### GET /dashboard/statistics
**Description**: Get comprehensive dashboard statistics
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Dashboard statistics fetched successfully",
  "data": {
    "statistics": {
      "total_employees": 50,
      "present_today": 48,
      "absent_today": 2,
      "on_leave_today": 0
    },
    "recent_attendances": [
      {
        "id": 1,
        "employee_name": "John Doe",
        "employee_id": 1,
        "department": "IT",
        "check_in_time": "08:30 AM",
        "check_out_time": "05:30 PM",
        "status": "present",
        "created_at": "2025-11-11 08:30:00"
      }
    ],
    "attendance_stats": {
      "total_working_days": 22,
      "total_employees_active": 50,
      "avg_attendance_rate": 94.5,
      "late_arrivals": 3
    },
    "employees_by_company": [
      {
        "count": 30,
        "company": "ABC Company"
      }
    ],
    "employees_by_department": [
      {
        "count": 15,
        "department": "IT"
      }
    ],
    "current_date": "2025-11-11",
    "current_time": "2025-11-11 14:30:00"
  }
}
```

---

#### GET /dashboard/attendance-summary
**Description**: Get attendance summary by date range
**Authentication**: JWT (required)
**Query Parameters**:
- `start_date` (optional, string): Start date (YYYY-MM-DD, default: first day of month)
- `end_date` (optional, string): End date (YYYY-MM-DD, default: today)

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Attendance summary fetched successfully",
  "data": [
    {
      "date": "2025-11-01",
      "total_present": 48,
      "total_absent": 2,
      "total_checked": 50
    },
    {
      "date": "2025-11-02",
      "total_present": 47,
      "total_absent": 3,
      "total_checked": 50
    }
  ]
}
```

---

#### GET /dashboard/employee-attendance
**Description**: Get detailed attendance for specific employee
**Authentication**: JWT (required)
**Query Parameters**:
- `employee_id` (optional, integer): Employee ID (if not provided, shows all employees)
- `start_date` (optional, string): Start date (YYYY-MM-DD, default: first day of month)
- `end_date` (optional, string): End date (YYYY-MM-DD, default: today)

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Employee attendance fetched successfully",
  "data": {
    "attendances": [
      {
        "date": "2025-11-01",
        "employee_name": "John Doe",
        "check_in": "08:30:00",
        "check_out": "17:30:00",
        "status": "present",
        "is_present": true
      }
    ],
    "stats": {
      "total_days": 20,
      "present_count": 19,
      "absent_count": 1,
      "attendance_rate": 95.0
    }
  }
}
```

---

### Company Management (CRUD)

#### GET /companies
**Description**: List all companies with pagination and search
**Authentication**: JWT (required)
**Query Parameters**:
- `page` (optional, integer): Page number (default: 1)
- `per_page` (optional, integer): Records per page (default: 10)
- `search` (optional, string): Search by name, company number, or address

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Companies fetched successfully",
  "data": {
    "data": [
      {
        "id": 1,
        "no_company": "COMP001",
        "name": "ABC Company",
        "logo_company": "companies/logos/abc.png",
        "address": "123 Business Street",
        "longitude": 106.5678,
        "latitude": -6.1234,
        "created_at": "2025-11-01T10:00:00Z"
      }
    ],
    "current_page": 1,
    "total": 5,
    "per_page": 10
  }
}
```

---

#### POST /companies
**Description**: Create new company
**Authentication**: JWT (required)
**Content-Type**: `multipart/form-data`
**Request Parameters**:
- `no_company` (required, string): Unique company number
- `name` (required, string): Company name
- `logo_company` (optional, file): Logo file (jpeg, png, jpg, gif, webp, max 5MB)
- `address` (optional, string): Company address
- `longitude` (optional, number): Longitude coordinate
- `latitude` (optional, number): Latitude coordinate

**Response**: 201 Created
```json
{
  "success": true,
  "message": "Company created successfully",
  "data": {
    "id": 2,
    "no_company": "COMP002",
    "name": "XYZ Corporation",
    "logo_company": "companies/logos/xyz.png",
    "address": "456 Corporate Ave",
    "longitude": 106.6789,
    "latitude": -6.2345
  }
}
```

---

#### GET /companies/{id}
**Description**: Get single company with employees
**Authentication**: JWT (required)
**URL Parameters**:
- `id` (required, integer): Company ID

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Company fetched successfully",
  "data": {
    "id": 1,
    "no_company": "COMP001",
    "name": "ABC Company",
    "logo_company": "companies/logos/abc.png",
    "address": "123 Business Street",
    "longitude": 106.5678,
    "latitude": -6.1234,
    "employees": [
      {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "is_attendances": true
      }
    ]
  }
}
```

---

#### PUT /companies/{id}
**Description**: Update company
**Authentication**: JWT (required)
**Content-Type**: `multipart/form-data`
**URL Parameters**:
- `id` (required, integer): Company ID

**Request Parameters** (same as POST, all optional):
- `no_company` (optional, string)
- `name` (optional, string)
- `logo_company` (optional, file)
- `address` (optional, string)
- `longitude` (optional, number)
- `latitude` (optional, number)

**Response**: 200 OK

---

#### DELETE /companies/{id}
**Description**: Delete company (only if no employees)
**Authentication**: JWT (required)
**URL Parameters**:
- `id` (required, integer): Company ID

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Company deleted successfully",
  "data": null
}
```

**Error Cases**:
- `400`: Cannot delete company with employees

---

### Department Management (CRUD)

#### GET /departments
**Description**: List all departments with pagination and search
**Authentication**: JWT (required)
**Query Parameters**:
- `page` (optional, integer): Page number (default: 1)
- `per_page` (optional, integer): Records per page (default: 10)
- `search` (optional, string): Search by name or description
- `status` (optional, string): Filter by status (ENABLE, DISABLED)

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Departments fetched successfully",
  "data": {
    "data": [
      {
        "id": 1,
        "name": "IT",
        "description": "Information Technology",
        "status": "ENABLE",
        "created_at": "2025-11-01T10:00:00Z"
      }
    ],
    "current_page": 1,
    "total": 10,
    "per_page": 10
  }
}
```

---

#### POST /departments
**Description**: Create new department
**Authentication**: JWT (required)
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "name": "HR",
  "description": "Human Resources",
  "status": "ENABLE"
}
```

**Response**: 201 Created

---

#### GET /departments/{id}
**Description**: Get single department with employees
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Department fetched successfully",
  "data": {
    "id": 1,
    "name": "IT",
    "description": "Information Technology",
    "status": "ENABLE",
    "employees": [
      {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
      }
    ]
  }
}
```

---

#### PUT /departments/{id}
**Description**: Update department
**Authentication**: JWT (required)
**Request Body**: Same as POST (all optional)

**Response**: 200 OK

---

#### DELETE /departments/{id}
**Description**: Delete department (only if no employees)
**Authentication**: JWT (required)
**Error Cases**:
- `400`: Cannot delete department with employees

---

### Employee Management (CRUD)

#### GET /employees
**Description**: List all employees with pagination and filtering
**Authentication**: JWT (required)
**Query Parameters**:
- `page` (optional, integer): Page number (default: 1)
- `per_page` (optional, integer): Records per page (default: 10)
- `search` (optional, string): Search by name, email, or phone
- `id_company` (optional, integer): Filter by company ID
- `id_department` (optional, integer): Filter by department ID
- `is_attendances` (optional, boolean): Filter by attendance status

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Employees fetched successfully",
  "data": {
    "data": [
      {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "phone_number": "08123456789",
        "address": "123 Main Street",
        "profile_picture": "employees/1/profile.jpg",
        "is_attendances": true,
        "total_attendances": 45,
        "fingerprint_registered": true,
        "department": {
          "id": 1,
          "name": "IT"
        },
        "company": {
          "id": 1,
          "name": "ABC Company"
        }
      }
    ],
    "current_page": 1,
    "total": 50,
    "per_page": 10
  }
}
```

---

#### POST /employees
**Description**: Create new employee
**Authentication**: JWT (required)
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "id_company": 1,
  "id_department": 1,
  "name": "Jane Smith",
  "email": "jane@example.com",
  "phone_number": "08987654321",
  "address": "456 Oak Avenue",
  "profile_picture": null
}
```

**Response**: 201 Created

---

#### GET /employees/{id}
**Description**: Get single employee with all related data
**Authentication**: JWT (required)
**Response**: 200 OK
```json
{
  "success": true,
  "message": "Employee fetched successfully",
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "phone_number": "08123456789",
    "is_attendances": true,
    "total_attendances": 45,
    "fingerprint_registered": true,
    "department": {
      "id": 1,
      "name": "IT"
    },
    "company": {
      "id": 1,
      "name": "ABC Company"
    },
    "attendances": [
      {
        "id": 1,
        "date": "2025-11-11",
        "check_in": "08:30:45",
        "check_out": "17:30:00",
        "status": "present"
      }
    ],
    "workSchedules": [
      {
        "id": 1,
        "shift_name": "Morning",
        "start_time": "08:00:00",
        "end_time": "17:00:00"
      }
    ],
    "leaves": []
  }
}
```

---

#### PUT /employees/{id}
**Description**: Update employee
**Authentication**: JWT (required)
**Request Body** (all optional):
```json
{
  "id_company": 1,
  "id_department": 1,
  "name": "Jane Smith",
  "email": "jane@example.com",
  "phone_number": "08987654321",
  "is_attendances": true,
  "total_attendances": 50,
  "address": "456 Oak Avenue"
}
```

**Response**: 200 OK

---

#### DELETE /employees/{id}
**Description**: Delete employee (only if no attendance records)
**Authentication**: JWT (required)
**Error Cases**:
- `400`: Cannot delete employee with attendance records

---

### Work Schedule Management (CRUD)

#### GET /work-schedules
**Description**: List all work schedules with pagination and filtering
**Authentication**: JWT (required)
**Query Parameters**:
- `page` (optional, integer): Page number (default: 1)
- `per_page` (optional, integer): Records per page (default: 10)
- `search` (optional, string): Search by shift name or employee name
- `id_employee` (optional, integer): Filter by employee ID
- `shift_name` (optional, string): Filter by shift name

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Work schedules fetched successfully",
  "data": {
    "data": [
      {
        "id": 1,
        "id_employee": 1,
        "shift_name": "Morning Shift",
        "start_time": "08:00:00",
        "end_time": "17:00:00",
        "employee": {
          "id": 1,
          "name": "John Doe",
          "email": "john@example.com"
        },
        "created_at": "2025-11-01T10:00:00Z"
      }
    ],
    "current_page": 1,
    "total": 30,
    "per_page": 10
  }
}
```

---

#### POST /work-schedules
**Description**: Create new work schedule
**Authentication**: JWT (required)
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "id_employee": 1,
  "shift_name": "Evening Shift",
  "start_time": "14:00:00",
  "end_time": "23:00:00"
}
```

**Parameters**:
- `id_employee` (required, integer): Employee ID
- `shift_name` (required, string): Shift name
- `start_time` (required, string): Start time (HH:MM:SS)
- `end_time` (required, string): End time (HH:MM:SS, must be after start_time)

**Response**: 201 Created

---

#### GET /work-schedules/{id}
**Description**: Get single work schedule
**Authentication**: JWT (required)
**Response**: 200 OK

---

#### PUT /work-schedules/{id}
**Description**: Update work schedule
**Authentication**: JWT (required)
**Request Body** (all optional):
```json
{
  "id_employee": 1,
  "shift_name": "Night Shift",
  "start_time": "22:00:00",
  "end_time": "06:00:00"
}
```

**Response**: 200 OK

---

#### DELETE /work-schedules/{id}
**Description**: Delete work schedule
**Authentication**: JWT (required)
**Response**: 200 OK

---

### Maps Integration

#### POST /expand-maps-link
**Description**: Expand shortened Google Maps link and extract coordinates
**Authentication**: JWT (required)
**Content-Type**: `application/json`
**Request Body**:
```json
{
  "url": "https://maps.app.goo.gl/abc123def"
}
```

**Response**: 200 OK
```json
{
  "success": true,
  "message": "Coordinates extracted from expanded link",
  "data": {
    "coordinates": {
      "latitude": -6.1234,
      "longitude": 106.5678
    }
  }
}
```

**Alternative Response** (if expansion not possible):
```json
{
  "success": true,
  "message": "Could not automatically expand shortened link",
  "data": {
    "expanded_url": null,
    "manual_required": true
  }
}
```

---

## Data Models & Relationships

### User Model
- Represents admin/system users
- Fields: id, email, password, name, created_at
- Relations: None

### Employee Model
- Represents company employees
- Fields: id, id_company, id_department, name, email, phone_number, address, profile_picture, is_attendances, total_attendances, fingerprint_registered
- Relations: belongsTo Company, belongsTo Department, hasMany Attendance, hasMany WorkSchedule

### Company Model
- Fields: id, no_company, name, logo_company, address, longitude, latitude
- Relations: hasMany Employee

### Department Model
- Fields: id, name, description, status
- Relations: hasMany Employee

### Attendance Model
- Fields: id, id_employee, date, check_in, check_out, status, location_in, location_out, photo_check_in, photo_check_out
- Relations: belongsTo Employee, hasOne AttendanceBypass

### AttendanceBypass Model
- Fields: id, id_employee, id_attendance, id_admin, type, reason, manual_check_in, manual_check_out, status
- Relations: belongsTo Attendance

### WorkSchedule Model
- Fields: id, id_employee, shift_name, start_time, end_time
- Relations: belongsTo Employee

### Leaves Model
- Fields: id, id_employee, start_date, end_date, type, reason, status
- Relations: belongsTo Employee

---

## Error Handling

### Common HTTP Status Codes

| Code | Meaning | Example |
|------|---------|---------|
| 200 | OK - Request successful | Fetching data |
| 201 | Created - Resource created | Creating company |
| 400 | Bad Request - Invalid input | Missing required field |
| 401 | Unauthorized - Auth failed | Invalid/expired token |
| 403 | Forbidden - Access denied | Employee not enabled |
| 404 | Not Found - Resource missing | Employee ID not exist |
| 500 | Server Error | Database error |

### Error Response Examples

**Validation Error (400)**:
```json
{
  "success": false,
  "message": "Validation failed",
  "data": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  }
}
```

**Authentication Error (401)**:
```json
{
  "success": false,
  "message": "Unauthorized",
  "data": null
}
```

**Not Found Error (404)**:
```json
{
  "success": false,
  "message": "Employee not found",
  "data": null
}
```

---

## Mobile Integration Guide

### 1. Fingerprint Registration Flow

```
Mobile App Flow:
1. User enters email → GET /public/employee?email={{email}}
2. If fingerprint_registered = false:
   - Capture fingerprint from device sensor
   - POST /public/attendance/register-fingerprint with base64 data
3. Display confirmation message
```

### 2. Daily Attendance Flow

```
Mobile App Flow:
1. User enters email
2. GET /public/employee?email={{email}} (verify employee exists)
3. Capture fingerprint from device sensor
4. (Optional) Capture photo from camera
5. Get GPS coordinates from device
6. POST /public/attendance/join with all data:
   - email
   - fingerprint_data (base64)
   - photo (optional, multipart)
   - location_latitude
   - location_longitude
   - type: "check_in" or "check_out"
7. Handle response:
   - If success: Show confirmation with fingerprint similarity %
   - If error: Display error message
```

### 3. Admin Dashboard Flow

```
Admin Web Flow:
1. POST /login with credentials
2. Store JWT token
3. GET /dashboard/statistics for overview
4. GET /attendance for detailed records
5. POST /attendance/bypass for manual adjustments
6. GET /employees for employee management
7. PUT/POST /work-schedules for scheduling
```

### 4. Implementation Checklist

- [ ] Implement fingerprint capture in mobile app
- [ ] Base64 encode fingerprint data before sending
- [ ] Handle JWT token storage and refresh
- [ ] Implement GPS location capture
- [ ] Implement camera/photo capture
- [ ] Add offline queue for failed requests
- [ ] Implement retry logic
- [ ] Add proper error handling and user feedback
- [ ] Test all endpoints in staging environment
- [ ] Set up monitoring and logging

---

## Rate Limiting & Performance Notes

- **Fingerprint Threshold**: 85% similarity by default
- **Photo Upload Limit**: 5MB per file
- **Logo Upload Limit**: 5MB per file
- **API Response**: Standard paginated responses with up to 10 records per page (configurable)
- **Photo Storage**: `storage/app/public/attendances/{employee_id}/`
- **Company Logo Storage**: `storage/app/public/companies/logos/`

---

## Security Considerations

1. **JWT Tokens**: Use secure, long-lived tokens with refresh mechanism
2. **HTTPS**: Always use HTTPS in production
3. **Fingerprint**: Current implementation uses Levenshtein distance (placeholder)
   - For production: Integrate professional biometric library
4. **File Uploads**: Validate file types and sizes on server
5. **Storage Link**: Must run `php artisan storage:link` to serve uploaded files
6. **CORS**: Configure appropriately for mobile/web clients

---

## Quick Reference

### Public Endpoints (No Auth):
- POST /login
- POST /public/attendance/join
- POST /public/attendance/register-fingerprint
- GET /public/employee

### Most Used Protected Endpoints:
- GET /attendance
- GET /dashboard/statistics
- GET /employees
- POST /attendance/bypass
- GET /me

### File Routes (Serve Uploads):
- GET /storage/{path} - Serves files from storage/app/public/

---

**Generated**: November 11, 2025
**Version**: 1.0
