{
    "openapi": "3.0.0",
    "info": {
        "title": "GajiPro HRIS/Payroll API",
        "description": "REST API untuk aplikasi GajiPro HRIS/Payroll SaaS. API ini digunakan oleh aplikasi mobile Flutter untuk mengelola absensi, cuti, lembur, slip gaji, pinjaman, dan reimbursement karyawan.",
        "contact": {
            "name": "GajiPro Support",
            "email": "support@gajipro.com"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "/api/v1",
            "description": "GajiPro API v1"
        }
    ],
    "paths": {
        "/announcements": {
            "get": {
                "tags": [
                    "Announcement"
                ],
                "summary": "Daftar Pengumuman",
                "description": "Menampilkan daftar pengumuman yang aktif dan ditargetkan untuk user yang sedang login. Pengumuman diurutkan berdasarkan status pin, prioritas, dan tanggal publikasi.",
                "operationId": "521d557c2f9e912f37b2fea539e0a8ce",
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Nomor halaman untuk pagination",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar pengumuman berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "title": {
                                                        "type": "string",
                                                        "example": "Libur Tahun Baru 2026"
                                                    },
                                                    "content": {
                                                        "type": "string",
                                                        "example": "Kantor akan libur pada tanggal 1 Januari 2026"
                                                    },
                                                    "priority": {
                                                        "type": "string",
                                                        "enum": [
                                                            "low",
                                                            "normal",
                                                            "high",
                                                            "urgent"
                                                        ],
                                                        "example": "high"
                                                    },
                                                    "priority_label": {
                                                        "type": "string",
                                                        "example": "Tinggi"
                                                    },
                                                    "is_pinned": {
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "is_read": {
                                                        "type": "boolean",
                                                        "example": false
                                                    },
                                                    "published_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "example": "2026-01-15 10:00:00"
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "example": "2026-01-15 09:30:00"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "meta": {
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "last_page": {
                                                    "type": "integer",
                                                    "example": 3
                                                },
                                                "per_page": {
                                                    "type": "integer",
                                                    "example": 15
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "example": 42
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/announcements/{id}": {
            "get": {
                "tags": [
                    "Announcement"
                ],
                "summary": "Detail Pengumuman",
                "description": "Menampilkan detail lengkap pengumuman termasuk informasi pembuat pengumuman. Hanya dapat diakses oleh user yang menjadi target pengumuman tersebut.",
                "operationId": "1c04bea8b6f40eb8c5c37147269ed1b9",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengumuman",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Detail pengumuman berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "title": {
                                                    "type": "string",
                                                    "example": "Libur Tahun Baru 2026"
                                                },
                                                "content": {
                                                    "type": "string",
                                                    "example": "Kantor akan libur pada tanggal 1 Januari 2026"
                                                },
                                                "priority": {
                                                    "type": "string",
                                                    "enum": [
                                                        "low",
                                                        "normal",
                                                        "high",
                                                        "urgent"
                                                    ],
                                                    "example": "high"
                                                },
                                                "priority_label": {
                                                    "type": "string",
                                                    "example": "Tinggi"
                                                },
                                                "is_pinned": {
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "is_read": {
                                                    "type": "boolean",
                                                    "example": false
                                                },
                                                "published_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-01-15 10:00:00"
                                                },
                                                "created_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-01-15 09:30:00"
                                                },
                                                "creator": {
                                                    "properties": {
                                                        "name": {
                                                            "type": "string",
                                                            "example": "Admin HRD"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa"
                    },
                    "404": {
                        "description": "Pengumuman tidak ditemukan atau tidak dapat diakses",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengumuman tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/announcements/{id}/read": {
            "post": {
                "tags": [
                    "Announcement"
                ],
                "summary": "Tandai Pengumuman Sudah Dibaca",
                "description": "Menandai pengumuman tertentu sebagai sudah dibaca oleh user yang sedang login. Setelah ditandai, pengumuman tidak akan muncul lagi di counter pengumuman yang belum dibaca.",
                "operationId": "25ac388e6a3eb882055963a51586eb39",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengumuman",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Pengumuman berhasil ditandai sudah dibaca",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengumuman ditandai sudah dibaca."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa"
                    },
                    "404": {
                        "description": "Pengumuman tidak ditemukan atau tidak dapat diakses",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengumuman tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/announcements/unread-count": {
            "get": {
                "tags": [
                    "Announcement"
                ],
                "summary": "Jumlah Pengumuman Belum Dibaca",
                "description": "Menghitung jumlah pengumuman yang belum dibaca oleh user yang sedang login. Endpoint ini berguna untuk menampilkan badge notifikasi di aplikasi mobile.",
                "operationId": "3d574365633b6e28d843feee1a5ecd62",
                "responses": {
                    "200": {
                        "description": "Jumlah pengumuman belum dibaca berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "count": {
                                                    "type": "integer",
                                                    "example": 5
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/pending": {
            "get": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Get pending approval items",
                "description": "Returns all pending leave requests, overtime requests, and reimbursements for manager approval",
                "operationId": "dfe14fa6c1448b2473e36b68761ecc2c",
                "responses": {
                    "200": {
                        "description": "Pending approvals retrieved successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "leave_requests": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "overtime_requests": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "reimbursements": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "total_pending": {
                                                    "type": "integer",
                                                    "example": 5
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/leave/{id}/approve": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Approve leave request",
                "operationId": "52ccaf002a8c0eb1c53150252d336820",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "example": "Approved"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Leave request approved"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "404": {
                        "description": "Leave request not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/leave/{id}/reject": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Reject leave request",
                "operationId": "40b403460e06f407e3af3255b701edd8",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "notes"
                                ],
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "example": "Insufficient leave balance"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Leave request rejected"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/overtime/{id}/approve": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Approve overtime request",
                "operationId": "0890b45432c049d13530d091e5f6d64d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Overtime request approved"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "404": {
                        "description": "Overtime request not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/overtime/{id}/reject": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Reject overtime request",
                "operationId": "0fcf806009b185211a73e105cdca5379",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "notes"
                                ],
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "example": "Not required"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Overtime request rejected"
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/reimbursement/{id}/approve": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Approve reimbursement",
                "operationId": "1b0670f91b076d25539ce3dffe855377",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reimbursement approved"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "404": {
                        "description": "Reimbursement not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/reimbursement/{id}/reject": {
            "post": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Reject reimbursement",
                "operationId": "cc1f4ca9ca66896f48e9eea54bb5f8d9",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "notes"
                                ],
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "example": "Invalid receipt"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Reimbursement rejected"
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/approvals/history": {
            "get": {
                "tags": [
                    "Approvals"
                ],
                "summary": "Get approval history",
                "description": "Returns history of approved/rejected requests by the manager",
                "operationId": "116035eb4bb0259da85b8d4163dacd91",
                "responses": {
                    "200": {
                        "description": "Approval history retrieved",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "type": {
                                                        "type": "string",
                                                        "example": "leave"
                                                    },
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "employee_name": {
                                                        "type": "string",
                                                        "example": "John Doe"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "example": "approved"
                                                    },
                                                    "approved_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/attendance/today": {
            "get": {
                "tags": [
                    "Attendance"
                ],
                "summary": "Mendapatkan data kehadiran hari ini",
                "description": "Mengembalikan data kehadiran karyawan untuk hari ini beserta jadwal kerja",
                "operationId": "dd197d70d8aa4758d51942a4329f60fd",
                "responses": {
                    "200": {
                        "description": "Data kehadiran hari ini",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer"
                                                },
                                                "date": {
                                                    "type": "string",
                                                    "format": "date"
                                                },
                                                "clock_in": {
                                                    "type": "string",
                                                    "example": "08:00"
                                                },
                                                "clock_out": {
                                                    "type": "string",
                                                    "nullable": true
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "present",
                                                        "late",
                                                        "absent",
                                                        "leave"
                                                    ]
                                                },
                                                "status_label": {
                                                    "type": "string"
                                                },
                                                "late_minutes": {
                                                    "type": "integer"
                                                },
                                                "working_minutes": {
                                                    "type": "integer",
                                                    "nullable": true
                                                },
                                                "schedule": {
                                                    "properties": {
                                                        "start_time": {
                                                            "type": "string",
                                                            "example": "08:00"
                                                        },
                                                        "end_time": {
                                                            "type": "string",
                                                            "example": "17:00"
                                                        }
                                                    },
                                                    "type": "object",
                                                    "nullable": true
                                                },
                                                "office_location": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "Kantor Pusat"
                                                        }
                                                    },
                                                    "type": "object",
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object",
                                            "nullable": true
                                        },
                                        "schedule": {
                                            "properties": {
                                                "name": {
                                                    "type": "string"
                                                },
                                                "start_time": {
                                                    "type": "string"
                                                },
                                                "end_time": {
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "nullable": true
                                        },
                                        "timezone": {
                                            "description": "Company timezone information for client-side time handling",
                                            "properties": {
                                                "name": {
                                                    "description": "IANA timezone name",
                                                    "type": "string",
                                                    "example": "Asia/Jakarta"
                                                },
                                                "offset": {
                                                    "description": "UTC offset",
                                                    "type": "string",
                                                    "example": "+07:00"
                                                },
                                                "current_time": {
                                                    "description": "Current server time in company timezone",
                                                    "type": "string",
                                                    "example": "2026-02-18 15:30:00"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/attendance/clock-in": {
            "post": {
                "tags": [
                    "Attendance"
                ],
                "summary": "Clock in / Absen masuk",
                "description": "Melakukan absen masuk dengan lokasi GPS dan verifikasi wajah. Mendukung client-side validation untuk GPS dan face: kirim gps_verified=true + office_location_id untuk GPS client-side, dan face_verified=true untuk face client-side.",
                "operationId": "542455a9a94d34e099b32c8b7b38aac2",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "latitude",
                                    "longitude"
                                ],
                                "properties": {
                                    "latitude": {
                                        "type": "number",
                                        "format": "double",
                                        "example": -6.2
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "format": "double",
                                        "example": 106.816666
                                    },
                                    "photo": {
                                        "description": "Foto selfie (jpg, jpeg, png)",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "notes": {
                                        "type": "string",
                                        "example": "Clock in dari kantor"
                                    },
                                    "face_verified": {
                                        "description": "Flag verifikasi wajah dari client (true jika sudah match di device lokal).",
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "face_confidence": {
                                        "description": "Confidence score dari verifikasi wajah di client (0-1). Opsional, untuk audit log.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 0.85
                                    },
                                    "face_descriptors": {
                                        "description": "[LEGACY] Array 128 nilai face descriptor untuk server-side matching.",
                                        "type": "array",
                                        "items": {
                                            "type": "number",
                                            "format": "float"
                                        },
                                        "maxItems": 128,
                                        "minItems": 128
                                    },
                                    "gps_verified": {
                                        "description": "Flag validasi GPS dari client (true jika sudah divalidasi di device lokal menggunakan assigned_offices dari login/profile).",
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "office_location_id": {
                                        "description": "ID lokasi kantor yang tervalidasi di client. Wajib jika gps_verified=true.",
                                        "type": "integer",
                                        "example": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Clock in berhasil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Clock in berhasil."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer"
                                                },
                                                "date": {
                                                    "type": "string",
                                                    "format": "date"
                                                },
                                                "clock_in": {
                                                    "type": "string",
                                                    "example": "08:05"
                                                },
                                                "status": {
                                                    "type": "string"
                                                },
                                                "late_minutes": {
                                                    "type": "integer"
                                                },
                                                "face_verified": {
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "office_location": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "Kantor Pusat"
                                                        }
                                                    },
                                                    "type": "object",
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Sudah clock in atau lokasi terlalu jauh",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/attendance/clock-out": {
            "post": {
                "tags": [
                    "Attendance"
                ],
                "summary": "Clock out / Absen pulang",
                "description": "Melakukan absen pulang dengan lokasi GPS dan verifikasi wajah. Mendukung client-side validation untuk GPS dan face: kirim gps_verified=true + office_location_id untuk GPS client-side, dan face_verified=true untuk face client-side.",
                "operationId": "2b67a646d2495e69c083c7e517dceafc",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "latitude",
                                    "longitude"
                                ],
                                "properties": {
                                    "latitude": {
                                        "type": "number",
                                        "format": "double",
                                        "example": -6.2
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "format": "double",
                                        "example": 106.816666
                                    },
                                    "photo": {
                                        "description": "Foto selfie",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "notes": {
                                        "type": "string"
                                    },
                                    "face_verified": {
                                        "description": "Flag verifikasi wajah dari client (true jika sudah match di device lokal).",
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "face_confidence": {
                                        "description": "Confidence score dari verifikasi wajah di client (0-1). Opsional, untuk audit log.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 0.85
                                    },
                                    "face_descriptors": {
                                        "description": "[LEGACY] Array 128 nilai face descriptor untuk server-side matching.",
                                        "type": "array",
                                        "items": {
                                            "type": "number",
                                            "format": "float"
                                        },
                                        "maxItems": 128,
                                        "minItems": 128
                                    },
                                    "gps_verified": {
                                        "description": "Flag validasi GPS dari client (true jika sudah divalidasi di device lokal menggunakan assigned_offices dari login/profile).",
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "office_location_id": {
                                        "description": "ID lokasi kantor yang tervalidasi di client. Wajib jika gps_verified=true.",
                                        "type": "integer",
                                        "example": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Clock out berhasil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Clock out berhasil."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer"
                                                },
                                                "date": {
                                                    "type": "string",
                                                    "format": "date"
                                                },
                                                "clock_in": {
                                                    "type": "string"
                                                },
                                                "clock_out": {
                                                    "type": "string"
                                                },
                                                "working_minutes": {
                                                    "type": "integer"
                                                },
                                                "overtime_minutes": {
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Belum clock in atau sudah clock out"
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/attendance/history": {
            "get": {
                "tags": [
                    "Attendance"
                ],
                "summary": "Riwayat kehadiran",
                "description": "Mendapatkan riwayat kehadiran karyawan dengan filter tanggal",
                "operationId": "180790ea1c526c0043e05e6c5ade776e",
                "parameters": [
                    {
                        "name": "start_date",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "end_date",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "month",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 12,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "year",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar riwayat kehadiran",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer"
                                                    },
                                                    "date": {
                                                        "type": "string",
                                                        "format": "date"
                                                    },
                                                    "clock_in": {
                                                        "type": "string"
                                                    },
                                                    "clock_out": {
                                                        "type": "string",
                                                        "nullable": true
                                                    },
                                                    "status": {
                                                        "type": "string"
                                                    },
                                                    "status_label": {
                                                        "type": "string"
                                                    },
                                                    "working_hours": {
                                                        "type": "string"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "meta": {
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer"
                                                },
                                                "last_page": {
                                                    "type": "integer"
                                                },
                                                "per_page": {
                                                    "type": "integer"
                                                },
                                                "total": {
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/attendance/summary": {
            "get": {
                "tags": [
                    "Attendance"
                ],
                "summary": "Ringkasan kehadiran bulanan",
                "description": "Mendapatkan ringkasan statistik kehadiran karyawan untuk bulan tertentu",
                "operationId": "f86f8cfc2e7f14cf33fb83ba18b93f74",
                "parameters": [
                    {
                        "name": "month",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 12,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "year",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Ringkasan kehadiran",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "data": {
                                            "properties": {
                                                "total_working_days": {
                                                    "type": "integer"
                                                },
                                                "total_present": {
                                                    "type": "integer"
                                                },
                                                "total_absent": {
                                                    "type": "integer"
                                                },
                                                "total_late": {
                                                    "type": "integer"
                                                },
                                                "total_leave": {
                                                    "type": "integer"
                                                },
                                                "total_working_hours": {
                                                    "type": "number"
                                                },
                                                "total_overtime_hours": {
                                                    "type": "number"
                                                },
                                                "total_late_minutes": {
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/auth/demo-register": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Registrasi akun demo",
                "description": "Mendaftarkan akun baru sebagai karyawan PT Demo GajiPro untuk testing aplikasi",
                "operationId": "ad06eceaa626d7865938905f80430133",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "email",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "John Doe"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "john@example.com"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "example": "081234567890"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 8,
                                        "example": "password123"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "password123"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Registrasi berhasil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Registrasi berhasil. Silakan login dengan email dan password Anda."
                                        },
                                        "data": {
                                            "properties": {
                                                "email": {
                                                    "type": "string",
                                                    "example": "john@example.com"
                                                },
                                                "name": {
                                                    "type": "string",
                                                    "example": "John Doe"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Email sudah terdaftar."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Demo company tidak tersedia",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Demo company tidak tersedia. Silakan hubungi administrator."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/auth/login": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Login ke aplikasi",
                "description": "Autentikasi pengguna dengan email atau ID karyawan dan password, mengembalikan token Sanctum",
                "operationId": "985cd5203e2d0a820e113f2f4fdb2847",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "password"
                                ],
                                "properties": {
                                    "email": {
                                        "description": "Email atau ID Karyawan",
                                        "type": "string",
                                        "example": "karyawan@perusahaan.com"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "password123"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login berhasil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Login berhasil."
                                        },
                                        "data": {
                                            "properties": {
                                                "token": {
                                                    "type": "string",
                                                    "example": "1|abcdef123456..."
                                                },
                                                "user": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "John Doe"
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "example": "john@company.com"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "employee": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "employee_id": {
                                                            "type": "string",
                                                            "example": "EMP20260001"
                                                        },
                                                        "full_name": {
                                                            "type": "string",
                                                            "example": "John Doe"
                                                        },
                                                        "department": {
                                                            "type": "string",
                                                            "example": "IT"
                                                        },
                                                        "position": {
                                                            "type": "string",
                                                            "example": "Software Engineer"
                                                        },
                                                        "face_enrolled": {
                                                            "description": "Apakah wajah sudah didaftarkan",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "face_embedding": {
                                                            "description": "Data embedding wajah untuk verifikasi di client menggunakan TFLite/Google MLKit (null jika belum enrolled atau face recognition disabled)",
                                                            "properties": {
                                                                "model": {
                                                                    "description": "Model yang digunakan untuk generate embedding (google_mlkit, tflite)",
                                                                    "type": "string",
                                                                    "example": "google_mlkit"
                                                                },
                                                                "version": {
                                                                    "description": "Versi format embedding",
                                                                    "type": "string",
                                                                    "example": "1.0"
                                                                },
                                                                "embedding": {
                                                                    "description": "Array 128/512 nilai float embedding wajah dari TFLite/MLKit",
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "number",
                                                                        "format": "float"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object",
                                                            "nullable": true
                                                        },
                                                        "assigned_offices": {
                                                            "description": "Daftar lokasi kantor yang di-assign ke karyawan untuk validasi GPS di client",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "integer",
                                                                        "example": 1
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "example": "Kantor Pusat"
                                                                    },
                                                                    "code": {
                                                                        "type": "string",
                                                                        "example": "HQ-001"
                                                                    },
                                                                    "latitude": {
                                                                        "type": "number",
                                                                        "format": "double",
                                                                        "example": -6.2
                                                                    },
                                                                    "longitude": {
                                                                        "type": "number",
                                                                        "format": "double",
                                                                        "example": 106.816666
                                                                    },
                                                                    "radius": {
                                                                        "description": "Radius validasi GPS dalam meter",
                                                                        "type": "integer",
                                                                        "example": 100
                                                                    },
                                                                    "is_primary": {
                                                                        "type": "boolean",
                                                                        "example": true
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "company": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "PT Example"
                                                        },
                                                        "enable_face_recognition": {
                                                            "description": "Apakah face recognition diaktifkan",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "face_match_threshold": {
                                                            "description": "Threshold kecocokan wajah (0-1)",
                                                            "type": "number",
                                                            "format": "float",
                                                            "example": 0.6
                                                        },
                                                        "enable_gps_validation": {
                                                            "description": "Apakah validasi GPS diaktifkan",
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kredensial salah",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Email/ID Karyawan atau password salah."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Akun tidak terdaftar sebagai karyawan atau tidak aktif",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Akun ini tidak terdaftar sebagai karyawan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error"
                    }
                }
            }
        },
        "/auth/logout": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Logout dari aplikasi",
                "description": "Menghapus token akses saat ini",
                "operationId": "a05022a34eef599e04fb0a5254375b84",
                "responses": {
                    "200": {
                        "description": "Logout berhasil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Berhasil logout."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/auth/profile": {
            "get": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Mendapatkan profil pengguna",
                "description": "Mengembalikan data profil pengguna yang sedang login beserta data karyawan dan perusahaan",
                "operationId": "bc998dce248d856001e74e7beb1239ba",
                "responses": {
                    "200": {
                        "description": "Data profil berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "user": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer"
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "email": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "employee": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer"
                                                        },
                                                        "employee_id": {
                                                            "type": "string"
                                                        },
                                                        "full_name": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string"
                                                        },
                                                        "last_name": {
                                                            "type": "string"
                                                        },
                                                        "phone": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "photo": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "department": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "position": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "hire_date": {
                                                            "type": "string",
                                                            "format": "date"
                                                        },
                                                        "employment_status": {
                                                            "type": "string"
                                                        },
                                                        "face_enrolled": {
                                                            "description": "Apakah wajah sudah didaftarkan",
                                                            "type": "boolean"
                                                        },
                                                        "face_embedding": {
                                                            "description": "Data embedding wajah untuk verifikasi di client menggunakan TFLite/Google MLKit",
                                                            "properties": {
                                                                "model": {
                                                                    "description": "Model: google_mlkit atau tflite",
                                                                    "type": "string"
                                                                },
                                                                "version": {
                                                                    "description": "Versi format embedding",
                                                                    "type": "string"
                                                                },
                                                                "embedding": {
                                                                    "description": "Array float embedding",
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "number"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object",
                                                            "nullable": true
                                                        },
                                                        "assigned_offices": {
                                                            "description": "Daftar lokasi kantor yang di-assign ke karyawan untuk validasi GPS di client",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "integer"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    },
                                                                    "code": {
                                                                        "type": "string"
                                                                    },
                                                                    "latitude": {
                                                                        "type": "number",
                                                                        "format": "double"
                                                                    },
                                                                    "longitude": {
                                                                        "type": "number",
                                                                        "format": "double"
                                                                    },
                                                                    "radius": {
                                                                        "description": "Radius dalam meter",
                                                                        "type": "integer"
                                                                    },
                                                                    "is_primary": {
                                                                        "type": "boolean"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "company": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer"
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "logo": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "enable_face_recognition": {
                                                            "type": "boolean"
                                                        },
                                                        "face_match_threshold": {
                                                            "type": "number",
                                                            "format": "float"
                                                        },
                                                        "enable_gps_validation": {
                                                            "type": "boolean"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Update profil",
                "description": "Memperbarui data profil karyawan termasuk nama, telepon, alamat, dan foto",
                "operationId": "f5c1fdd4be08c88ddabe4ce2f2535ffb",
                "requestBody": {
                    "required": false,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "first_name": {
                                        "description": "Nama depan",
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "John"
                                    },
                                    "last_name": {
                                        "description": "Nama belakang",
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "Doe"
                                    },
                                    "phone": {
                                        "description": "Nomor telepon (format Indonesia)",
                                        "type": "string",
                                        "example": "081234567890"
                                    },
                                    "address": {
                                        "description": "Alamat",
                                        "type": "string",
                                        "example": "Jl. Sudirman No. 1"
                                    },
                                    "photo": {
                                        "description": "Foto profil (jpg, jpeg, png, max 2MB)",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Profil berhasil diperbarui",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Profil berhasil diperbarui."
                                        },
                                        "data": {
                                            "properties": {
                                                "employee": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer"
                                                        },
                                                        "employee_id": {
                                                            "type": "string"
                                                        },
                                                        "full_name": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string"
                                                        },
                                                        "last_name": {
                                                            "type": "string"
                                                        },
                                                        "phone": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "photo": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/auth/change-password": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Mengubah password",
                "description": "Mengubah password pengguna yang sedang login",
                "operationId": "f01557748f9ad13189210c6637084834",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "current_password",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "current_password": {
                                        "type": "string",
                                        "example": "oldpassword"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 8,
                                        "example": "newpassword123"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "newpassword123"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password berhasil diubah",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Password berhasil diubah."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/auth/delete-account": {
            "delete": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Hapus akun",
                "description": "Menghapus akun pengguna (soft delete). Akun dapat direaktivasi dalam 30 hari dengan menghubungi admin.",
                "operationId": "5cadb16e1576067e7b2f2e1671015b14",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "password",
                                    "confirmation"
                                ],
                                "properties": {
                                    "password": {
                                        "description": "Password saat ini untuk konfirmasi",
                                        "type": "string",
                                        "example": "password123"
                                    },
                                    "confirmation": {
                                        "description": "Ketik \"HAPUS AKUN\" untuk konfirmasi",
                                        "type": "string",
                                        "example": "HAPUS AKUN"
                                    },
                                    "reason": {
                                        "description": "Alasan penghapusan akun (opsional)",
                                        "type": "string",
                                        "example": "Tidak lagi bekerja di perusahaan ini"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Akun berhasil dihapus",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Akun Anda berhasil dihapus. Akun dapat direaktivasi dalam 30 hari dengan menghubungi admin."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Password salah",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Password tidak sesuai."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/dashboard": {
            "get": {
                "tags": [
                    "Dashboard"
                ],
                "summary": "Dashboard summary untuk mobile app",
                "description": "Mengembalikan ringkasan data untuk dashboard mobile app termasuk kehadiran, cuti, payroll, dan request pending",
                "operationId": "07d2d0f81b9051bfc2a937097221e0ce",
                "responses": {
                    "200": {
                        "description": "Dashboard data berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "attendance": {
                                                    "properties": {
                                                        "today_status": {
                                                            "type": "string",
                                                            "example": "present",
                                                            "nullable": true
                                                        },
                                                        "clock_in": {
                                                            "type": "string",
                                                            "example": "08:00",
                                                            "nullable": true
                                                        },
                                                        "clock_out": {
                                                            "type": "string",
                                                            "example": "17:00",
                                                            "nullable": true
                                                        },
                                                        "monthly_present": {
                                                            "type": "integer",
                                                            "example": 20
                                                        },
                                                        "monthly_absent": {
                                                            "type": "integer",
                                                            "example": 2
                                                        },
                                                        "monthly_late": {
                                                            "type": "integer",
                                                            "example": 3
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "leave": {
                                                    "properties": {
                                                        "annual_balance": {
                                                            "type": "number",
                                                            "example": 12
                                                        },
                                                        "annual_used": {
                                                            "type": "number",
                                                            "example": 5
                                                        },
                                                        "pending_requests": {
                                                            "type": "integer",
                                                            "example": 1
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "payroll": {
                                                    "properties": {
                                                        "last_payslip_month": {
                                                            "type": "string",
                                                            "example": "Januari 2026",
                                                            "nullable": true
                                                        },
                                                        "last_payslip_amount": {
                                                            "type": "number",
                                                            "example": 8500000
                                                        },
                                                        "ytd_gross": {
                                                            "type": "number",
                                                            "example": 120000000
                                                        },
                                                        "ytd_net": {
                                                            "type": "number",
                                                            "example": 102000000
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "requests": {
                                                    "properties": {
                                                        "pending_overtime": {
                                                            "type": "integer",
                                                            "example": 2
                                                        },
                                                        "pending_reimbursement": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "pending_leave": {
                                                            "type": "integer",
                                                            "example": 0
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/dashboard/attendance-chart": {
            "get": {
                "tags": [
                    "Dashboard"
                ],
                "summary": "Data chart kehadiran",
                "description": "Mengembalikan data untuk chart kehadiran dalam format yang siap digunakan oleh chart library",
                "operationId": "5cb5fa1a4e87e5488bc8d7e15e506835",
                "parameters": [
                    {
                        "name": "days",
                        "in": "query",
                        "description": "Jumlah hari (default: 7, max: 30)",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 7,
                            "maximum": 30
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Chart data berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "labels": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "example": [
                                                        "Sen",
                                                        "Sel",
                                                        "Rab",
                                                        "Kam",
                                                        "Jum",
                                                        "Sab",
                                                        "Min"
                                                    ]
                                                },
                                                "datasets": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "label": {
                                                                "type": "string",
                                                                "example": "Jam Kerja"
                                                            },
                                                            "data": {
                                                                "type": "array",
                                                                "items": {
                                                                    "type": "number"
                                                                },
                                                                "example": [
                                                                    8,
                                                                    8.5,
                                                                    7.5,
                                                                    8,
                                                                    9,
                                                                    0,
                                                                    0
                                                                ]
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/dashboard/quick-stats": {
            "get": {
                "tags": [
                    "Dashboard"
                ],
                "summary": "Statistik cepat bulan ini",
                "description": "Mengembalikan statistik ringkas untuk bulan berjalan",
                "operationId": "5a00fde73b3a80fa2e141ce2ec76d35b",
                "responses": {
                    "200": {
                        "description": "Quick stats berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "total_working_days_this_month": {
                                                    "type": "integer",
                                                    "example": 22
                                                },
                                                "total_present_days": {
                                                    "type": "integer",
                                                    "example": 20
                                                },
                                                "total_absent_days": {
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "total_leave_days": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "total_late_count": {
                                                    "type": "integer",
                                                    "example": 3
                                                },
                                                "total_overtime_hours": {
                                                    "type": "number",
                                                    "example": 12.5
                                                },
                                                "attendance_percentage": {
                                                    "type": "number",
                                                    "example": 90.9
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/device-tokens": {
            "get": {
                "tags": [
                    "DeviceToken"
                ],
                "summary": "Daftar Device Token",
                "description": "Menampilkan daftar semua device token yang terdaftar untuk user yang sedang login. Diurutkan berdasarkan waktu terakhir digunakan.",
                "operationId": "3d68f724c16fc562f6f194507ec6bb99",
                "responses": {
                    "200": {
                        "description": "Daftar device token berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "platform": {
                                                        "type": "string",
                                                        "enum": [
                                                            "android",
                                                            "ios",
                                                            "web"
                                                        ],
                                                        "example": "android"
                                                    },
                                                    "device_name": {
                                                        "type": "string",
                                                        "example": "Samsung Galaxy S24",
                                                        "nullable": true
                                                    },
                                                    "device_model": {
                                                        "type": "string",
                                                        "example": "SM-S921B",
                                                        "nullable": true
                                                    },
                                                    "app_version": {
                                                        "type": "string",
                                                        "example": "1.0.0",
                                                        "nullable": true
                                                    },
                                                    "is_active": {
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "last_used_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "example": "2026-02-15T10:30:00+07:00",
                                                        "nullable": true
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/device-tokens/register": {
            "post": {
                "tags": [
                    "DeviceToken"
                ],
                "summary": "Daftarkan Device Token",
                "description": "Mendaftarkan device token baru untuk push notification atau memperbarui token yang sudah ada. Jika token sudah terdaftar, data akan diperbarui.",
                "operationId": "05f026b6eaeef0246103b1f931ed413c",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token",
                                    "platform"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "Firebase Cloud Messaging token",
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "dK8jH3kL...firebase_token"
                                    },
                                    "platform": {
                                        "description": "Platform device",
                                        "type": "string",
                                        "enum": [
                                            "android",
                                            "ios",
                                            "web"
                                        ],
                                        "example": "android"
                                    },
                                    "device_name": {
                                        "description": "Nama device (opsional)",
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "Samsung Galaxy S24",
                                        "nullable": true
                                    },
                                    "device_model": {
                                        "description": "Model device (opsional)",
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "SM-S921B",
                                        "nullable": true
                                    },
                                    "app_version": {
                                        "description": "Versi aplikasi (opsional)",
                                        "type": "string",
                                        "maxLength": 50,
                                        "example": "1.0.0",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Device token berhasil didaftarkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token registered successfully."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "platform": {
                                                    "type": "string",
                                                    "example": "android"
                                                },
                                                "device_name": {
                                                    "type": "string",
                                                    "example": "Samsung Galaxy S24"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "Device token berhasil diperbarui (token sudah ada)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token updated successfully."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "platform": {
                                                    "type": "string",
                                                    "example": "android"
                                                },
                                                "device_name": {
                                                    "type": "string",
                                                    "example": "Samsung Galaxy S24"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/device-tokens/unregister": {
            "delete": {
                "tags": [
                    "DeviceToken"
                ],
                "summary": "Hapus Device Token",
                "description": "Menghapus device token dari sistem. Biasanya dipanggil saat user logout atau uninstall aplikasi.",
                "operationId": "a49cb093a970056422a88a0f5a88b214",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "Firebase Cloud Messaging token yang akan dihapus",
                                        "type": "string",
                                        "example": "dK8jH3kL...firebase_token"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Device token berhasil dihapus",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token unregistered successfully."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Device token tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token not found."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/device-tokens/refresh": {
            "post": {
                "tags": [
                    "DeviceToken"
                ],
                "summary": "Refresh Device Token",
                "description": "Memperbarui device token dengan token baru. Dipanggil ketika FCM mengeluarkan token baru untuk device yang sama.",
                "operationId": "d1d1c6f2e53a68605234eaf7057ed965",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "old_token",
                                    "new_token"
                                ],
                                "properties": {
                                    "old_token": {
                                        "description": "Token lama yang akan diganti",
                                        "type": "string",
                                        "example": "old_firebase_token..."
                                    },
                                    "new_token": {
                                        "description": "Token baru dari FCM",
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "new_firebase_token..."
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Device token berhasil di-refresh",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token refreshed successfully."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "platform": {
                                                    "type": "string",
                                                    "example": "android"
                                                },
                                                "device_name": {
                                                    "type": "string",
                                                    "example": "Samsung Galaxy S24"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Device token lama tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Device token not found."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/employees/{employee}/offices": {
            "get": {
                "tags": [
                    "EmployeeOffice"
                ],
                "summary": "Daftar Kantor Karyawan",
                "description": "Mengambil daftar lokasi kantor yang di-assign ke karyawan. HR/Admin dapat melihat data karyawan manapun, karyawan hanya bisa melihat data sendiri.",
                "operationId": "d4df60b26b8b73bb59e0c3a0413af601",
                "parameters": [
                    {
                        "name": "employee",
                        "in": "path",
                        "description": "ID Employee",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar lokasi kantor berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "example": "Kantor Pusat"
                                                    },
                                                    "code": {
                                                        "type": "string",
                                                        "example": "HQ-001"
                                                    },
                                                    "address": {
                                                        "type": "string",
                                                        "example": "Jl. Sudirman No. 1"
                                                    },
                                                    "latitude": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": -6.2
                                                    },
                                                    "longitude": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 106.816666
                                                    },
                                                    "radius": {
                                                        "type": "integer",
                                                        "example": 100
                                                    },
                                                    "is_primary": {
                                                        "type": "boolean",
                                                        "example": true
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "403": {
                        "description": "Forbidden - tidak memiliki akses"
                    },
                    "404": {
                        "description": "Employee tidak ditemukan"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "EmployeeOffice"
                ],
                "summary": "Assign Kantor ke Karyawan",
                "description": "Meng-assign satu atau lebih lokasi kantor ke karyawan. Hanya HR/Admin yang dapat melakukan aksi ini. Assignment sebelumnya akan diganti.",
                "operationId": "4ffbdcd43d18f574954a7d6dbb5eea7f",
                "parameters": [
                    {
                        "name": "employee",
                        "in": "path",
                        "description": "ID Employee",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "office_location_ids"
                                ],
                                "properties": {
                                    "office_location_ids": {
                                        "description": "Array ID lokasi kantor",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        },
                                        "example": [
                                            1,
                                            2,
                                            3
                                        ]
                                    },
                                    "primary_office_id": {
                                        "description": "ID kantor utama (opsional, default ke office pertama)",
                                        "type": "integer",
                                        "example": 1,
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Office locations berhasil di-assign",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Office locations berhasil di-assign."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "403": {
                        "description": "Forbidden - hanya HR/Admin yang dapat assign"
                    },
                    "404": {
                        "description": "Employee tidak ditemukan"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "EmployeeOffice"
                ],
                "summary": "Hapus Semua Assignment Kantor",
                "description": "Menghapus semua assignment lokasi kantor dari karyawan. Hanya HR/Admin yang dapat melakukan aksi ini.",
                "operationId": "6e9be0a7a1c33c65013fb4554069c449",
                "parameters": [
                    {
                        "name": "employee",
                        "in": "path",
                        "description": "ID Employee",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Semua office locations berhasil dihapus",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Semua office locations berhasil dihapus."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "403": {
                        "description": "Forbidden - hanya HR/Admin yang dapat hapus"
                    },
                    "404": {
                        "description": "Employee tidak ditemukan"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/employees/{employee}/offices/{office}": {
            "delete": {
                "tags": [
                    "EmployeeOffice"
                ],
                "summary": "Hapus Assignment Kantor Tertentu",
                "description": "Menghapus assignment satu lokasi kantor dari karyawan. Jika kantor yang dihapus adalah primary, kantor lain akan otomatis dijadikan primary.",
                "operationId": "6ff0adb0c046d1e001c319f915038862",
                "parameters": [
                    {
                        "name": "employee",
                        "in": "path",
                        "description": "ID Employee",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "office",
                        "in": "path",
                        "description": "ID Office Location",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Office location berhasil dihapus",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Office location berhasil dihapus."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "403": {
                        "description": "Forbidden - hanya HR/Admin yang dapat hapus"
                    },
                    "404": {
                        "description": "Employee atau office tidak ditemukan"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/employees/{employee}/offices/{office}/set-primary": {
            "patch": {
                "tags": [
                    "EmployeeOffice"
                ],
                "summary": "Set Kantor Sebagai Primary",
                "description": "Menjadikan lokasi kantor sebagai primary untuk karyawan. Kantor sebelumnya yang primary akan di-unset.",
                "operationId": "f3e20beff7e811e2be02f435441238d1",
                "parameters": [
                    {
                        "name": "employee",
                        "in": "path",
                        "description": "ID Employee",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "office",
                        "in": "path",
                        "description": "ID Office Location",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Office location berhasil dijadikan primary",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Office location berhasil dijadikan primary."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "403": {
                        "description": "Forbidden - hanya HR/Admin yang dapat mengubah"
                    },
                    "404": {
                        "description": "Office tidak di-assign ke karyawan"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/face-recognition/status": {
            "get": {
                "tags": [
                    "FaceRecognition"
                ],
                "summary": "Status Pendaftaran Wajah",
                "description": "Mengambil status pendaftaran wajah karyawan untuk keperluan absensi. Mengembalikan informasi apakah wajah sudah terdaftar beserta pengaturan face recognition perusahaan.",
                "operationId": "4598b99c42839b2f43a8a45f01e1ca4a",
                "responses": {
                    "200": {
                        "description": "Status pendaftaran wajah berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "properties": {
                                                "enrolled": {
                                                    "description": "Apakah wajah sudah terdaftar",
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "enrolled_at": {
                                                    "description": "Waktu pendaftaran wajah",
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-01-15T10:30:00+07:00",
                                                    "nullable": true
                                                },
                                                "quality_score": {
                                                    "description": "Skor kualitas embedding wajah (0-1)",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 0.95,
                                                    "nullable": true
                                                },
                                                "company_settings": {
                                                    "properties": {
                                                        "face_recognition_enabled": {
                                                            "description": "Apakah face recognition diaktifkan di perusahaan",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "liveness_required": {
                                                            "description": "Apakah liveness detection diperlukan",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "match_threshold": {
                                                            "description": "Threshold kecocokan wajah (0-1)",
                                                            "type": "number",
                                                            "format": "float",
                                                            "example": 0.6
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Employee tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Employee not found for this user."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/face-recognition/enroll": {
            "post": {
                "tags": [
                    "FaceRecognition"
                ],
                "summary": "Daftarkan Wajah",
                "description": "Mendaftarkan wajah karyawan untuk verifikasi saat absensi. Mengirimkan embedding data dari face-api.js dan opsional foto wajah.",
                "operationId": "a9a83fa7391905c18307284e7beeba1a",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "embedding_data"
                                ],
                                "properties": {
                                    "embedding_data": {
                                        "description": "Data embedding wajah dari face-api.js",
                                        "required": [
                                            "version",
                                            "model",
                                            "descriptors"
                                        ],
                                        "properties": {
                                            "version": {
                                                "description": "Versi format embedding",
                                                "type": "string",
                                                "example": "1.0"
                                            },
                                            "model": {
                                                "description": "Model yang digunakan untuk ekstraksi embedding",
                                                "type": "string",
                                                "example": "face-api.js"
                                            },
                                            "descriptors": {
                                                "description": "Array 128 nilai float descriptor wajah",
                                                "type": "array",
                                                "items": {
                                                    "type": "number",
                                                    "format": "float"
                                                },
                                                "maxItems": 128,
                                                "minItems": 128
                                            }
                                        },
                                        "type": "object"
                                    },
                                    "photo": {
                                        "description": "Foto wajah (opsional, max 5MB)",
                                        "type": "string",
                                        "format": "binary",
                                        "nullable": true
                                    },
                                    "quality_score": {
                                        "description": "Skor kualitas gambar (0-1)",
                                        "type": "number",
                                        "format": "float",
                                        "example": 0.95,
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Wajah berhasil didaftarkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Face enrolled successfully."
                                        },
                                        "data": {
                                            "properties": {
                                                "enrolled": {
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "enrolled_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-02-15T10:30:00+07:00"
                                                },
                                                "quality_score": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 0.95
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Face recognition tidak diaktifkan di perusahaan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Face recognition is not enabled for this company."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Employee tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Employee not found for this user."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/face-recognition/verify": {
            "post": {
                "tags": [
                    "FaceRecognition"
                ],
                "summary": "Verifikasi Wajah",
                "description": "Memverifikasi wajah karyawan dengan embedding yang terdaftar. Digunakan untuk validasi saat clock in/out.",
                "operationId": "ffc7d10eb70878dcc5bdf1750dab8c72",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "descriptors"
                                ],
                                "properties": {
                                    "descriptors": {
                                        "description": "Array 128 nilai float descriptor wajah dari face-api.js",
                                        "type": "array",
                                        "items": {
                                            "type": "number",
                                            "format": "float"
                                        },
                                        "maxItems": 128,
                                        "minItems": 128
                                    },
                                    "verification_type": {
                                        "description": "Tipe verifikasi",
                                        "type": "string",
                                        "enum": [
                                            "clock_in",
                                            "clock_out"
                                        ],
                                        "example": "clock_in",
                                        "nullable": true
                                    },
                                    "photo": {
                                        "description": "Foto wajah untuk log (opsional, max 5MB)",
                                        "type": "string",
                                        "format": "binary",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Hasil verifikasi wajah",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "properties": {
                                                "matched": {
                                                    "description": "Apakah wajah cocok",
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "confidence": {
                                                    "description": "Tingkat kecocokan (0-1)",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 0.85
                                                },
                                                "error": {
                                                    "description": "Pesan error jika gagal",
                                                    "type": "string",
                                                    "example": null,
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Employee tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Employee not found for this user."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/face-recognition/enrollment": {
            "delete": {
                "tags": [
                    "FaceRecognition"
                ],
                "summary": "Hapus Pendaftaran Wajah",
                "description": "Menghapus data pendaftaran wajah karyawan. Setelah dihapus, karyawan perlu mendaftarkan wajah lagi untuk menggunakan fitur face recognition.",
                "operationId": "8ffdfa9f2e16b1d920fdd9f4e7a08317",
                "responses": {
                    "200": {
                        "description": "Pendaftaran wajah berhasil dihapus",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Face enrollment removed successfully."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Pendaftaran wajah tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "No face enrollment found."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/leaves": {
            "get": {
                "tags": [
                    "Leave"
                ],
                "summary": "Mendapatkan daftar pengajuan cuti",
                "description": "Mengembalikan daftar semua pengajuan cuti karyawan dengan filter status dan tahun",
                "operationId": "114d2cad3e7f0e39a805ef90f4e6161b",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter berdasarkan status cuti",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "approved",
                                "rejected",
                                "cancelled"
                            ]
                        }
                    },
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Filter berdasarkan tahun (default: tahun berjalan)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Nomor halaman untuk pagination",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar pengajuan cuti berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "request_number": {
                                                        "type": "string",
                                                        "example": "LV20260001"
                                                    },
                                                    "leave_type": {
                                                        "type": "string",
                                                        "example": "Cuti Tahunan"
                                                    },
                                                    "start_date": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-03-01"
                                                    },
                                                    "end_date": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-03-05"
                                                    },
                                                    "total_days": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 5
                                                    },
                                                    "reason": {
                                                        "type": "string",
                                                        "example": "Liburan keluarga"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "example": "pending"
                                                    },
                                                    "status_label": {
                                                        "type": "string",
                                                        "example": "Menunggu Persetujuan"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "meta": {
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer"
                                                },
                                                "last_page": {
                                                    "type": "integer"
                                                },
                                                "per_page": {
                                                    "type": "integer"
                                                },
                                                "total": {
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Leave"
                ],
                "summary": "Mengajukan cuti baru",
                "description": "Membuat pengajuan cuti baru dengan validasi saldo cuti dan overlap tanggal",
                "operationId": "0240808da1cac5a2e19b1785e88a026f",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "leave_type_id",
                                    "start_date",
                                    "end_date",
                                    "reason"
                                ],
                                "properties": {
                                    "leave_type_id": {
                                        "description": "ID jenis cuti",
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "start_date": {
                                        "description": "Tanggal mulai cuti (harus >= hari ini)",
                                        "type": "string",
                                        "format": "date",
                                        "example": "2026-03-01"
                                    },
                                    "end_date": {
                                        "description": "Tanggal selesai cuti",
                                        "type": "string",
                                        "format": "date",
                                        "example": "2026-03-05"
                                    },
                                    "is_half_day": {
                                        "description": "Apakah cuti setengah hari",
                                        "type": "boolean",
                                        "example": false
                                    },
                                    "half_day_type": {
                                        "description": "Jenis setengah hari (wajib jika is_half_day=true)",
                                        "type": "string",
                                        "enum": [
                                            "morning",
                                            "afternoon"
                                        ]
                                    },
                                    "reason": {
                                        "description": "Alasan pengajuan cuti",
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "Liburan keluarga"
                                    },
                                    "attachment": {
                                        "description": "Lampiran (jpg, jpeg, png, pdf, max 2MB)",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "emergency_contact": {
                                        "description": "Kontak darurat selama cuti",
                                        "type": "string",
                                        "maxLength": 100,
                                        "example": "081234567890"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Pengajuan cuti berhasil dibuat",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengajuan cuti berhasil dibuat."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "request_number": {
                                                    "type": "string",
                                                    "example": "LV20260001"
                                                },
                                                "leave_type": {
                                                    "type": "string",
                                                    "example": "Cuti Tahunan"
                                                },
                                                "start_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-03-01"
                                                },
                                                "end_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-03-05"
                                                },
                                                "total_days": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 5
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "pending"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validasi gagal atau saldo cuti tidak mencukupi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Sisa cuti tidak mencukupi."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/leaves/{id}": {
            "get": {
                "tags": [
                    "Leave"
                ],
                "summary": "Mendapatkan detail pengajuan cuti",
                "description": "Mengembalikan detail lengkap pengajuan cuti termasuk informasi approval",
                "operationId": "1e5f377eb6a7b686203fa4f298ef8bbc",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengajuan cuti",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Detail pengajuan cuti berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "request_number": {
                                                    "type": "string",
                                                    "example": "LV20260001"
                                                },
                                                "leave_type": {
                                                    "type": "string",
                                                    "example": "Cuti Tahunan"
                                                },
                                                "start_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-03-01"
                                                },
                                                "end_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-03-05"
                                                },
                                                "total_days": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 5
                                                },
                                                "is_half_day": {
                                                    "type": "boolean",
                                                    "example": false
                                                },
                                                "reason": {
                                                    "type": "string",
                                                    "example": "Liburan keluarga"
                                                },
                                                "attachment": {
                                                    "type": "string",
                                                    "example": "https://example.com/storage/leave-attachments/1/file.pdf",
                                                    "nullable": true
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "approved"
                                                },
                                                "status_label": {
                                                    "type": "string",
                                                    "example": "Disetujui"
                                                },
                                                "approved_by": {
                                                    "type": "string",
                                                    "example": "John Doe",
                                                    "nullable": true
                                                },
                                                "approved_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-02-12 10:30:00",
                                                    "nullable": true
                                                },
                                                "rejection_reason": {
                                                    "type": "string",
                                                    "nullable": true
                                                },
                                                "created_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-02-12 08:00:00"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Data tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/leaves/{id}/cancel": {
            "post": {
                "tags": [
                    "Leave"
                ],
                "summary": "Membatalkan pengajuan cuti",
                "description": "Membatalkan pengajuan cuti yang masih pending atau approved (dengan syarat belum dimulai)",
                "operationId": "59904619ed7807bbb7d721f6fc06b603",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengajuan cuti",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "reason": {
                                        "description": "Alasan pembatalan (opsional)",
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "Perubahan rencana mendadak"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Pengajuan cuti berhasil dibatalkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Cuti berhasil dibatalkan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Data tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Cuti tidak dapat dibatalkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Cuti yang sudah berjalan tidak dapat dibatalkan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/leaves/balance": {
            "get": {
                "tags": [
                    "Leave"
                ],
                "summary": "Mendapatkan saldo cuti",
                "description": "Mengembalikan informasi saldo cuti karyawan untuk semua jenis cuti",
                "operationId": "7b3713dabc49b5a5003031680eae2f6a",
                "parameters": [
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Tahun saldo cuti (default: tahun berjalan)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Saldo cuti berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "leave_type_id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "leave_type_name": {
                                                        "type": "string",
                                                        "example": "Cuti Tahunan"
                                                    },
                                                    "year": {
                                                        "type": "integer",
                                                        "example": 2026
                                                    },
                                                    "entitled_days": {
                                                        "description": "Hak cuti",
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 12
                                                    },
                                                    "used_days": {
                                                        "description": "Cuti terpakai",
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 5
                                                    },
                                                    "pending_days": {
                                                        "description": "Cuti dalam proses",
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 2
                                                    },
                                                    "remaining_days": {
                                                        "description": "Sisa cuti",
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 5
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/leaves/types": {
            "get": {
                "tags": [
                    "Leave"
                ],
                "summary": "Mendapatkan daftar jenis cuti",
                "description": "Mengembalikan daftar semua jenis cuti yang aktif di perusahaan",
                "operationId": "e63a901ac998ca8582ff3d32707a82df",
                "responses": {
                    "200": {
                        "description": "Daftar jenis cuti berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "example": "Cuti Tahunan"
                                                    },
                                                    "quota": {
                                                        "description": "Kuota default per tahun",
                                                        "type": "integer",
                                                        "example": 12
                                                    },
                                                    "is_paid": {
                                                        "description": "Apakah cuti dibayar",
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "requires_attachment": {
                                                        "description": "Apakah memerlukan lampiran",
                                                        "type": "boolean",
                                                        "example": false
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/office-locations": {
            "get": {
                "tags": [
                    "OfficeLocation"
                ],
                "summary": "Daftar Lokasi Kantor",
                "description": "Menampilkan daftar semua lokasi kantor yang aktif di perusahaan. Diurutkan berdasarkan nama.",
                "operationId": "ed9ae872ef7c7eca34bd27d3a05ab04b",
                "responses": {
                    "200": {
                        "description": "Daftar lokasi kantor berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "example": "Kantor Pusat Jakarta"
                                                    },
                                                    "code": {
                                                        "type": "string",
                                                        "example": "HQ-JKT",
                                                        "nullable": true
                                                    },
                                                    "address": {
                                                        "type": "string",
                                                        "example": "Jl. Sudirman No. 123"
                                                    },
                                                    "city": {
                                                        "type": "string",
                                                        "example": "Jakarta Selatan",
                                                        "nullable": true
                                                    },
                                                    "province": {
                                                        "type": "string",
                                                        "example": "DKI Jakarta",
                                                        "nullable": true
                                                    },
                                                    "latitude": {
                                                        "type": "number",
                                                        "format": "double",
                                                        "example": -6.2088
                                                    },
                                                    "longitude": {
                                                        "type": "number",
                                                        "format": "double",
                                                        "example": 106.8456
                                                    },
                                                    "radius": {
                                                        "description": "Radius validasi GPS dalam meter",
                                                        "type": "integer",
                                                        "example": 100
                                                    },
                                                    "is_active": {
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "is_headquarters": {
                                                        "type": "boolean",
                                                        "example": true
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/office-locations/assigned": {
            "get": {
                "tags": [
                    "OfficeLocation"
                ],
                "summary": "Lokasi Kantor yang Ditugaskan",
                "description": "Menampilkan daftar lokasi kantor yang ditugaskan kepada karyawan yang sedang login. Karyawan hanya dapat melakukan absensi di lokasi yang ditugaskan.",
                "operationId": "6907d5ac9e6c653464d9cbb697cb85b6",
                "responses": {
                    "200": {
                        "description": "Daftar lokasi kantor yang ditugaskan berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "example": "Kantor Pusat Jakarta"
                                                    },
                                                    "code": {
                                                        "type": "string",
                                                        "example": "HQ-JKT",
                                                        "nullable": true
                                                    },
                                                    "address": {
                                                        "type": "string",
                                                        "example": "Jl. Sudirman No. 123"
                                                    },
                                                    "city": {
                                                        "type": "string",
                                                        "example": "Jakarta Selatan",
                                                        "nullable": true
                                                    },
                                                    "province": {
                                                        "type": "string",
                                                        "example": "DKI Jakarta",
                                                        "nullable": true
                                                    },
                                                    "latitude": {
                                                        "type": "number",
                                                        "format": "double",
                                                        "example": -6.2088
                                                    },
                                                    "longitude": {
                                                        "type": "number",
                                                        "format": "double",
                                                        "example": 106.8456
                                                    },
                                                    "radius": {
                                                        "type": "integer",
                                                        "example": 100
                                                    },
                                                    "is_active": {
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "is_headquarters": {
                                                        "type": "boolean",
                                                        "example": true
                                                    },
                                                    "is_primary": {
                                                        "description": "Apakah ini lokasi utama karyawan",
                                                        "type": "boolean",
                                                        "example": true
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Employee tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Employee not found for this user."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/office-locations/{id}": {
            "get": {
                "tags": [
                    "OfficeLocation"
                ],
                "summary": "Detail Lokasi Kantor",
                "description": "Menampilkan detail lokasi kantor berdasarkan ID.",
                "operationId": "a73c85a2090c5d6ef44f791766d356f0",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID lokasi kantor",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Detail lokasi kantor berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "name": {
                                                    "type": "string",
                                                    "example": "Kantor Pusat Jakarta"
                                                },
                                                "code": {
                                                    "type": "string",
                                                    "example": "HQ-JKT",
                                                    "nullable": true
                                                },
                                                "address": {
                                                    "type": "string",
                                                    "example": "Jl. Sudirman No. 123"
                                                },
                                                "city": {
                                                    "type": "string",
                                                    "example": "Jakarta Selatan",
                                                    "nullable": true
                                                },
                                                "province": {
                                                    "type": "string",
                                                    "example": "DKI Jakarta",
                                                    "nullable": true
                                                },
                                                "latitude": {
                                                    "type": "number",
                                                    "format": "double",
                                                    "example": -6.2088
                                                },
                                                "longitude": {
                                                    "type": "number",
                                                    "format": "double",
                                                    "example": 106.8456
                                                },
                                                "radius": {
                                                    "type": "integer",
                                                    "example": 100
                                                },
                                                "is_active": {
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "is_headquarters": {
                                                    "type": "boolean",
                                                    "example": true
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Lokasi kantor tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Office location not found."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/office-locations/validate-gps": {
            "post": {
                "tags": [
                    "OfficeLocation"
                ],
                "summary": "Validasi GPS",
                "description": "Memvalidasi koordinat GPS karyawan terhadap lokasi kantor yang ditugaskan. Mengembalikan apakah lokasi valid untuk absensi dan jarak ke kantor terdekat.",
                "operationId": "8f57fc9c9a6eb0c87f2eb8c10c63e6bb",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "latitude",
                                    "longitude"
                                ],
                                "properties": {
                                    "latitude": {
                                        "description": "Latitude koordinat GPS (-90 sampai 90)",
                                        "type": "number",
                                        "format": "double",
                                        "example": -6.2088
                                    },
                                    "longitude": {
                                        "description": "Longitude koordinat GPS (-180 sampai 180)",
                                        "type": "number",
                                        "format": "double",
                                        "example": 106.8456
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Hasil validasi GPS",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "data": {
                                            "properties": {
                                                "valid": {
                                                    "description": "Apakah lokasi valid untuk absensi",
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "office_location_id": {
                                                    "description": "ID lokasi kantor terdekat yang valid",
                                                    "type": "integer",
                                                    "example": 1,
                                                    "nullable": true
                                                },
                                                "distance": {
                                                    "description": "Jarak ke kantor terdekat dalam meter",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 45.5,
                                                    "nullable": true
                                                },
                                                "reason": {
                                                    "description": "Alasan jika tidak valid (no_assigned_offices, no_active_offices, outside_radius)",
                                                    "type": "string",
                                                    "example": "outside_radius",
                                                    "nullable": true
                                                },
                                                "office": {
                                                    "description": "Detail lokasi kantor jika valid",
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "Kantor Pusat Jakarta"
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "example": "Jl. Sudirman No. 123"
                                                        },
                                                        "latitude": {
                                                            "type": "number",
                                                            "format": "double",
                                                            "example": -6.2088
                                                        },
                                                        "longitude": {
                                                            "type": "number",
                                                            "format": "double",
                                                            "example": 106.8456
                                                        },
                                                        "radius": {
                                                            "type": "integer",
                                                            "example": 100
                                                        }
                                                    },
                                                    "type": "object",
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Employee tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Employee not found for this user."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/overtimes": {
            "get": {
                "tags": [
                    "Overtime"
                ],
                "summary": "Daftar pengajuan lembur",
                "description": "Mendapatkan daftar pengajuan lembur karyawan dengan filter status dan tanggal",
                "operationId": "6b20c4cacfeb6ef59269b630a500f279",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter berdasarkan status",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "approved",
                                "rejected",
                                "cancelled"
                            ]
                        }
                    },
                    {
                        "name": "start_date",
                        "in": "query",
                        "description": "Tanggal awal filter",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "end_date",
                        "in": "query",
                        "description": "Tanggal akhir filter",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Nomor halaman",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar pengajuan lembur",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "date": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-02-15"
                                                    },
                                                    "start_time": {
                                                        "type": "string",
                                                        "example": "18:00"
                                                    },
                                                    "end_time": {
                                                        "type": "string",
                                                        "example": "21:00"
                                                    },
                                                    "overtime_hours": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 3
                                                    },
                                                    "overtime_type": {
                                                        "type": "string",
                                                        "enum": [
                                                            "weekday",
                                                            "weekend",
                                                            "holiday"
                                                        ]
                                                    },
                                                    "overtime_type_label": {
                                                        "type": "string",
                                                        "example": "Hari Kerja"
                                                    },
                                                    "overtime_amount": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 150000
                                                    },
                                                    "reason": {
                                                        "type": "string",
                                                        "example": "Menyelesaikan deadline project"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "pending",
                                                            "approved",
                                                            "rejected",
                                                            "cancelled"
                                                        ]
                                                    },
                                                    "status_label": {
                                                        "type": "string",
                                                        "example": "Menunggu"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "meta": {
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "last_page": {
                                                    "type": "integer",
                                                    "example": 3
                                                },
                                                "per_page": {
                                                    "type": "integer",
                                                    "example": 15
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "example": 42
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Overtime"
                ],
                "summary": "Buat pengajuan lembur",
                "description": "Membuat pengajuan lembur baru dengan menghitung jam lembur dan estimasi upah lembur",
                "operationId": "230f7ea1bd46d5dcf49e72c1a51b43ed",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "date",
                                    "start_time",
                                    "end_time",
                                    "reason"
                                ],
                                "properties": {
                                    "date": {
                                        "description": "Tanggal lembur",
                                        "type": "string",
                                        "format": "date",
                                        "example": "2026-02-15"
                                    },
                                    "start_time": {
                                        "description": "Jam mulai lembur (format HH:mm)",
                                        "type": "string",
                                        "example": "18:00"
                                    },
                                    "end_time": {
                                        "description": "Jam selesai lembur (format HH:mm)",
                                        "type": "string",
                                        "example": "21:00"
                                    },
                                    "overtime_type": {
                                        "description": "Jenis lembur (opsional, akan otomatis terdeteksi jika tidak diisi)",
                                        "type": "string",
                                        "enum": [
                                            "weekday",
                                            "weekend",
                                            "holiday"
                                        ],
                                        "example": "weekday"
                                    },
                                    "reason": {
                                        "description": "Alasan lembur",
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "Menyelesaikan deadline project urgent"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Pengajuan lembur berhasil dibuat",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengajuan lembur berhasil dibuat."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-02-15"
                                                },
                                                "start_time": {
                                                    "type": "string",
                                                    "example": "18:00"
                                                },
                                                "end_time": {
                                                    "type": "string",
                                                    "example": "21:00"
                                                },
                                                "overtime_hours": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 3
                                                },
                                                "overtime_type": {
                                                    "type": "string",
                                                    "example": "weekday"
                                                },
                                                "overtime_amount": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 150000
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "pending"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error atau sudah ada pengajuan pada tanggal tersebut",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Sudah ada pengajuan lembur pada tanggal tersebut."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/overtimes/{id}": {
            "get": {
                "tags": [
                    "Overtime"
                ],
                "summary": "Detail pengajuan lembur",
                "description": "Mendapatkan detail lengkap pengajuan lembur termasuk informasi approval",
                "operationId": "766d4f84a397874a6a49983b61b9c3da",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengajuan lembur",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Detail pengajuan lembur",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-02-15"
                                                },
                                                "start_time": {
                                                    "type": "string",
                                                    "example": "18:00"
                                                },
                                                "end_time": {
                                                    "type": "string",
                                                    "example": "21:00"
                                                },
                                                "overtime_hours": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 3
                                                },
                                                "overtime_type": {
                                                    "type": "string",
                                                    "example": "weekday"
                                                },
                                                "overtime_type_label": {
                                                    "type": "string",
                                                    "example": "Hari Kerja"
                                                },
                                                "overtime_amount": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 150000
                                                },
                                                "formatted_amount": {
                                                    "type": "string",
                                                    "example": "Rp 150.000"
                                                },
                                                "reason": {
                                                    "type": "string",
                                                    "example": "Menyelesaikan deadline project"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "approved"
                                                },
                                                "status_label": {
                                                    "type": "string",
                                                    "example": "Disetujui"
                                                },
                                                "approved_by": {
                                                    "type": "string",
                                                    "example": "John Doe",
                                                    "nullable": true
                                                },
                                                "approved_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "nullable": true
                                                },
                                                "rejection_reason": {
                                                    "type": "string",
                                                    "nullable": true
                                                },
                                                "created_at": {
                                                    "type": "string",
                                                    "format": "date-time"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Data tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/overtimes/{id}/cancel": {
            "post": {
                "tags": [
                    "Overtime"
                ],
                "summary": "Batalkan pengajuan lembur",
                "description": "Membatalkan pengajuan lembur dengan status pending",
                "operationId": "8ff729db00202c52225fe6e0f87d0125",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID pengajuan lembur",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Pengajuan berhasil dibatalkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengajuan lembur berhasil dibatalkan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Data tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Tidak dapat dibatalkan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Hanya pengajuan dengan status menunggu yang dapat dibatalkan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/overtimes/summary": {
            "get": {
                "tags": [
                    "Overtime"
                ],
                "summary": "Ringkasan lembur bulanan",
                "description": "Mendapatkan ringkasan statistik lembur karyawan untuk bulan tertentu",
                "operationId": "d8f9b53313f66c7a51cde8a5edd55cfa",
                "parameters": [
                    {
                        "name": "month",
                        "in": "query",
                        "description": "Bulan (1-12)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 12,
                            "minimum": 1,
                            "example": 2
                        }
                    },
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Tahun",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 2026
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Ringkasan lembur bulanan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "total_requests": {
                                                    "description": "Total pengajuan lembur",
                                                    "type": "integer",
                                                    "example": 8
                                                },
                                                "approved_requests": {
                                                    "description": "Jumlah pengajuan disetujui",
                                                    "type": "integer",
                                                    "example": 6
                                                },
                                                "pending_requests": {
                                                    "description": "Jumlah pengajuan menunggu",
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "total_hours": {
                                                    "description": "Total jam lembur yang disetujui",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 24.5
                                                },
                                                "total_amount": {
                                                    "description": "Total upah lembur yang disetujui",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 1250000
                                                },
                                                "formatted_total_amount": {
                                                    "description": "Total upah lembur dalam format Rupiah",
                                                    "type": "string",
                                                    "example": "Rp 1.250.000"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/payslips": {
            "get": {
                "tags": [
                    "Payslip"
                ],
                "summary": "Daftar Slip Gaji",
                "description": "Menampilkan daftar slip gaji karyawan yang sudah dibayar. Bisa difilter berdasarkan tahun.",
                "operationId": "cfe722e101219306775e8b66b6ef9457",
                "parameters": [
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Filter berdasarkan tahun (contoh: 2026)",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "example": 2026
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Nomor halaman untuk pagination",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan daftar slip gaji",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "payroll_id": {
                                                        "type": "integer",
                                                        "example": 5
                                                    },
                                                    "period": {
                                                        "type": "string",
                                                        "example": "Januari 2026"
                                                    },
                                                    "period_month": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "period_year": {
                                                        "type": "integer",
                                                        "example": 2026
                                                    },
                                                    "net_salary": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 8500000
                                                    },
                                                    "formatted_net_salary": {
                                                        "type": "string",
                                                        "example": "Rp 8.500.000"
                                                    },
                                                    "payment_date": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-02-01"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "example": "paid"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/payslips/{id}": {
            "get": {
                "tags": [
                    "Payslip"
                ],
                "summary": "Detail Slip Gaji",
                "description": "Menampilkan detail slip gaji termasuk rincian penghasilan (earnings) dan potongan (deductions).",
                "operationId": "0122300f48caeeb937a1f6f77d08ad40",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID dari slip gaji (payroll_item_id)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan detail slip gaji",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "payroll_id": {
                                                    "type": "integer",
                                                    "example": 5
                                                },
                                                "period": {
                                                    "type": "string",
                                                    "example": "Januari 2026"
                                                },
                                                "period_month": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "period_year": {
                                                    "type": "integer",
                                                    "example": 2026
                                                },
                                                "employee": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "employee_id": {
                                                            "type": "string",
                                                            "example": "EMP20260001"
                                                        },
                                                        "full_name": {
                                                            "type": "string",
                                                            "example": "John Doe"
                                                        },
                                                        "department": {
                                                            "type": "string",
                                                            "example": "IT"
                                                        },
                                                        "position": {
                                                            "type": "string",
                                                            "example": "Software Engineer"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "attendance": {
                                                    "description": "Ringkasan kehadiran periode ini",
                                                    "properties": {
                                                        "working_days": {
                                                            "description": "Jumlah hari kerja",
                                                            "type": "integer",
                                                            "example": 22
                                                        },
                                                        "present_days": {
                                                            "description": "Jumlah hari hadir",
                                                            "type": "integer",
                                                            "example": 20
                                                        },
                                                        "absent_days": {
                                                            "description": "Jumlah hari tidak hadir",
                                                            "type": "integer",
                                                            "example": 2
                                                        },
                                                        "late_days": {
                                                            "description": "Jumlah hari terlambat",
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "leave_days": {
                                                            "description": "Jumlah hari cuti",
                                                            "type": "integer",
                                                            "example": 0
                                                        },
                                                        "overtime_hours": {
                                                            "description": "Jumlah jam lembur",
                                                            "type": "integer",
                                                            "example": 5
                                                        },
                                                        "attendance_percentage": {
                                                            "description": "Persentase kehadiran",
                                                            "type": "number",
                                                            "format": "float",
                                                            "example": 90.9
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "base_salary": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 8000000
                                                },
                                                "earnings": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "name": {
                                                                "type": "string",
                                                                "example": "Tunjangan Transport"
                                                            },
                                                            "amount": {
                                                                "type": "number",
                                                                "format": "float",
                                                                "example": 500000
                                                            },
                                                            "formatted_amount": {
                                                                "type": "string",
                                                                "example": "Rp 500.000"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                },
                                                "deductions": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "name": {
                                                                "type": "string",
                                                                "example": "BPJS Kesehatan"
                                                            },
                                                            "amount": {
                                                                "type": "number",
                                                                "format": "float",
                                                                "example": 80000
                                                            },
                                                            "formatted_amount": {
                                                                "type": "string",
                                                                "example": "Rp 80.000"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                },
                                                "total_earnings": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 8500000
                                                },
                                                "total_deductions": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 200000
                                                },
                                                "net_salary": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 8300000
                                                },
                                                "formatted_base_salary": {
                                                    "type": "string",
                                                    "example": "Rp 8.000.000"
                                                },
                                                "formatted_total_earnings": {
                                                    "type": "string",
                                                    "example": "Rp 8.500.000"
                                                },
                                                "formatted_total_deductions": {
                                                    "type": "string",
                                                    "example": "Rp 200.000"
                                                },
                                                "formatted_net_salary": {
                                                    "type": "string",
                                                    "example": "Rp 8.300.000"
                                                },
                                                "payment_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-02-01"
                                                },
                                                "payment_method": {
                                                    "type": "string",
                                                    "example": "Transfer Bank"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "paid"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Slip gaji tidak ditemukan atau tidak dapat diakses",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/payslips/{id}/download": {
            "get": {
                "tags": [
                    "Payslip"
                ],
                "summary": "Download Slip Gaji PDF",
                "description": "Mendapatkan URL untuk mengunduh slip gaji dalam format PDF.",
                "operationId": "6d0e4f7ffa6632ab2530281116022d6f",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID dari slip gaji (payroll_item_id)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan URL download",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "download_url": {
                                                    "type": "string",
                                                    "example": "https://app.gajipro.com/api/v1/payslips/1/pdf?token=xxx"
                                                },
                                                "filename": {
                                                    "type": "string",
                                                    "example": "Slip_Gaji_EMP20260001_1_2026.pdf"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Slip gaji tidak ditemukan atau tidak dapat diakses",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/payslips/summary": {
            "get": {
                "tags": [
                    "Payslip"
                ],
                "summary": "Ringkasan Penghasilan Tahunan",
                "description": "Menampilkan ringkasan penghasilan karyawan per tahun, termasuk total earnings, deductions, net salary, dan breakdown per bulan.",
                "operationId": "63e5555da6859ca3991044f148a5d287",
                "parameters": [
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Tahun untuk ringkasan (contoh: 2026)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 2026
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan ringkasan penghasilan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "year": {
                                                    "type": "integer",
                                                    "example": 2026
                                                },
                                                "total_months": {
                                                    "type": "integer",
                                                    "example": 12
                                                },
                                                "total_earnings": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 102000000
                                                },
                                                "total_deductions": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 2400000
                                                },
                                                "total_net_salary": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 99600000
                                                },
                                                "average_net_salary": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 8300000
                                                },
                                                "formatted_total_earnings": {
                                                    "type": "string",
                                                    "example": "Rp 102.000.000"
                                                },
                                                "formatted_total_deductions": {
                                                    "type": "string",
                                                    "example": "Rp 2.400.000"
                                                },
                                                "formatted_total_net_salary": {
                                                    "type": "string",
                                                    "example": "Rp 99.600.000"
                                                },
                                                "formatted_average_net_salary": {
                                                    "type": "string",
                                                    "example": "Rp 8.300.000"
                                                },
                                                "monthly_breakdown": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "month": {
                                                                "type": "integer",
                                                                "example": 1
                                                            },
                                                            "month_name": {
                                                                "type": "string",
                                                                "example": "Januari"
                                                            },
                                                            "net_salary": {
                                                                "type": "number",
                                                                "format": "float",
                                                                "example": 8300000
                                                            },
                                                            "formatted_net_salary": {
                                                                "type": "string",
                                                                "example": "Rp 8.300.000"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validasi gagal",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "The year field is required."
                                        },
                                        "errors": {
                                            "properties": {
                                                "year": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "example": "The year field is required."
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/reimbursements": {
            "get": {
                "tags": [
                    "Reimbursement"
                ],
                "summary": "Daftar pengajuan reimbursement karyawan",
                "description": "Mengambil daftar semua pengajuan reimbursement milik karyawan yang sedang login dengan pagination. Dapat difilter berdasarkan status dan rentang tanggal pengeluaran.",
                "operationId": "23e2f3d7bb849cb0a714caf9acf42261",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter berdasarkan status reimbursement",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "approved",
                                "rejected",
                                "paid"
                            ]
                        }
                    },
                    {
                        "name": "start_date",
                        "in": "query",
                        "description": "Tanggal awal pengeluaran (format: Y-m-d)",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-01-01"
                        }
                    },
                    {
                        "name": "end_date",
                        "in": "query",
                        "description": "Tanggal akhir pengeluaran (format: Y-m-d)",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-01-31"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Nomor halaman untuk pagination",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daftar reimbursement berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "category": {
                                                        "type": "string",
                                                        "example": "Transportasi"
                                                    },
                                                    "amount": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 150000
                                                    },
                                                    "formatted_amount": {
                                                        "type": "string",
                                                        "example": "Rp 150.000"
                                                    },
                                                    "description": {
                                                        "type": "string",
                                                        "example": "Biaya taksi ke kantor cabang"
                                                    },
                                                    "expense_date": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-02-10"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "example": "pending"
                                                    },
                                                    "status_label": {
                                                        "type": "string",
                                                        "example": "Pending"
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "example": "2026-02-12 10:30:00"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "meta": {
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "last_page": {
                                                    "type": "integer",
                                                    "example": 3
                                                },
                                                "per_page": {
                                                    "type": "integer",
                                                    "example": 15
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "example": 42
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error - Parameter tidak valid",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "The status field must be one of: pending, approved, rejected, paid."
                                        },
                                        "errors": {
                                            "properties": {
                                                "status": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "example": "The status field must be one of: pending, approved, rejected, paid."
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Reimbursement"
                ],
                "summary": "Buat pengajuan reimbursement baru",
                "description": "Membuat pengajuan reimbursement baru untuk karyawan yang sedang login. Dapat menyertakan bukti struk/kwitansi dalam bentuk file gambar atau PDF.",
                "operationId": "fc4dbefe9013565b80c6848b67a79ed0",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "category_id",
                                    "amount",
                                    "description",
                                    "expense_date"
                                ],
                                "properties": {
                                    "category_id": {
                                        "description": "ID kategori reimbursement",
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "amount": {
                                        "description": "Jumlah reimbursement dalam Rupiah (tanpa format)",
                                        "type": "number",
                                        "format": "float",
                                        "example": 150000
                                    },
                                    "description": {
                                        "description": "Deskripsi pengeluaran (maksimal 500 karakter)",
                                        "type": "string",
                                        "example": "Biaya taksi untuk kunjungan ke kantor cabang Jakarta"
                                    },
                                    "expense_date": {
                                        "description": "Tanggal pengeluaran (format: Y-m-d)",
                                        "type": "string",
                                        "format": "date",
                                        "example": "2026-02-10"
                                    },
                                    "receipt": {
                                        "description": "File bukti struk/kwitansi (opsional). Format: JPG, PNG, atau PDF. Maksimal 2MB.",
                                        "type": "string",
                                        "format": "binary",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Reimbursement berhasil dibuat",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Pengajuan reimbursement berhasil dibuat."
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "category": {
                                                    "type": "string",
                                                    "example": "Transportasi"
                                                },
                                                "amount": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 150000
                                                },
                                                "formatted_amount": {
                                                    "type": "string",
                                                    "example": "Rp 150.000"
                                                },
                                                "description": {
                                                    "type": "string",
                                                    "example": "Biaya taksi ke kantor cabang"
                                                },
                                                "expense_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-02-10"
                                                },
                                                "receipt_url": {
                                                    "type": "string",
                                                    "example": "https://example.com/storage/reimbursement-receipts/1/receipt.jpg",
                                                    "nullable": true
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "pending"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error atau jumlah melebihi batas kategori",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Jumlah melebihi batas maksimal kategori (Rp 500.000)."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/reimbursements/{id}": {
            "get": {
                "tags": [
                    "Reimbursement"
                ],
                "summary": "Detail pengajuan reimbursement",
                "description": "Mengambil informasi detail dari satu pengajuan reimbursement berdasarkan ID, termasuk informasi kategori, approver, dan status pembayaran.",
                "operationId": "0d4b319c940662291ba9e788d51b3029",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID reimbursement",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Detail reimbursement berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "category": {
                                                    "properties": {
                                                        "id": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "example": "Transportasi"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "amount": {
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 150000
                                                },
                                                "formatted_amount": {
                                                    "type": "string",
                                                    "example": "Rp 150.000"
                                                },
                                                "description": {
                                                    "type": "string",
                                                    "example": "Biaya taksi ke kantor cabang"
                                                },
                                                "expense_date": {
                                                    "type": "string",
                                                    "format": "date",
                                                    "example": "2026-02-10"
                                                },
                                                "receipt_url": {
                                                    "type": "string",
                                                    "example": "https://example.com/storage/reimbursement-receipts/1/receipt.jpg",
                                                    "nullable": true
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "example": "approved"
                                                },
                                                "status_label": {
                                                    "type": "string",
                                                    "example": "Disetujui"
                                                },
                                                "approved_by": {
                                                    "type": "string",
                                                    "example": "John Doe",
                                                    "nullable": true
                                                },
                                                "approved_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-02-11 14:30:00",
                                                    "nullable": true
                                                },
                                                "rejection_reason": {
                                                    "type": "string",
                                                    "example": null,
                                                    "nullable": true
                                                },
                                                "paid_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": null,
                                                    "nullable": true
                                                },
                                                "payment_method": {
                                                    "type": "string",
                                                    "example": null,
                                                    "nullable": true
                                                },
                                                "created_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "example": "2026-02-10 09:15:00"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Reimbursement tidak ditemukan atau bukan milik karyawan ini",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/reimbursements/categories": {
            "get": {
                "tags": [
                    "Reimbursement"
                ],
                "summary": "Daftar kategori reimbursement aktif",
                "description": "Mengambil daftar semua kategori reimbursement yang aktif di perusahaan karyawan. Digunakan untuk memilih kategori saat membuat pengajuan reimbursement baru.",
                "operationId": "1c13c00850aa9cd3df0431cd81faeb47",
                "responses": {
                    "200": {
                        "description": "Daftar kategori berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "example": "Transportasi"
                                                    },
                                                    "description": {
                                                        "type": "string",
                                                        "example": "Biaya transportasi dinas",
                                                        "nullable": true
                                                    },
                                                    "max_amount": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 500000,
                                                        "nullable": true
                                                    },
                                                    "formatted_max_amount": {
                                                        "type": "string",
                                                        "example": "Rp 500.000",
                                                        "nullable": true
                                                    },
                                                    "requires_receipt": {
                                                        "type": "boolean",
                                                        "example": true
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/reimbursements/summary": {
            "get": {
                "tags": [
                    "Reimbursement"
                ],
                "summary": "Ringkasan reimbursement karyawan per bulan",
                "description": "Mengambil ringkasan statistik reimbursement karyawan untuk bulan dan tahun tertentu, termasuk jumlah pengajuan per status dan total nominal.",
                "operationId": "1b1f1005725cc5988e58060743797af1",
                "parameters": [
                    {
                        "name": "month",
                        "in": "query",
                        "description": "Bulan (1-12)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 2
                        }
                    },
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Tahun (format: YYYY)",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 2026
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Ringkasan reimbursement berhasil diambil",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "total_requests": {
                                                    "description": "Total pengajuan reimbursement",
                                                    "type": "integer",
                                                    "example": 5
                                                },
                                                "pending_requests": {
                                                    "description": "Jumlah pengajuan pending",
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "approved_requests": {
                                                    "description": "Jumlah pengajuan disetujui",
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "paid_requests": {
                                                    "description": "Jumlah pengajuan sudah dibayar",
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "total_amount": {
                                                    "description": "Total nominal semua pengajuan",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 750000
                                                },
                                                "approved_amount": {
                                                    "description": "Total nominal yang disetujui",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 450000
                                                },
                                                "paid_amount": {
                                                    "description": "Total nominal yang sudah dibayar",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 150000
                                                },
                                                "pending_amount": {
                                                    "description": "Total nominal yang masih pending",
                                                    "type": "number",
                                                    "format": "float",
                                                    "example": 300000
                                                },
                                                "formatted_total_amount": {
                                                    "description": "Total nominal terformat",
                                                    "type": "string",
                                                    "example": "Rp 750.000"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized - Token tidak valid atau kadaluarsa",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error - Parameter tidak valid",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "The month field must be between 1 and 12."
                                        },
                                        "errors": {
                                            "properties": {
                                                "month": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "example": "The month field must be between 1 and 12."
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/schedule": {
            "get": {
                "tags": [
                    "Schedule"
                ],
                "summary": "Jadwal kerja bulanan karyawan",
                "description": "Mengembalikan jadwal kerja karyawan untuk satu bulan penuh, menggunakan resolveScheduleForDate() untuk mendukung weekly schedule pattern dan default schedule.",
                "operationId": "71d6ec4d1a0460077d2a5a4e6c1dc1f6",
                "parameters": [
                    {
                        "name": "month",
                        "in": "query",
                        "description": "Bulan dalam format YYYY-MM. Default: bulan ini.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "2026-04"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Jadwal berhasil diambil"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "404": {
                        "description": "Data karyawan tidak ditemukan"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/tax-forms": {
            "get": {
                "tags": [
                    "Tax Form"
                ],
                "summary": "Daftar Bukti Potong 1721-A1",
                "description": "Menampilkan daftar bukti potong pajak 1721-A1 untuk karyawan yang sedang login.",
                "operationId": "e13e64e8778d00cb063b9c1ed438952d",
                "parameters": [
                    {
                        "name": "year",
                        "in": "query",
                        "description": "Filter berdasarkan tahun pajak (contoh: 2025)",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "example": 2025
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan daftar bukti potong",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "example": 1
                                                    },
                                                    "form_number": {
                                                        "type": "string",
                                                        "example": "1.1-12.345.678.9-012.000-2025"
                                                    },
                                                    "tax_year": {
                                                        "type": "integer",
                                                        "example": 2025
                                                    },
                                                    "employee_name": {
                                                        "type": "string",
                                                        "example": "John Doe"
                                                    },
                                                    "gross_salary": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 144000000
                                                    },
                                                    "formatted_gross_salary": {
                                                        "type": "string",
                                                        "example": "Rp 144.000.000"
                                                    },
                                                    "total_pph21_withheld": {
                                                        "type": "number",
                                                        "format": "float",
                                                        "example": 3600000
                                                    },
                                                    "formatted_pph21": {
                                                        "type": "string",
                                                        "example": "Rp 3.600.000"
                                                    },
                                                    "generated_at": {
                                                        "type": "string",
                                                        "format": "date",
                                                        "example": "2026-01-15"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/tax-forms/years": {
            "get": {
                "tags": [
                    "Tax Form"
                ],
                "summary": "Daftar Tahun Pajak Tersedia",
                "description": "Menampilkan daftar tahun pajak yang memiliki bukti potong untuk karyawan yang login.",
                "operationId": "20777e9981fd32446cd0329f0ec0d8fe",
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan daftar tahun",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "year": {
                                                        "type": "integer",
                                                        "example": 2025
                                                    },
                                                    "count": {
                                                        "type": "integer",
                                                        "example": 1
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/tax-forms/{id}": {
            "get": {
                "tags": [
                    "Tax Form"
                ],
                "summary": "Detail Bukti Potong 1721-A1",
                "description": "Menampilkan detail lengkap bukti potong pajak 1721-A1 termasuk rincian penghasilan dan perhitungan PPh.",
                "operationId": "eb0cb6aba50dcbdcf10d63af8cb9e92b",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID bukti potong",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan detail bukti potong",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Bukti potong tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/tax-forms/{id}/download": {
            "get": {
                "tags": [
                    "Tax Form"
                ],
                "summary": "Download Bukti Potong PDF",
                "description": "Mendapatkan URL untuk mengunduh bukti potong 1721-A1 dalam format PDF.",
                "operationId": "800e52c59a880427cf48776a13bbe123",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "ID bukti potong",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Berhasil mendapatkan URL download",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "data": {
                                            "properties": {
                                                "download_url": {
                                                    "type": "string",
                                                    "example": "https://app.gajipro.com/api/v1/tax-forms/1/pdf?token=xxx"
                                                },
                                                "filename": {
                                                    "type": "string",
                                                    "example": "Bukti_Potong_1721-A1_EMP20260001_2025.pdf"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Bukti potong tidak ditemukan",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "Data tidak ditemukan."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Tidak terautentikasi",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "example": "Unauthenticated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "sanctum": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT",
                "description": "Enter your Sanctum token (without Bearer prefix)"
            }
        }
    },
    "tags": [
        {
            "name": "Authentication",
            "description": "Login, logout, dan manajemen profil"
        },
        {
            "name": "Attendance",
            "description": "Clock in/out dan riwayat kehadiran"
        },
        {
            "name": "Leave",
            "description": "Pengajuan dan manajemen cuti"
        },
        {
            "name": "Overtime",
            "description": "Pengajuan dan manajemen lembur"
        },
        {
            "name": "Payslip",
            "description": "Slip gaji dan ringkasan penghasilan"
        },
        {
            "name": "Reimbursement",
            "description": "Pengajuan reimbursement"
        },
        {
            "name": "Announcement",
            "description": "Pengumuman perusahaan"
        },
        {
            "name": "Dashboard",
            "description": "Dashboard dan statistik untuk mobile app"
        },
        {
            "name": "Approvals",
            "description": "Approval cuti, lembur, dan reimbursement untuk manager"
        },
        {
            "name": "DeviceToken",
            "description": "Manajemen device token untuk push notification"
        },
        {
            "name": "FaceRecognition",
            "description": "Face enrollment dan verifikasi untuk absensi"
        },
        {
            "name": "OfficeLocation",
            "description": "Lokasi kantor dan validasi GPS"
        },
        {
            "name": "EmployeeOffice",
            "description": "EmployeeOffice"
        },
        {
            "name": "Schedule",
            "description": "Schedule"
        },
        {
            "name": "Tax Form",
            "description": "Tax Form"
        }
    ],
    "security": [
        {
            "sanctum": []
        }
    ]
}