# QR Attendance API Documentation

## Overview
The QR Attendance system provides secure, location-based attendance tracking using QR codes. Each QR code is time-limited and includes security measures to prevent unauthorized usage.

## Authentication
All endpoints require Bearer token authentication.

```http
Authorization: Bearer {your_api_token}
```

## Rate Limiting
QR endpoints are rate limited to prevent abuse:
- **Generate QR**: 10 requests per hour
- **Scan QR**: 60 requests per hour  
- **QR Status**: 120 requests per hour
- **Refresh QR**: 5 requests per hour

Rate limit headers are included in responses:
- `X-RateLimit-Limit`: Maximum attempts allowed
- `X-RateLimit-Remaining`: Remaining attempts
- `X-RateLimit-Reset`: Seconds until rate limit resets

## Endpoints

### 1. Generate QR Code
Generate a new QR code for attendance scanning.

**Endpoint:** `POST /api/v1/hrm/attendance/qr/generate`

**Request Body:**
```json
{
    "branch_id": "123",
    "expires_in_minutes": 30
}
```

**Parameters:**
- `branch_id` (required): ID of the branch where QR code will be used
- `expires_in_minutes` (optional): QR code expiration time (5-60 minutes, default: 30)

**Success Response (201):**
```json
{
    "success": true,
    "message": "QR code generated successfully",
    "data": {
        "qr_token": "qr_abc123def456...",
        "qr_data": "{\"token\":\"qr_abc123def456...\",\"branch_id\":\"123\",\"company_id\":\"456\",\"expires_at\":\"2025-09-21T15:30:00.000000Z\"}",
        "expires_at": "2025-09-21T15:30:00.000000Z",
        "expires_in_minutes": 30,
        "branch_id": "123",
        "usage_count": 0
    }
}
```

**Error Responses:**
```json
// Validation Error (422)
{
    "success": false,
    "message": "Validation failed",
    "data": {
        "branch_id": ["The branch id field is required."]
    }
}

// Permission Error (403)
{
    "success": false,
    "message": "You do not have permission to generate QR codes for this branch",
    "data": []
}

// Rate Limit Error (429)
{
    "success": false,
    "message": "Too many requests. Please try again in 5 minutes.",
    "error_code": "RATE_LIMIT_EXCEEDED",
    "retry_after": 300
}
```

### 2. Scan QR Code
Process attendance by scanning a QR code.

**Endpoint:** `POST /api/v1/hrm/attendance/qr/scan`

**Request Body:**
```json
{
    "qr_token": "qr_abc123def456...",
    "employee_id": "789",
    "action": "check_in",
    "latitude": 23.8103,
    "longitude": 90.4125,
    "device_info": {
        "user_agent": "Mozilla/5.0...",
        "ip_address": "192.168.1.100",
        "device_type": "mobile",
        "platform": "android"
    }
}
```

**Parameters:**
- `qr_token` (required): The QR token to scan (minimum 10 characters)
- `employee_id` (required): ID of the employee checking in/out
- `action` (required): Either "check_in" or "check_out"
- `latitude` (optional): GPS latitude (-90 to 90)
- `longitude` (optional): GPS longitude (-180 to 180)
- `device_info` (optional): Device information object
  - `user_agent` (optional): Browser user agent string
  - `ip_address` (optional): Device IP address

**Success Response (201):**
```json
{
    "success": true,
    "message": "Check-in recorded successfully via QR code",
    "data": {
        "id": "att_001",
        "employee_id": "789",
        "date": "2025-09-21",
        "check_in_time": "09:00:00",
        "check_in_method": "qr_code",
        "check_in_location": "Office Entrance",
        "check_in_latitude": 23.8103,
        "check_in_longitude": 90.4125,
        "status": "present",
        "employee": {
            "id": "789",
            "employee_code": "EMP001",
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@company.com"
        }
    }
}
```

**Error Responses:**
```json
// Invalid QR Token (400)
{
    "success": false,
    "message": "Invalid or expired QR code",
    "data": []
}

// Employee Company Mismatch (403)
{
    "success": false,
    "message": "Employee does not belong to your company",
    "data": []
}

// Validation Error (422)
{
    "success": false,
    "message": "Validation failed",
    "data": {
        "qr_token": ["The qr token field is required."],
        "employee_id": ["The selected employee id is invalid."]
    }
}
```

### 3. Get QR Status
Check the current status of QR codes for a branch.

**Endpoint:** `GET /api/v1/hrm/attendance/qr/status`

**Query Parameters:**
- `branch_id` (required): Branch ID to check QR status for

**Example:** `GET /api/v1/hrm/attendance/qr/status?branch_id=123`

**Success Response (200):**
```json
{
    "success": true,
    "message": "QR status retrieved successfully",
    "data": {
        "has_active_qr": true,
        "active_qr": {
            "token": "qr_abc123def456...",
            "expires_at": "2025-09-21T15:30:00.000000Z",
            "expires_in_minutes": 25,
            "usage_count": 5,
            "generated_at": "2025-09-21T15:00:00.000000Z"
        },
        "branch_id": "123"
    }
}
```

### 4. Refresh QR Code
Generate a new QR code for a branch, deactivating the previous one.

**Endpoint:** `POST /api/v1/hrm/attendance/qr/refresh`

**Request Body:**
```json
{
    "branch_id": "123",
    "expires_in_minutes": 30
}
```

**Success Response (201):**
```json
{
    "success": true,
    "message": "QR code refreshed successfully",
    "data": {
        "qr_token": "qr_new789xyz456...",
        "qr_data": "{\"token\":\"qr_new789xyz456...\",\"branch_id\":\"123\",\"company_id\":\"456\",\"expires_at\":\"2025-09-21T16:00:00.000000Z\"}",
        "expires_at": "2025-09-21T16:00:00.000000Z",
        "expires_in_minutes": 30,
        "branch_id": "123",
        "usage_count": 0,
        "previous_qr_deactivated": true
    }
}
```

## Security Features

### 1. Time-based Expiration
- QR codes automatically expire after the specified time
- Default expiration: 30 minutes
- Range: 5-60 minutes

### 2. Company & Branch Validation
- QR codes are tied to specific companies and branches
- Employees can only use QR codes from their own company
- Branch access permissions are validated

### 3. Location Tracking
- GPS coordinates are captured when available
- Location validation can be enabled for geofencing
- Device information is logged for audit trails

### 4. Rate Limiting
- Different rate limits for each endpoint
- IP and user-based limiting
- Automatic rate limit headers in responses

### 5. Audit Logging
- All QR operations are logged
- Failed attempts are tracked
- Device and location information is recorded

## Error Codes

| Code | Description |
|------|-------------|
| `RATE_LIMIT_EXCEEDED` | Too many requests within time window |
| `QR_EXPIRED` | QR code has expired |
| `QR_INVALID` | QR code token is invalid |
| `EMPLOYEE_COMPANY_MISMATCH` | Employee doesn't belong to QR company |
| `BRANCH_ACCESS_DENIED` | User lacks permission for branch |
| `VALIDATION_FAILED` | Request validation errors |

## Integration Examples

### Frontend QR Scanner Integration
```javascript
// Generate QR Code
const generateQR = async (branchId) => {
    const response = await fetch('/api/v1/hrm/attendance/qr/generate', {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            branch_id: branchId,
            expires_in_minutes: 30
        })
    });
    
    const data = await response.json();
    return data.data.qr_data; // Use this for QR code display
};

// Process QR Scan
const scanQR = async (qrToken, employeeId, coordinates) => {
    const response = await fetch('/api/v1/hrm/attendance/qr/scan', {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            qr_token: qrToken,
            employee_id: employeeId,
            action: 'check_in',
            latitude: coordinates.latitude,
            longitude: coordinates.longitude,
            device_info: {
                user_agent: navigator.userAgent,
                device_type: 'mobile'
            }
        })
    });
    
    return await response.json();
};
```

### Backend Integration
```php
// Using the AttendanceService directly
$attendanceService = app(AttendanceService::class);

// Generate QR Code
$qrData = $attendanceService->generateQRCode(
    $companyId, 
    $branchId, 
    30 // expires in 30 minutes
);

// Process QR Attendance
$attendance = $attendanceService->processQRAttendance([
    'qr_token' => $qrToken,
    'employee_id' => $employeeId,
    'action' => 'check_in',
    'latitude' => $latitude,
    'longitude' => $longitude,
    'device_info' => $deviceInfo
]);
```

## Best Practices

1. **QR Code Display**: Display QR codes with expiration countdown
2. **Error Handling**: Implement proper error handling for all scenarios
3. **Location Services**: Request location permissions for enhanced security
4. **Offline Support**: Cache QR tokens for offline scanning when possible
5. **User Feedback**: Provide clear feedback on scan success/failure
6. **Rate Limiting**: Handle rate limit responses gracefully
7. **Security**: Never expose QR tokens in logs or URLs