{"openapi":"3.0.0","info":{"title":"Comedi API","description":"API documentation for Comedi application","license":{"name":"MIT"},"version":"1.0.0"},"servers":[{"url":"\/api","description":"API base path"}],"paths":{"\/admin\/auth\/login":{"post":{"tags":["Admin"],"summary":"Login","description":"Login: email + password, returns JWT access_token + refresh_token and user.","operationId":"0d4bd5d2bd75b40d68161afda0ef07ac","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["email","password"],"properties":{"email":{"type":"string","format":"email","example":"admin@example.com"},"password":{"type":"string","format":"password","example":"password"}},"type":"object"}}}},"responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Login successfully."},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer","example":3600},"user":{"properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"name":{"type":"string"},"email":{"type":"string"},"phone_number":{"type":"string","nullable":true}},"type":"object"}},"type":"object"}},"type":"object"}}}},"400":{"description":"Invalid credentials","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"These credentials do not match our records."},"error":{"properties":{"key":{"type":"string","example":"auth.unauthorized"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/admin\/auth\/forgot-password":{"post":{"tags":["Admin"],"summary":"Forgot password","description":"Forgot password: queues email with reset link containing a stateless JWT (`token` query).","operationId":"a030ad5ab947dcee46ed18344316b9f2","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["email"],"properties":{"email":{"type":"string","format":"email","example":"admin@example.com"}},"type":"object"}}}},"responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"If your email is registered, you will receive password reset instructions shortly."},"data":{"type":"array","items":[],"example":[]}},"type":"object"}}}},"400":{"description":"User email not registered","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"We could not find a user with that email address."},"error":{"properties":{"key":{"type":"string","example":"admin.password_reset_user_not_found"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/admin\/auth\/reset-password":{"post":{"tags":["Admin"],"summary":"Reset password","description":"Reset password: submit JWT from the reset email plus new password and confirmation.","operationId":"4fbf358eedfcf4f75780db592fbdcb42","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["token","password","password_confirmation"],"properties":{"token":{"description":"JWT from email link query","type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGc..."},"password":{"type":"string","format":"password","minLength":6,"example":"newpassword123"},"password_confirmation":{"type":"string","format":"password","example":"newpassword123"}},"type":"object"}}}},"responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Password has been reset successfully."},"data":{"type":"array","items":[],"example":[]}},"type":"object"}}}},"400":{"description":"Reset failed (invalid\/expired token, admin not found, stale token_version)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string"},"error":{"properties":{"key":{"description":"One of: admin.invalid_or_expired_reset_token, admin.invalid_reset_token, admin.password_reset_user_not_found","type":"string","example":"admin.invalid_or_expired_reset_token"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error (including password_confirmation mismatch)","content":{"application\/json":{"schema":[]}}}}}},"\/admin\/auth\/refresh-token":{"post":{"tags":["Admin"],"summary":"Refresh token","description":"Refresh tokens: submit a valid refresh_token, server returns fresh access_token + refresh_token.","operationId":"e36448ffce4750de0ec71bd7f24a84a7","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["refresh_token"],"properties":{"refresh_token":{"description":"JWT refresh token","type":"string"}},"type":"object"}}}},"responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Token refreshed successfully."},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer"},"user":{"type":"object"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Invalid or expired refresh token","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Invalid or expired refresh token."},"error":{"properties":{"key":{"type":"string","example":"jwt.exception"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/admin\/auth\/logout":{"post":{"tags":["Admin"],"summary":"Logout","description":"Logout current admin account (increments `token_version` to invalidate existing JWTs).","operationId":"12d9d47117cc79b77b180802b77422ae","responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Logout successfully."},"data":{"type":"array","items":[],"example":[]}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company-branch":{"get":{"tags":["Admin Company Branch"],"summary":"Get list of company branches","description":"List company branches with filtering and pagination.\n\nResponse uses the shared flat pagination shape from\n{@see \\App\\Http\\Controllers\\AppBaseController::pagination()}.","operationId":"002a25e792faf7562e8d98c38c4d4845","parameters":[{"name":"company_id","in":"query","description":"Filter by company id","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"search_key","in":"query","description":"Search by branch name or responsible person email","required":false,"schema":{"type":"string","maxLength":255,"example":"Tokyo"}},{"name":"prefecture_id","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":13}},{"name":"district_id","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":101}},{"name":"limit","in":"query","description":"Results per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"order_by","in":"query","description":"Sort column","required":false,"schema":{"type":"string","enum":["id","name","company_id"]}},{"name":"order_direction","in":"query","description":"Sort direction","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Company branch list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"type":"object"}},"total":{"type":"integer","example":45},"last_page":{"type":"integer","example":3},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company":{"get":{"tags":["Admin Company"],"summary":"Get list of companies","description":"List companies with filtering and pagination. Response uses the shared\n{@see \\App\\Http\\Controllers\\AppBaseController::pagination()} flat shape\n(NOT the standard success\/message\/data envelope).","operationId":"f5be04970302f023f6d4ae67f81d3edf","parameters":[{"name":"name","in":"query","required":false,"schema":{"type":"string","example":"Acme Inc"}},{"name":"address","in":"query","required":false,"schema":{"type":"string","example":"Tokyo St"}},{"name":"status","in":"query","required":false,"schema":{"description":"1=active 2=inactive","type":"integer","enum":[1,2]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["id","name","created_at"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Filtered company list","content":{"application\/json":{"schema":{"properties":{"data":{"description":"Laravel paginator payload","properties":{"current_page":{"type":"integer","example":1},"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/company"}},"per_page":{"type":"integer","example":15},"total":{"type":"integer","example":43}},"type":"object"},"total":{"type":"integer","example":43},"last_page":{"type":"integer","example":3},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Admin Company"],"summary":"Create a new company","description":"Create a new company.","operationId":"e87b14fda83cd7f7e23cb8bbe3bb45a6","requestBody":{"description":"Use `application\/json` when no file is sent. Use `multipart\/form-data` to upload `company_file` and\/or `company_avatar`.","required":true,"content":{"multipart\/form-data":{"schema":{"required":["name"],"properties":{"name":{"type":"string","example":"ABC Pvt Ltd"},"furigana":{"type":"string","example":"\u30a8\u30fc\u30d3\u30fc\u30b7\u30fc"},"email":{"type":"string","format":"email","example":"company@example.com","nullable":true},"tax_code":{"description":"Business \/ corporate registration number (\u6cd5\u4eba\u756a\u53f7).","type":"string","example":"1234567890123","nullable":true},"prefecture_id":{"description":"Prefecture ID, must exist in m_prefectures.","type":"integer","example":13,"nullable":true},"district_id":{"description":"District\/city ID, must exist in m_districts.","type":"integer","example":101,"nullable":true},"latitude":{"description":"Required with longitude when either is sent.","type":"number","format":"float","maximum":90,"minimum":-90,"example":35.681236,"nullable":true},"longitude":{"description":"Required with latitude when either is sent.","type":"number","format":"float","maximum":180,"minimum":-180,"example":139.767125,"nullable":true},"address":{"type":"string","maxLength":255,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"company_file":{"description":"Company face photo image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary"},"company_avatar":{"description":"Company logo \/ avatar image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary"},"representative_name":{"type":"string","example":"John Representative"},"business_content":{"type":"string","maxLength":2000,"example":"Healthcare staffing and care services.","nullable":true},"category_ids[]":{"description":"Company-level category IDs (repeat field for multiple values)","type":"array","items":{"type":"integer","example":1},"nullable":true},"person_in_charge_name":{"type":"string","example":"John Doe"},"person_in_charge_email":{"type":"string","format":"email","example":"john.doe@example.com"},"area":{"description":"Company area \/ region label.","type":"string","example":"Kanto","nullable":true},"person_in_charge_expenses[0][name]":{"description":"Use index 0..4 for up to 5 expense contacts.","type":"string","example":"Expense Contact","nullable":true},"person_in_charge_expenses[0][email]":{"type":"string","format":"email","example":"john.doe@example.com"}},"type":"object"}},"application\/json":{"schema":{"required":["name"],"properties":{"name":{"type":"string","example":"ABC Pvt Ltd"},"furigana":{"type":"string","example":"\u30a8\u30fc\u30d3\u30fc\u30b7\u30fc"},"email":{"type":"string","format":"email","example":"company@example.com","nullable":true},"tax_code":{"description":"Business \/ corporate registration number (\u6cd5\u4eba\u756a\u53f7).","type":"string","example":"1234567890123","nullable":true},"prefecture_id":{"description":"Prefecture ID, must exist in m_prefectures.","type":"integer","example":13,"nullable":true},"district_id":{"description":"District\/city ID, must exist in m_districts.","type":"integer","example":101,"nullable":true},"latitude":{"description":"Required with longitude when either is sent.","type":"number","format":"float","maximum":90,"minimum":-90,"example":35.681236,"nullable":true},"longitude":{"description":"Required with latitude when either is sent.","type":"number","format":"float","maximum":180,"minimum":-180,"example":139.767125,"nullable":true},"address":{"type":"string","maxLength":255,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"representative_name":{"type":"string","example":"John Representative"},"business_content":{"type":"string","maxLength":2000,"example":"Healthcare staffing and care services.","nullable":true},"category_ids":{"description":"Company-level category IDs from m_category (pivot t_company_category)","type":"array","items":{"type":"integer","example":1},"nullable":true},"person_in_charge_name":{"type":"string","example":"John Doe"},"person_in_charge_email":{"type":"string","format":"email","example":"john.doe@example.com"},"area":{"description":"Company area \/ region label.","type":"string","example":"Kanto","nullable":true},"person_in_charge_expenses":{"type":"array","items":{"properties":{"name":{"type":"string","example":"Expense Contact","nullable":true},"email":{"type":"string","format":"email","example":"john.doe@example.com"}},"type":"object"},"maxItems":5,"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company profile created successfully."},"data":{"$ref":"#\/components\/schemas\/company"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"The given data was invalid."},"errors":{"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company\/{id}":{"get":{"tags":["Admin Company"],"summary":"Get details of a company","description":"Get company detail by ID.","operationId":"e54aa1644c12879d511b90fd09cc6c14","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company detail retrieved successfully."},"data":{"$ref":"#\/components\/schemas\/company"}},"type":"object"}}}},"400":{"description":"Company not found","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company not found."},"error":{"properties":{"key":{"type":"string","example":"company.not_found"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Admin Company"],"summary":"Update an existing company","description":"Update a company's details.","operationId":"30ee8f2112aec4304c66b4e9296972c7","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"description":"Use `application\/json` when no file is sent. Use `multipart\/form-data` to upload or replace `company_file` and\/or `company_avatar`. Send `category_ids: []` to clear company-level category links.","required":true,"content":{"multipart\/form-data":{"schema":{"properties":{"name":{"type":"string","example":"Acme Inc"},"furigana":{"type":"string","example":"\u30a2\u30af\u30e1"},"email":{"type":"string","format":"email","example":"info@acme.com"},"tax_code":{"description":"Business \/ corporate registration number (\u6cd5\u4eba\u756a\u53f7).","type":"string","example":"1234567890123","nullable":true},"prefecture_id":{"description":"Prefecture ID, must exist in m_prefectures.","type":"integer","example":13,"nullable":true},"district_id":{"description":"District\/city ID, must exist in m_districts.","type":"integer","example":101,"nullable":true},"latitude":{"description":"Required with longitude when either is sent.","type":"number","format":"float","maximum":90,"minimum":-90,"example":35.681236,"nullable":true},"longitude":{"description":"Required with latitude when either is sent.","type":"number","format":"float","maximum":180,"minimum":-180,"example":139.767125,"nullable":true},"address":{"type":"string","maxLength":255,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"company_file":{"description":"Replace company face photo image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary"},"company_avatar":{"description":"Replace company logo \/ avatar image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary"},"representative_name":{"type":"string","example":"Jane Representative"},"business_content":{"type":"string","maxLength":2000,"example":"Healthcare staffing and care services.","nullable":true},"category_ids[]":{"description":"Company-level category IDs (repeat field for multiple values). Send empty to clear links.","type":"array","items":{"type":"integer","example":1},"nullable":true},"person_in_charge_name":{"type":"string","example":"Jane Doe"},"person_in_charge_email":{"type":"string","format":"email","example":"jane.doe@acme.com"},"area":{"description":"Company area \/ region label.","type":"string","example":"Kanto","nullable":true},"person_in_charge_expenses[0][name]":{"description":"Use index 0..4 for up to 5 expense contacts.","type":"string","example":"Expense Contact","nullable":true},"person_in_charge_expenses[0][email]":{"type":"string","format":"email","example":"accounting@acme.com"}},"type":"object"}},"application\/json":{"schema":{"properties":{"name":{"type":"string","example":"Acme Inc"},"furigana":{"type":"string","example":"\u30a2\u30af\u30e1"},"email":{"type":"string","format":"email","example":"info@acme.com"},"tax_code":{"description":"Business \/ corporate registration number (\u6cd5\u4eba\u756a\u53f7).","type":"string","example":"1234567890123","nullable":true},"prefecture_id":{"description":"Prefecture ID, must exist in m_prefectures.","type":"integer","example":13,"nullable":true},"district_id":{"description":"District\/city ID, must exist in m_districts.","type":"integer","example":101,"nullable":true},"latitude":{"description":"Required with longitude when either is sent.","type":"number","format":"float","maximum":90,"minimum":-90,"example":35.681236,"nullable":true},"longitude":{"description":"Required with latitude when either is sent.","type":"number","format":"float","maximum":180,"minimum":-180,"example":139.767125,"nullable":true},"address":{"type":"string","maxLength":255,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"representative_name":{"type":"string","example":"Jane Representative"},"business_content":{"type":"string","maxLength":2000,"example":"Healthcare staffing and care services.","nullable":true},"category_ids":{"description":"Company-level category IDs from m_category (pivot t_company_category). Empty array clears links.","type":"array","items":{"type":"integer","example":1},"nullable":true},"person_in_charge_name":{"type":"string","example":"Jane Doe"},"person_in_charge_email":{"type":"string","format":"email","example":"jane.doe@acme.com"},"area":{"description":"Company area \/ region label.","type":"string","example":"Kanto","nullable":true},"person_in_charge_expenses":{"type":"array","items":{"properties":{"name":{"type":"string","example":"Expense Contact","nullable":true},"email":{"type":"string","format":"email","example":"accounting@acme.com"}},"type":"object"},"maxItems":5,"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Company updated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company updated successfully."},"data":{"$ref":"#\/components\/schemas\/company"}},"type":"object"}}}},"400":{"description":"Company not found","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company not found."},"error":{"properties":{"key":{"type":"string","example":"company.not_found"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company\/{id}\/status":{"put":{"tags":["Admin Company"],"summary":"Update company active\/inactive status","description":"Activate or inactivate a company.","operationId":"6fd7b2d0e8aed6203b019d28af549d46","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["status"],"properties":{"status":{"description":"1=active 2=inactive","type":"integer","enum":[1,2],"example":2}},"type":"object"}}}},"responses":{"200":{"description":"Status updated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company status updated successfully."},"data":{"$ref":"#\/components\/schemas\/company"}},"type":"object"}}}},"400":{"description":"Business rule error","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"This company cannot be set inactive."},"error":{"properties":{"key":{"type":"string","example":"company.cannot_inactivate"},"content":{"type":"string"},"reasons":{"type":"array","items":{"properties":{"key":{"type":"string","example":"company.has_live_jobs"},"content":{"type":"string"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company-profile":{"get":{"tags":["Admin"],"summary":"Get list of company users","description":"List company users with filtering and pagination.","operationId":"b94768c0ca8a58e2dc192e109f638a8d","parameters":[{"name":"name","in":"query","description":"Company user name to filter","required":false,"schema":{"type":"string","example":"Acme Profile"}},{"name":"company_id","in":"query","description":"Filter by company ID","required":false,"schema":{"type":"integer","example":123}},{"name":"limit","in":"query","description":"Results per page (default: 20, max: 100)","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"order_by","in":"query","description":"Sort column (single field; use with order_direction)","required":false,"schema":{"type":"string","enum":["id","name","company_id","created_at"]}},{"name":"order_direction","in":"query","description":"asc or desc (with order_by)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Filtered company user list","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company profiles listed successfully."},"data":{"description":"Laravel paginator payload","properties":{"current_page":{"type":"integer","example":1},"data":{"type":"array","items":{"type":"object"}},"per_page":{"type":"integer","example":15},"total":{"type":"integer","example":43}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Admin"],"summary":"Create a new company user","description":"Create a new company user.","operationId":"e32fe6da0d8f9c44810b388630ff3353","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["name","company_id","email"],"properties":{"name":{"description":"Name of the company user","type":"string","maxLength":255,"example":"Acme Profile"},"company_id":{"description":"ID of the associated company","type":"integer","example":123},"email":{"description":"Login email that receives the generated initial password; must be unique","type":"string","format":"email","maxLength":255,"example":"acme@example.com"},"phone_number":{"description":"Phone number of the company user","type":"string","maxLength":255,"example":"0909090909"}},"type":"object"}}}},"responses":{"200":{"description":"Company user created successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company profile created successfully."},"data":{"properties":{"id":{"type":"integer","example":321},"user_id":{"type":"integer","example":456},"company_id":{"type":"integer","example":123},"name":{"type":"string","example":"Acme Profile"},"email":{"type":"string","example":"acme@example.com"},"phone_number":{"type":"string","example":"0909090909"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (missing required, unknown company_id, duplicate email\/phone)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"The given data was invalid."},"errors":{"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/company-profile\/{id}":{"get":{"tags":["Admin"],"summary":"Get details of a company user","description":"Returns details of a specific company user by ID.","operationId":"getCompanyProfileDetail","parameters":[{"name":"id","in":"path","description":"ID of the company user","required":true,"schema":{"type":"integer","example":321}}],"responses":{"200":{"description":"Company user retrieved successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company user detail retrieved successfully"},"data":{"properties":{"id":{"type":"integer","example":321},"user_id":{"type":"integer","example":456},"company_id":{"type":"integer","example":123},"name":{"type":"string","example":"Acme Profile"},"email":{"type":"string","example":"acme@example.com"},"phone_number":{"type":"string","example":"0909090909"},"company":{"properties":{"id":{"type":"integer","example":123},"name":{"type":"string","example":"Acme Inc"}},"type":"object"}},"type":"object"}},"type":"object"}}}},"400":{"description":"Company profile not found","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company profile not found."},"error":{"properties":{"key":{"type":"string","example":"company_profile.not_found"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Admin"],"summary":"Update a company user","description":"Swagger endpoint: `update` (PUT `\/admin\/company-profile\/{id}`).\n\nUpdate a company user.","operationId":"e99787d8fd45049c6e541f8da34e03e6","parameters":[{"name":"id","in":"path","description":"ID of the company user to update","required":true,"schema":{"type":"integer","example":321}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":[],"properties":{"email":{"description":"Login email; must be unique","type":"string","format":"email","maxLength":255,"example":"new-acme@example.com"},"company_id":{"description":"ID of the associated company","type":"integer","example":123},"name":{"description":"Name of the company user","type":"string","maxLength":255,"example":"Acme Profile"},"phone_number":{"description":"Phone number of the company user","type":"string","maxLength":255,"example":"0909090909"}},"type":"object"}}}},"responses":{"200":{"description":"Company profile updated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company profile updated successfully."},"data":{"type":"object"}},"type":"object"}}}},"400":{"description":"Company profile not found","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company profile not found."},"error":{"properties":{"key":{"type":"string","example":"company_profile.not_found"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (including duplicate email\/phone)","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/dashboard":{"get":{"tags":["Admin Dashboard"],"summary":"Get admin dashboard summary","operationId":"48eae2542ce5d48288ee45fd07672345","responses":{"200":{"description":"Admin dashboard totals","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"total_payment_amount":{"type":"string","example":"3000.50"},"total_companies":{"type":"integer","example":2},"total_company_branches":{"type":"integer","example":2},"total_registered_users":{"type":"integer","example":2}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/admin\/google-maps\/api-key":{"get":{"tags":["Admin Google Maps"],"summary":"Get Google Maps API key","operationId":"adminGoogleMapsApiKey","responses":{"200":{"description":"Google Maps API key fetched","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Google Maps API key fetched successfully."},"data":{"properties":{"api_key":{"type":"string","example":"AIzaSyD-EXAMPLE"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/masters":{"get":{"tags":["Admin Master"],"summary":"Get admin master data","description":"Get admin master data (medical profile categories).","operationId":"a5a4bde8fea630200c14b51497401e8e","responses":{"200":{"description":"Master data payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Get master data successfully."},"data":{"properties":{"categories":{"description":"Per-category medical profile master payload. Unused sections are empty arrays.","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"},"display_order":{"type":"integer","example":1},"license_required":{"type":"boolean","example":true},"experience_years":{"type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"certificates":{"type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"workplace_types":{"type":"array","items":{"type":"object"}}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/masters\/locations":{"get":{"tags":["Admin Master"],"summary":"Get location master data (prefectures and districts)","description":"Get prefecture and district master data.","operationId":"4a7cf39c426c1fad824a3bef41106c09","responses":{"200":{"description":"Location master data payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Get master data successfully."},"data":{"properties":{"prefectures":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Tokyo"},"short":{"type":"string","example":"TK","nullable":true},"kana":{"type":"string","example":"\u3068\u3046\u304d\u3087\u3046","nullable":true},"en":{"type":"string","example":"Tokyo","nullable":true},"salary":{"description":"Minimum hourly wage (JPY) for this prefecture","type":"number","format":"float","example":1072},"districts":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"prefecture_id":{"type":"integer","example":1},"name":{"type":"string","example":"Chiyoda"}},"type":"object"}}},"type":"object"}},"districts":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"prefecture_id":{"type":"integer","example":1},"name":{"type":"string","example":"Chiyoda"},"prefecture":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Tokyo"},"short":{"type":"string","nullable":true},"kana":{"type":"string","nullable":true},"en":{"type":"string","nullable":true}},"type":"object"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/monthly-payment-stats":{"get":{"tags":["Admin Monthly Payment Stats"],"summary":"Get system-wide monthly payment stats","description":"Aggregates salary-confirmed company wallet totals (`t_company_wallets`) across all companies by calendar month.","operationId":"b345130b5288e3225e77ae53fa236987","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"year_month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","example":"2026-01"}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["year_month","transaction_count","worker_count","total_paid_amount"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"System-wide monthly payment stats list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"year_month":{"type":"string","example":"2026-01"},"transaction_count":{"type":"integer","example":12},"worker_count":{"type":"integer","example":8},"total_paid_amount":{"type":"number","format":"float","example":12000.5}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/monthly-payment-stats\/workers":{"get":{"tags":["Admin Monthly Payment Stats"],"summary":"Get worker breakdown for a monthly payment stats period","description":"Lists workers with salary-confirmed monthly totals from `t_worker_salary` for the given `year_month`. Rows are aggregated from `payment`\/`done` job workings (`income_after_tax` > 0). `base_pay` is the sum of `standard_salary` per shift. `transfer_amount` is the sum of `income_after_tax` per shift.","operationId":"461ed6a5ddcf930a588c5a4edcc46384","parameters":[{"name":"year_month","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","example":"2026-02"}},{"name":"user_name","in":"query","required":false,"schema":{"type":"string","example":"Tanaka"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["user_id","user_name","shift_count","working_minutes","base_pay","transport_expenses","deduction","transfer_amount"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Worker monthly payment breakdown","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"year_month":{"type":"string","example":"2026-02"},"user_id":{"type":"integer","example":1},"user_name":{"type":"string","example":"Tanaka Taro"},"avatar_file_id":{"type":"integer","example":10,"nullable":true},"avatar_file":{"properties":{"id":{"type":"integer","example":10},"url":{"type":"string","example":"https:\/\/cdn.example.com\/uploads\/avatars\/user.png"}},"type":"object","nullable":true},"late_cancel_rate_within_1h":{"description":"Percentage of late cancellations within 1 hour before shift start.","type":"number","format":"float","example":12.34},"shift_count":{"type":"integer","example":3},"working_minutes":{"type":"integer","example":1440},"base_pay":{"type":"number","format":"float","example":9000},"transport_expenses":{"type":"number","format":"float","example":500},"deduction":{"type":"number","format":"float","example":120},"transfer_amount":{"type":"number","format":"float","example":9380}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/monthly-payment-stats\/workers\/{userId}":{"get":{"tags":["Admin Monthly Payment Stats"],"summary":"Get worker shift payment details for a month","description":"Drill-down from worker list. Returns paginated salary-confirmed shifts (`payment`\/`done`, `income_after_tax` > 0) for one worker in `year_month`. `monthly_total_payment` is `transfer_amount` from `t_worker_salary` (sum of `income_after_tax` per shift). `review_summary` is the worker's aggregated company review scores from `t_user_review_summaries` (null when no reviews). `working_minutes` per shift is `actual_total_working_minutes` (same field aggregated into `t_worker_salary`). `payment_amount` per shift is `income_after_tax`.","operationId":"5576aa5984eae44bb89c29ec4e93b52a","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","example":1}},{"name":"year_month","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","example":"2026-02"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["working_date","workplace_name","working_minutes","overtime_minutes","night_working_minutes","hourly_salary","transport_expenses","payment_amount"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Worker shift payment detail","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"properties":{"user_id":{"type":"integer","example":1},"user_name":{"type":"string","example":"Tanaka Taro"},"avatar_file_id":{"type":"integer","nullable":true},"avatar_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"late_cancel_rate_within_1h":{"description":"Percentage of late cancellations within 1 hour before shift start.","type":"number","format":"float","example":12.34},"year_month":{"type":"string","example":"2026-02"},"monthly_total_payment":{"type":"number","format":"float","example":2500},"review_summary":{"properties":{"punctuality_avg":{"type":"number","format":"float","example":4.5},"work_handling_avg":{"type":"number","format":"float","example":4.25},"communication_avg":{"type":"number","format":"float","example":4},"work_attitude_avg":{"type":"number","format":"float","example":4.75},"total_avg":{"type":"number","format":"float","example":4.38},"total_reviews":{"type":"integer","example":12}},"type":"object","nullable":true},"shifts":{"type":"array","items":{"properties":{"job_working_id":{"type":"integer","example":101},"working_date":{"type":"string","format":"date","example":"2026-02-15"},"workplace_name":{"type":"string","example":"Tokyo Branch"},"working_minutes":{"type":"integer","example":480},"overtime_minutes":{"type":"integer","example":0},"night_working_minutes":{"type":"integer","example":0},"hourly_salary":{"type":"number","format":"float","example":1500},"transport_expenses":{"type":"number","format":"float","example":100},"payment_amount":{"type":"number","format":"float","example":2000},"job_apply":{"properties":{"id":{"type":"integer","example":10},"status":{"type":"string","example":"approved"},"start_working_date":{"type":"string","format":"date","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true}},"type":"object","nullable":true},"transaction":{"description":"Latest withdraw transaction log for this shift.","properties":{"id":{"type":"integer","example":1},"type":{"type":"string","example":"withdraw"},"user_status":{"type":"string","nullable":true},"company_status":{"type":"string","nullable":true},"status":{"description":"Legacy alias of company_status","type":"string","nullable":true},"transaction_id":{"type":"string","nullable":true},"amount":{"type":"string","example":"2000.00","nullable":true},"action":{"type":"string","nullable":true}},"type":"object","nullable":true}},"type":"object"}},"total":{"type":"integer","example":2},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"User not found or no salary stats for the given month","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/salary-payments":{"get":{"tags":["Admin Salary Payment"],"summary":"Get salary payment list","description":"List salary payments with filtering and pagination. Response uses the shared\n{@see \\App\\Http\\Controllers\\AppBaseController::pagination()} flat shape\n(NOT the standard success\/message\/data envelope).","operationId":"dd1da3b1c6bdcb22712e6d9f83e6c964","parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","description":"Sort column (single field; use with order_direction). Defaults to id desc.","required":false,"schema":{"type":"string","enum":["id","amount","status","withdraw_at","company_branch_id","job_working_id"]}},{"name":"order_direction","in":"query","description":"asc or desc (required with order_by)","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"user_name","in":"query","description":"Filter by user profile name (LIKE)","required":false,"schema":{"type":"string","example":"Demo User"}},{"name":"user_katakana_name","in":"query","description":"Filter by user profile katakana name (LIKE)","required":false,"schema":{"type":"string","example":"\u30c7\u30e2\u30e6\u30fc\u30b6\u30fc"}},{"name":"user_phone_number","in":"query","description":"Filter by user profile phone number (LIKE)","required":false,"schema":{"type":"string","example":"09012345678"}},{"name":"company_id","in":"query","description":"Company ID (must exist in t_companies)","required":false,"schema":{"type":"integer","example":1}},{"name":"company_name","in":"query","description":"Filter by company name (LIKE)","required":false,"schema":{"type":"string","example":"Demo Company"}},{"name":"job_working_id","in":"query","description":"Job working ID (must exist in t_job_workings)","required":false,"schema":{"type":"integer","example":1}},{"name":"status","in":"query","description":"Transaction log status (t_transaction_logs.status)","required":false,"schema":{"type":"string","enum":["processing","success","failed"],"example":"success"}},{"name":"withdraw_at_from","in":"query","description":"Withdraw date from (YYYY-MM-DD)","required":false,"schema":{"type":"string","format":"date","example":"2025-01-01"}},{"name":"withdraw_at_to","in":"query","description":"Withdraw date to (YYYY-MM-DD, must be >= withdraw_at_from)","required":false,"schema":{"type":"string","format":"date","example":"2025-01-31"}},{"name":"transaction_id","in":"query","description":"Transaction ID","required":false,"schema":{"type":"string","example":"txn_123456"}}],"responses":{"200":{"description":"Salary payment list (pagination flat shape)","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer","example":2},"user_id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":1},"amount":{"type":"string","example":"78667.00"},"status":{"type":"string","example":"in-wallet"},"withdraw_at":{"type":"string","example":null,"nullable":true},"transaction_id":{"type":"string","example":null,"nullable":true}},"type":"object"}},"total":{"type":"integer","example":3},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"The given data was invalid."},"errors":{"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/salary-payments\/{id}":{"get":{"tags":["Admin Salary Payment"],"summary":"Get salary payment detail","description":"Show salary payment detail. Response includes the `user.profile` relation\n(requested via `firstById($id, ['user.profile'])`).","operationId":"9c737ac9611e2a20f45078603146ff2e","parameters":[{"name":"id","in":"path","description":"Salary payment ID","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Salary payment detail","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"id":{"type":"integer","example":1},"user_id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":1},"amount":{"type":"string","example":"99999.00"},"status":{"type":"string","example":"in-wallet"},"withdraw_at":{"type":"string","example":null,"nullable":true},"transaction_id":{"type":"string","example":null,"nullable":true},"user":{"properties":{"id":{"type":"integer","example":1},"profile":{"properties":{"id":{"type":"integer","example":1},"user_id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo User"},"katakana_name":{"type":"string","example":"\u30c7\u30e2\u30e6\u30fc\u30b6\u30fc"},"phone_number":{"type":"string","example":"09012345678"}},"type":"object","nullable":true}},"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"400":{"description":"Salary payment not found","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Salary payment not found."},"error":{"properties":{"key":{"type":"string","example":"company_payment.not_found"},"content":{"type":"string","example":"Salary payment not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/system-fees":{"get":{"tags":["Admin System Fee"],"summary":"Get system fee branch monthly stats","operationId":"adab2af089aa518dd879585d992c82bc","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"branch_ids[]","in":"query","description":"Filter by branch IDs. Example: branch_ids[]=1&branch_ids[]=2","required":false,"style":"form","explode":true,"schema":{"type":"array","items":{"type":"integer"},"example":[1,2]}},{"name":"year_month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","example":"2026-01"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","paid","unbilled"]}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["branch_id"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"System fee branch monthly stats list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"billing_id":{"type":"integer","example":12,"nullable":true},"branch_id":{"type":"integer","example":1},"branch_name":{"type":"string","example":"Tokyo Branch"},"year_month":{"type":"string","example":"2026-01"},"jobs_created_count":{"description":"Snapshot stored on t_system_fee_billings","type":"integer","example":3},"hired_users_count":{"description":"Snapshot stored on t_system_fee_billings","type":"integer","example":2},"total_paid_amount":{"description":"Snapshot stored on t_system_fee_billings","type":"number","format":"float","example":12000.5},"status":{"type":"string","enum":["pending","paid"],"example":"pending","nullable":true},"paid_at":{"type":"string","format":"date-time","nullable":true}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/system-fees\/export-csv":{"post":{"tags":["Admin System Fee"],"summary":"Export system fee branch monthly stats CSV","operationId":"683b75363f780d1430b2458eebc148d8","requestBody":{"required":false,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AdminSystemFeeExportRequest"}}}},"responses":{"200":{"description":"CSV file download"},"400":{"description":"No data","content":{"application\/json":{"schema":[]}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/system-fees\/export-excel":{"post":{"tags":["Admin System Fee"],"summary":"Export system fee branch monthly stats Excel","operationId":"2f1699515848fe82bf5bb77b7922ea36","requestBody":{"required":false,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AdminSystemFeeExportRequest"}}}},"responses":{"200":{"description":"Excel file download"},"400":{"description":"No data","content":{"application\/json":{"schema":[]}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/admin\/companies\/system-fees\/{billingId}\/mark-paid":{"patch":{"tags":["Admin System Fee"],"summary":"Mark system fee billing as paid","operationId":"286a0fb024ba4f28c44c736c96505e13","parameters":[{"name":"billingId","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Billing marked as paid"},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"404":{"description":"Not found","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company-branches\/{id}":{"get":{"tags":["App company branches"],"summary":"Get company branch detail (app)","description":"Branch profile for workers. Response includes `is_favorite` for the authenticated user.","operationId":"62193f0297ca6411fc2fb87421cdff41","parameters":[{"name":"id","in":"path","description":"Company branch id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/app\/auth\/send-code":{"post":{"tags":["App"],"summary":"Send verify code to phone number","description":"Swagger endpoint: `sendVerifyCode` (POST `\/app\/auth\/send-code`).","operationId":"6f8437e44719fc3ed5c010e7af01811f","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["phone_number"],"properties":{"phone_number":{"type":"string","example":"09012345678"}},"type":"object"}}}},"responses":{"200":{"description":"Verify code sent successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Verify code sent successfully."},"data":{"properties":{"otp":{"type":"string","example":"1234"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/app\/auth\/confirm-code":{"post":{"tags":["App"],"summary":"Confirm the verification code sent to the phone number","description":"Swagger endpoint: `confirmVerifyCode` (POST `\/app\/auth\/confirm-code`).","operationId":"2a62c02b3c97aa0216083babf8dd5f0d","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["phone_number","code"],"properties":{"phone_number":{"type":"string","example":"09012345678"},"code":{"type":"string","example":"1234"}},"type":"object"}}}},"responses":{"200":{"description":"Verification successful","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Verification successful."},"data":{"properties":{"access_token":{"type":"string","example":"..."},"refresh_token":{"type":"string","example":"..."},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer","example":3600},"user":{"type":"object"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}},"400":{"description":"Invalid code","content":{"application\/json":{"schema":[]}}}}}},"\/app\/auth\/refresh-token":{"post":{"tags":["App"],"summary":"Refresh the JWT token for the user","description":"Swagger endpoint: `refreshToken` (POST `\/app\/auth\/refresh-token`).","operationId":"53336a66d03fb81abf47a0f680d9835f","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["refresh_token"],"properties":{"refresh_token":{"type":"string","example":"refresh_token"}},"type":"object"}}}},"responses":{"200":{"description":"Token refreshed successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Token refreshed successfully."},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer"},"user":{"$ref":"#\/components\/schemas\/user"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/app\/auth\/logout":{"post":{"tags":["App"],"summary":"Logout","description":"Swagger endpoint: `logout` (POST `\/app\/auth\/logout`).","operationId":"e29416956439a8018af81aefcdefdbb0","responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Logout successfully."},"data":{"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/bank\/account":{"post":{"tags":["App Bank Account"],"summary":"Upsert bank account","description":"Create bank account if missing; otherwise update the existing bank account for the authenticated app user.","operationId":"003383ced616ced43b40a5884ef89c82","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["bank_id","bank_branch_id","bank_account_type","bank_account_name","bank_account_number"],"properties":{"bank_id":{"description":"Bank ID (m_banks.id)","type":"integer","example":1},"bank_branch_id":{"description":"Bank branch ID (m_bank_branches.id)","type":"integer","example":10},"bank_account_type":{"description":"Account type ID (m_bank_account_types.id)","type":"integer","example":1},"bank_account_name":{"description":"Account holder name","type":"string","example":"\u5c71\u7530 \u592a\u90ce"},"bank_account_number":{"description":"Account number","type":"string","example":"1234567"}},"type":"object"}}}},"responses":{"200":{"description":"Bank account saved successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"\u9280\u884c\u53e3\u5ea7\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002"},"data":{"properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"bank_id":{"type":"integer"},"bank_branch_id":{"type":"integer"},"bank_account_type":{"type":"integer"},"bank_account_name":{"type":"string"},"bank_account_number":{"type":"string"},"bank":{"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"},"bank_branch":{"properties":{"id":{"type":"integer"},"bank_id":{"type":"integer"},"name":{"type":"string"}},"type":"object"},"account_type":{"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company-branch-favorites":{"get":{"tags":["App favorites"],"summary":"List company branch favorites (app)","operationId":"bdb334f66641a78368bf4932954c9fc1","parameters":[{"name":"page","in":"query","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"order_by","in":"query","description":"Sort field (optional; requires `order_direction` if provided).","required":false,"schema":{"type":"string","enum":["id"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; requires `order_by` if provided).","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated favorites"},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["App favorites"],"summary":"Add company branch to favorites","operationId":"7d8d114141b100dcb1b4396d45bf27dc","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["company_branch_id"],"properties":{"company_branch_id":{"description":"Company branch id","type":"integer","example":1}},"type":"object"}}}},"responses":{"200":{"description":"Created"},"400":{"description":"Business rule error"},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company-branch-favorites\/{id}":{"delete":{"tags":["App favorites"],"summary":"Remove company branch favorite","operationId":"ebf630033c0a2f333c59c0233aec7912","parameters":[{"name":"id","in":"path","description":"Company branch id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Deleted"},"400":{"description":"Not found"},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/reviews\/company-branches\/{id}\/summary":{"get":{"tags":["App Review company branches"],"summary":"Get company branch review summary","description":"Get aggregated review summary for a specific company branch.","operationId":"1d0b5f77b431a775d73f37ceb0618157","parameters":[{"name":"id","in":"path","description":"Company Branch ID","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Review summary","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company branch review summary fetched successfully."},"data":{"properties":{"company_branch_id":{"type":"integer","example":3},"work_environment_avg":{"type":"string","example":"4.00"},"guidance_avg":{"type":"string","example":"3.75"},"equipment_avg":{"type":"string","example":"4.25"},"total_avg":{"type":"string","example":"4.00"},"total_reviews":{"type":"integer","example":8},"can_review":{"type":"boolean","example":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/reviews\/company-branches\/{id}\/me":{"get":{"tags":["App Review company branches"],"summary":"Get my company branch review","description":"Get the authenticated user's review for the specified company branch.","operationId":"a69fe5c52ecfe9c5f903221c83d47658","parameters":[{"name":"id","in":"path","description":"Company Branch ID","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Review detail","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company branch review fetched successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":3},"user_id":{"type":"integer","example":10},"work_environment":{"type":"integer","example":4},"guidance":{"type":"integer","example":3},"equipment":{"type":"integer","example":5},"average_score":{"type":"string","example":"4.00"},"comment":{"type":"string","example":"Nice place.","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Not found"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/reviews\/company-branches\/{id}":{"get":{"tags":["App Review company branches"],"summary":"List company branch reviews","description":"Get paginated reviews for a specific company branch. Default sort: `order_by=id` and `order_direction=desc` (newest first). Examples: oldest first \u2192 `id` + `asc`; highest rating \u2192 `average_score` + `desc`; lowest rating \u2192 `average_score` + `asc`.","operationId":"aaf72645dad3c4a86eb6bc2b868936ff","parameters":[{"name":"id","in":"path","description":"Company Branch ID","required":true,"schema":{"type":"integer","minimum":1}},{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","description":"Sort field: `id` (time \/ insert order) or `average_score` (rating)","required":false,"schema":{"type":"string","enum":["id","average_score"]}},{"name":"order_direction","in":"query","description":"Sort direction: `desc` or `asc`","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Review list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":3},"user_id":{"type":"integer","example":10},"work_environment":{"type":"integer","example":4},"guidance":{"type":"integer","example":3},"equipment":{"type":"integer","example":5},"average_score":{"type":"string","example":"4.00"},"comment":{"type":"string","example":"\u30b9\u30bf\u30c3\u30d5\u306e\u6848\u5185\u304c\u89aa\u5207\u3067\u3057\u305f\u3002","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}},"type":"object"}},"total":{"type":"integer","example":3},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["App Review company branches"],"summary":"Submit company branch review","description":"Create or update the authenticated user's review for the specified company branch. Each user can submit one review per branch; re-submitting will overwrite the previous review.","operationId":"7b54c36507afa27aea9df158626e7502","parameters":[{"name":"id","in":"path","description":"Company Branch ID","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["work_environment","guidance","equipment"],"properties":{"work_environment":{"description":"Work environment rating (1-5)","type":"integer","maximum":5,"minimum":1,"example":4},"guidance":{"description":"Guidance and instruction rating (1-5)","type":"integer","maximum":5,"minimum":1,"example":3},"equipment":{"description":"Equipment and facilities rating (1-5)","type":"integer","maximum":5,"minimum":1,"example":5},"comment":{"type":"string","maxLength":1000,"example":"The staff guidance was very helpful.","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Review submitted successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"\u4e8b\u696d\u6240\u306e\u30ec\u30d3\u30e5\u30fc\u3092\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002"},"data":{"type":"boolean","example":true}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Company branch not found"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/documents\/privacy-policy":{"get":{"tags":["App\/Documents"],"summary":"Get privacy-policy PDF URL","description":"Get privacy-policy PDF presigned URL.","operationId":"46f1f2c0099932ff2df11224f396ede7","responses":{"200":{"description":"Presigned URL","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"url":{"type":"string","example":"https:\/\/example.com\/presigned-url"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/fcm\/devices":{"post":{"tags":["App - FCM"],"summary":"Register an FCM device token","operationId":"92873512364d106a0785dde0f364b5e3","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["fcm_token"],"properties":{"fcm_token":{"type":"string","example":"abcyxz123456789"},"device_model":{"type":"string","example":"09012345678"},"os":{"type":"string","example":"ios,android,web"},"os_version":{"type":"string","example":"1.1.1"}},"type":"object"}}}},"responses":{"200":{"description":"Token registered"}},"security":[{"bearerAuth":[]}]}},"\/fcm\/devices\/{id}":{"delete":{"tags":["App - FCM"],"summary":"Remove an FCM device token","operationId":"d0e759bffadb7158480505e62c877ba0","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Token removed"}},"security":[{"bearerAuth":[]}]}},"\/job-apply":{"get":{"tags":["App jobs"],"summary":"List applied jobs","description":"Get paginated applied jobs for the authenticated user.","operationId":"32abfdff2b15c36b24a2a4582b56998b","parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"status","in":"query","description":"Filter by list tab: pending, approved, closed (rejected + cancel-related apply statuses), or completed (job working is payment or done \u2014 salary confirmed\/settled). Checkout and request_change stay on approved. Each job appears in at most one tab. Legacy granular apply statuses are normalized to closed.","required":false,"schema":{"type":"string","enum":["pending","approved","closed","completed"]}},{"name":"search_key","in":"query","description":"Search by keyword","required":false,"schema":{"type":"string","maxLength":255}},{"name":"start_working_date","in":"query","description":"Filter from date (Y-m-d)","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Filter to date (Y-m-d)","required":false,"schema":{"type":"string","format":"date"}},{"name":"order_by","in":"query","description":"Sort field (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["id","created_at","status"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated applied jobs","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"job_working_status":{"description":"Latest t_job_workings.status for this user on the latest apply (e.g. approved, checkin, checkout, request_change, payment, done). Tab completed only includes payment and done.","type":"string","nullable":true},"job_working_id":{"description":"Latest t_job_workings.id paired with job_working_status","type":"integer","nullable":true}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/job-apply\/to-do-list":{"get":{"tags":["App jobs"],"summary":"List jobs pending confirmed note","description":"Paginated jobs where the authenticated user's latest apply is approved and confirmed_note is false. Same job shape as GET \/job-apply (includes job_working_status). Excludes applies whose job working is payment or done.","operationId":"e1bece2065feb4bcbd940d473ebac053","parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":20}},{"name":"search_key","in":"query","description":"Search by keyword","required":false,"schema":{"type":"string","maxLength":255}},{"name":"start_working_date","in":"query","description":"Filter from date (Y-m-d)","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Filter to date (Y-m-d)","required":false,"schema":{"type":"string","format":"date"}},{"name":"order_by","in":"query","description":"Sort field (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["id","status"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated jobs pending confirmed note","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"type":"object"}},"total":{"type":"integer","example":1},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/job-apply\/applied-jobs":{"get":{"tags":["App jobs"],"summary":"List applied jobs with latest apply","description":"Returns paginated jobs the authenticated user has applied to. Each job includes `latest_apply` (the most recent t_job_applies row for that job). Optional `company_branch_id` narrows to one branch.","operationId":"1339bd56508d9c4d07793b9cb0ec62be","parameters":[{"name":"company_branch_id","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1}}],"responses":{"200":{"description":"Paginated jobs with latest apply per job","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"jobs":{"type":"array","items":{"properties":{"latest_apply":{"description":"Latest apply row for this job","type":"object","nullable":true}},"type":"object"}},"total":{"type":"integer"},"last_page":{"type":"integer"},"current_page":{"type":"integer"},"company_branch_id":{"type":"integer","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/job-apply\/history":{"get":{"tags":["App jobs"],"summary":"List all applied job history","description":"Returns apply timeline for the authenticated user, grouped by date (newest first). Omit both `page` and `limit` to return the full timeline (`success`, `message`, `data`). Pass either query param to paginate date groups (`data`, `total`, `last_page`, `current_page`; default page=1, limit=15). Each row in `t_job_apply_status_histories` becomes one item in `jobs` (grouped by that row's `created_at` date). When an apply has no status history yet, a single snapshot from `t_job_applies` is returned. Pending or approved applies also include a scheduled snapshot on `t_jobs.start_working_date` when it differs from other events on that date. When a linked `t_job_workings` row exists, an additional snapshot is included on `working_date` with `job_working_status` and `job_working_id` set.","operationId":"a56ed05098eb86a4076d54be39616a34","parameters":[{"name":"page","in":"query","description":"Page number (1-based). Omit with `limit` to return all rows.","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Date groups per page (max 100). Omit with `page` to return all rows.","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}}],"responses":{"200":{"description":"Apply history date groups. Without `page`\/`limit`: `success`, `message`, and `data`. With either param: `data`, `total`, `last_page`, `current_page` only.","content":{"application\/json":{"schema":{"properties":{"success":{"description":"Present only when pagination params are omitted.","type":"boolean","example":true,"nullable":true},"message":{"description":"Present only when pagination params are omitted.","type":"string","example":"","nullable":true},"data":{"type":"array","items":{"properties":{"date":{"type":"string","format":"date","example":"2026-05-15","nullable":true},"jobs":{"type":"array","items":{"properties":{"id":{"type":"integer","example":123},"name":{"type":"string","example":"Seeded Job #01"},"job_apply_id":{"type":"integer","example":456},"job_apply_status":{"type":"string","example":"user_cancelled"},"event_type":{"type":"string","enum":["apply","status_change","scheduled","working"],"example":"scheduled"},"job_apply_confirmed_note":{"type":"boolean","example":false},"job_apply_status_history_id":{"type":"integer","example":99,"nullable":true},"job_apply_status_note":{"type":"string","example":"Company note","nullable":true},"status_changed_at":{"type":"string","format":"date-time","example":"2026-05-20 14:30:00"},"job_working_status":{"type":"string","example":"payment","nullable":true},"job_working_id":{"type":"integer","example":42,"nullable":true}},"type":"object"}}},"type":"object"}},"total":{"description":"Present only when `page` or `limit` is sent.","type":"integer","example":42,"nullable":true},"last_page":{"description":"Present only when `page` or `limit` is sent.","type":"integer","example":3,"nullable":true},"current_page":{"description":"Present only when `page` or `limit` is sent.","type":"integer","example":1,"nullable":true}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/jobs\/{id}\/apply":{"post":{"tags":["App jobs"],"summary":"Apply to a job (app)","description":"Submit an application for a job.","operationId":"db83de3594510357864421136f737a99","parameters":[{"name":"id","in":"path","description":"Job ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Application submitted","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Application submitted successfully."},"data":{"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Job not found"},"400":{"description":"Business rule error. Notable `error.key` values include `job_apply.time_overlap` (another pending\/approved shift overlaps this time range), `job_apply.shift_insufficient_gap` (same day, non-overlapping but less than 60 minutes apart), `job_apply.cancelled_slot_blocked` (user cancelled this job or an overlapping shift window and cannot re-apply), `job_apply.already_applied`, `job_apply.job_full` (approved count reached recruitment limit), `job_apply.monthly_working_hours_exceeded`.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string"},"error":{"properties":{"key":{"type":"string","example":"job_apply.shift_insufficient_gap"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/jobs\/{id}\/cancel":{"post":{"tags":["App jobs"],"summary":"Cancel job application (app)","description":"Cancel or request cancellation of a job application.\n\nBehaviour depends on the current application status:\n- `pending`  \u2192 user_cancelled immediately.\n- `approved` \u2192 transitions to `cancel_requested`; company must approve\/reject.\nAllowed only before shift start; blocked after start or once check-in\/out exists.\n- `checkin` \/ `checkout` \/ `request_change` \u2192 400 error (cannot cancel while shift is in progress).\n- Any other status \u2192 400 error (cannot cancel).","operationId":"e51f62731b5d740a38842d091cf48c99","parameters":[{"name":"id","in":"path","description":"t_jobs.id of the job to cancel the application for","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["cancel_note"],"properties":{"cancel_note":{"description":"Mandatory note recorded in status history.","type":"string","maxLength":2000}},"type":"object"}}}},"responses":{"200":{"description":"Cancelled (pending\u2192user_cancelled) or cancel request submitted (approved\u2192cancel_requested).","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"description":"'Application cancelled successfully.' when pending was user_cancelled; 'Cancellation request submitted successfully.' when an approved application moves to cancel_requested.","type":"string","example":"Application cancelled successfully."},"data":{"properties":{"id":{"type":"integer"},"job_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"description":"'user_cancelled' when the pending apply was cancelled directly; 'cancel_requested' when the approved apply is awaiting company decision.","type":"string","enum":["user_cancelled","cancel_requested"]}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"Business rule error. Possible `error.key` values:\n     *       - `job_apply.not_found` \u2014 no active application found for this job\n     *       - `job_apply.cannot_cancel` \u2014 application is in a non-cancellable status (rejected, cancelled, cancel_requested)\n     *       - `job_apply.currently_working` \u2014 shift is currently in progress (checkin \/ checkout \/ request_change)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"This application cannot be cancelled."},"error":{"properties":{"key":{"type":"string","example":"job_apply.cannot_cancel"},"content":{"type":"string","example":"This application cannot be cancelled."}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/jobs\/{id}\/confirmed-note":{"post":{"tags":["App jobs"],"summary":"confirmed-note to an approved job (app)","description":"User agrees to an approved job application.","operationId":"aa2b4bc4bfee80bd19aad19b87289e7b","parameters":[{"name":"id","in":"path","description":"Job ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Agreement confirmed","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Application note updated successfully."},"data":{"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Application not found"},"400":{"description":"Status not APPROVED"}},"security":[{"bearerAuth":[]}]}},"\/jobs\/{id}\/verify-certificates":{"get":{"tags":["App jobs"],"summary":"Get license verification context (app)","description":"Returns user licenses matching the job category and certificate, plus acknowledgment state and whether confirmation is allowed at the current time.","operationId":"48fb19f519d21da286a63956b73299db","parameters":[{"name":"id","in":"path","description":"Job ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"License verification context","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"License verification context fetched successfully."},"data":{"properties":{"matching_licenses":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"type":{"type":"string","example":"nurse"},"category_id":{"type":"integer","example":5},"license_number":{"type":"string","example":"123456","nullable":true},"registration_subtype_id":{"description":"Master id (m_registration_subtypes.id).","type":"integer","nullable":true},"registration_subtype":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"medical"},"name":{"type":"string","example":"\u533b\u79d1"}},"type":"object","nullable":true},"acquired_at":{"type":"string","format":"date","example":"2020-01-01","nullable":true},"clinical_training_end_at":{"type":"string","format":"date","nullable":true}},"type":"object"}},"confirmed_license":{"type":"boolean","example":false},"can_confirm_now":{"description":"True when current time is within [T-1h, end_working_date_time).","type":"boolean","example":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"Not approved, no matching license, or certificate not required"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["App jobs"],"summary":"Acknowledge license before shift (app)","description":"Records `confirmed_license` on the approved apply. Available from one hour before shift start until shift end. Idempotent when already acknowledged.","operationId":"48b7b9535aca881f422dbb02e7c3e5b4","parameters":[{"name":"id","in":"path","description":"Job ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"License acknowledgment recorded","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"License acknowledgment recorded."},"data":{"type":"boolean","example":true}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"Not approved, outside time window, or certificate not required"}},"security":[{"bearerAuth":[]}]}},"\/jobs":{"get":{"tags":["App jobs"],"summary":"List jobs (app)","description":"List open job postings.","operationId":"57a9be4c4972adfa99693561b4f9384d","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"order_by","in":"query","description":"Sort field (optional; omit to use default ordering). Use distance only with lat\/lon.","required":false,"schema":{"type":"string","enum":["id","start_working_date","end_apply_date_time","hourly_salary","distance"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"search_key","in":"query","required":false,"schema":{"type":"string"}},{"name":"company_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"prefecture_ids","in":"query","description":"Comma-separated prefecture ids","required":false,"schema":{"type":"string"}},{"name":"district_ids","in":"query","description":"Comma-separated district ids","required":false,"schema":{"type":"string"}},{"name":"start_working_date","in":"query","description":"Working date filter. With end_working_date: range start. Without end_working_date: exact day.","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Working date filter. With start_working_date: range end. Without start_working_date: exact day.","required":false,"schema":{"type":"string","format":"date"}},{"name":"start_working_time","in":"query","required":false,"schema":{"type":"string"}},{"name":"end_working_time","in":"query","required":false,"schema":{"type":"string"}},{"name":"hourly_salary","in":"query","description":"Minimum hourly salary","required":false,"schema":{"type":"number"}},{"name":"category_ids","in":"query","description":"Comma-separated m_category ids","required":false,"schema":{"type":"string"}},{"name":"skill_ids","in":"query","description":"Comma-separated m_skills ids","required":false,"schema":{"type":"string"}},{"name":"workplace_ids","in":"query","description":"Comma-separated m_workplaces ids","required":false,"schema":{"type":"string"}},{"name":"condition_ids","in":"query","description":"Comma-separated m_job_conditions ids (\u3053\u3060\u308f\u308a\u6761\u4ef6 checkbox filter)","required":false,"schema":{"type":"string"}},{"name":"appearance_option_ids","in":"query","description":"Comma-separated m_appearance_items leaf ids (\u670d\u88c5\/\u9aea\u578b\/\u30cd\u30a4\u30eb options from t_job_appearance_selections)","required":false,"schema":{"type":"string"}},{"name":"travel_method_ids","in":"query","description":"Comma-separated m_travel_methods ids (commute \/ transport options from t_job_travels)","required":false,"schema":{"type":"string"}},{"name":"transport_expenses","in":"query","description":"Minimum transport expense filter (yen). Returns jobs with transport_expenses >= value. Range 0\u20133000.","required":false,"schema":{"type":"number"}},{"name":"favorites","in":"query","description":"When true, return only jobs favorited by the authenticated app user (includes closed\/expired favorites; requires Bearer token).","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Paginated job rows: data, total, last_page, current_page. Each row always includes distance (kilometers, null when unavailable). Distance is computed from the authenticated user's saved coordinates when available."},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}}}},"\/jobs\/repeats":{"get":{"tags":["App jobs"],"summary":"List repeat jobs by repeat_id (app)","description":"List open job postings by repeat group.","operationId":"95c4ba682e92b5c5c1e3a458514eb13b","parameters":[{"name":"repeat_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"order_by","in":"query","description":"Sort field (optional; omit to use default ordering). Use distance only with lat\/lon.","required":false,"schema":{"type":"string","enum":["id","start_working_date","end_apply_date_time","hourly_salary","distance"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; omit to use default ordering)","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"search_key","in":"query","required":false,"schema":{"type":"string"}},{"name":"company_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"prefecture_ids","in":"query","description":"Comma-separated prefecture ids","required":false,"schema":{"type":"string"}},{"name":"district_ids","in":"query","description":"Comma-separated district ids","required":false,"schema":{"type":"string"}},{"name":"start_working_date","in":"query","description":"Working date filter. With end_working_date: range start. Without end_working_date: exact day.","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Working date filter. With start_working_date: range end. Without start_working_date: exact day.","required":false,"schema":{"type":"string","format":"date"}},{"name":"start_working_time","in":"query","required":false,"schema":{"type":"string"}},{"name":"end_working_time","in":"query","required":false,"schema":{"type":"string"}},{"name":"hourly_salary","in":"query","description":"Minimum hourly salary","required":false,"schema":{"type":"number"}},{"name":"category_ids","in":"query","description":"Comma-separated m_category ids","required":false,"schema":{"type":"string"}},{"name":"skill_ids","in":"query","description":"Comma-separated m_skills ids","required":false,"schema":{"type":"string"}},{"name":"workplace_ids","in":"query","description":"Comma-separated m_workplaces ids","required":false,"schema":{"type":"string"}},{"name":"condition_ids","in":"query","description":"Comma-separated m_job_conditions ids (\u3053\u3060\u308f\u308a\u6761\u4ef6 checkbox filter)","required":false,"schema":{"type":"string"}},{"name":"appearance_option_ids","in":"query","description":"Comma-separated m_appearance_items leaf ids (\u670d\u88c5\/\u9aea\u578b\/\u30cd\u30a4\u30eb options from t_job_appearance_selections)","required":false,"schema":{"type":"string"}},{"name":"travel_method_ids","in":"query","description":"Comma-separated m_travel_methods ids (commute \/ transport options from t_job_travels)","required":false,"schema":{"type":"string"}},{"name":"transport_expenses","in":"query","description":"Minimum transport expense filter (yen). Returns jobs with transport_expenses >= value. Range 0\u20133000.","required":false,"schema":{"type":"number"}},{"name":"favorites","in":"query","description":"When true, return only jobs favorited by the authenticated app user (includes closed\/expired favorites; requires Bearer token).","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Paginated job rows filtered by repeat_id. Same distance behavior as GET \/jobs."},"422":{"description":"Validation error"}}}},"\/jobs\/{id}":{"get":{"tags":["App jobs"],"summary":"Get job detail (app)","description":"Job detail for the app (open job only: published + deadline not passed).","operationId":"6a0571f1d8e8ad496d2ecaf70fd03d77","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job detail fetched successfully."},"data":{"properties":{"job":{"description":"Job detail object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"thumbnail":{"description":"FK to t_file_uploads.id","type":"integer","nullable":true},"thumbnail_file":{"properties":{"id":{"type":"integer"},"url":{"description":"Presigned S3 URL (expires ~1h)","type":"string","nullable":true}},"type":"object","nullable":true},"total_user":{"type":"integer"},"approved_count":{"description":"Number of approved applications for this job.","type":"integer","example":2},"distance":{"description":"Distance in kilometers from the authenticated user's saved coordinates to the job. Always present; null when guest, user has no saved coordinates, or job has no coordinates.","type":"number","format":"float","example":2.5,"nullable":true},"conditions":{"description":"\u3053\u3060\u308f\u308a\u6761\u4ef6 attached to this job","type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"key":{"type":"string"},"display_order":{"type":"integer"}},"type":"object"}},"company":{"type":"object"},"category":{"type":"object"},"prefecture":{"type":"object","nullable":true},"district":{"type":"object","nullable":true},"company_branch":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"review_summary":{"description":"Review summary for the job's branch","properties":{"total_avg":{"type":"number","format":"float","example":4.12},"total_reviews":{"type":"integer","example":18}},"type":"object","nullable":true}},"type":"object"},"categories":{"type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"job_certificates":{"type":"array","items":{"type":"object"}},"job_travels":{"type":"array","items":{"type":"object"}},"job_shifts":{"type":"array","items":{"type":"object"}},"job_workings":{"description":"Job working row for this job, including check-in time.","type":"array","items":{"properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"job_id":{"type":"integer"},"status":{"type":"string","example":"user_checkin"},"working_date":{"type":"string","format":"date","nullable":true},"start_working_time":{"type":"string","format":"date-time","example":"2026-05-12 09:05:00","nullable":true},"end_working_time":{"type":"string","format":"date-time","nullable":true}},"type":"object"}}},"type":"object"},"is_applied":{"description":"Whether the authenticated user has already applied to this job.","type":"boolean","example":false},"job_apply_status":{"description":"Latest apply status for the authenticated user (pending\/approved\/rejected\/cancelled\/cancel_requested\/approve_cancelled\/user_cancelled).","type":"string","example":"approved","nullable":true},"job_apply_confirmed_note":{"description":"Whether the authenticated user confirmed the pre-work note on their latest apply. Null when not logged in or not applied.","type":"boolean","example":true,"nullable":true},"job_apply_confirmed_license":{"description":"Whether the authenticated user acknowledged their license on their latest apply. Null when not logged in or not applied.","type":"boolean","example":false,"nullable":true},"job_apply_qr":{"description":"QR code URL returned only when the latest apply status is approved.","type":"string","example":"https:\/\/example.com\/qrcode.svg","nullable":true},"user_review":{"description":"Company review of the authenticated worker for this job (`t_user_reviews`). Null when not logged in or no review row exists yet.","properties":{"id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":10},"job_id":{"type":"integer","example":3},"user_id":{"type":"integer","example":10},"status":{"type":"string","enum":["not_reviewed","reviewed"],"example":"reviewed"},"punctuality":{"type":"integer","example":5,"nullable":true},"appearance":{"type":"integer","example":4,"nullable":true},"communication":{"type":"integer","example":5,"nullable":true},"work_attitude":{"type":"integer","example":4,"nullable":true},"skill":{"type":"integer","example":5,"nullable":true},"average_score":{"type":"string","example":"4.60","nullable":true},"comment":{"type":"string","example":"Great worker.","nullable":true}},"type":"object","nullable":true},"job_repeats":{"description":"Other open jobs in the same repeat group (published, apply deadline not passed), excluding the current job.","type":"array","items":{"properties":{"id":{"type":"integer"},"repeat_id":{"type":"string"},"start_working_date":{"type":"string","format":"date"},"start_working_time":{"type":"string"},"end_working_time":{"type":"string"},"income_after_tax":{"type":"number"},"total_user":{"type":"integer"},"applier_count":{"type":"integer"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Not found or not open for application"}}}},"\/job-favorites":{"get":{"tags":["App favorites"],"summary":"List job favorites (app)","operationId":"13dc646c51317ea022293caded196372","parameters":[{"name":"type","in":"query","description":"Filter type. Use `published` to return only favorites whose job is still open for application.","required":false,"schema":{"type":"string","enum":["published"]}},{"name":"page","in":"query","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"order_by","in":"query","description":"Sort field (optional; requires `order_direction` if provided).","required":false,"schema":{"type":"string","enum":["start_working_date","end_apply_date_time","hourly_salary"]}},{"name":"order_direction","in":"query","description":"Sort direction (optional; requires `order_by` if provided).","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated favorites"},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["App favorites"],"summary":"Add job to favorites","operationId":"eb84438118e7462a1bf730a3d2199d0e","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["job_id"],"properties":{"job_id":{"description":"Job id","type":"integer","example":1}},"type":"object"}}}},"responses":{"200":{"description":"Created"},"400":{"description":"Business rule error"},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/job-favorites\/{id}":{"delete":{"tags":["App favorites"],"summary":"Remove job favorite","operationId":"50ba8908deb068e7a32a2c252f0240a6","parameters":[{"name":"id","in":"path","description":"Job id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Deleted"},"400":{"description":"Not found"},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/kyc\/applicant":{"get":{"tags":["KYC"],"summary":"Get Sumsub applicant ID","description":"Returns the authenticated user's Sumsub applicant ID (t_users.kyc_applicant_id). Creates a Sumsub applicant from the user profile when missing.","operationId":"getKycApplicantId","responses":{"200":{"description":"Applicant ID returned successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Get applicant successfully."},"data":{"properties":{"applicant_id":{"description":"Sumsub applicant ID (t_users.kyc_applicant_id)","type":"string","example":"6a14063d8f5f99497c6ae143"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"User not found or Sumsub error"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["KYC"],"summary":"Create KYC applicant (Sumsub)","description":"Creates a Sumsub applicant from request body. Bearer token required. Optional user_id loads phone from t_users; otherwise phone_number and phone_number_with_country_code are required. Sumsub: externalUserId=phone_number (domestic), info.phone=phone_number_with_country_code. Email is not sent.","operationId":"createKycApplicant","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["first_name","last_name","dob","nationality","country","id_number"],"properties":{"user_id":{"description":"Optional. When set, phones may be omitted (loaded from t_users).","type":"integer","example":1,"nullable":true},"first_name":{"type":"string","maxLength":100,"example":"John"},"last_name":{"type":"string","maxLength":100,"example":"Doe"},"dob":{"type":"string","format":"date","example":"1990-01-01"},"nationality":{"description":"ISO 3166-1 alpha-3","type":"string","maxLength":3,"minLength":3,"example":"JPN"},"country":{"description":"ISO 3166-1 alpha-3 (alpha-2 converted server-side)","type":"string","maxLength":3,"minLength":3,"example":"JPN"},"id_number":{"description":"Required. Sent to Sumsub as idNumber (not stored on t_users).","type":"string","maxLength":50,"example":"A1234567"},"phone_number":{"description":"Domestic JP phone. Required when user_id omitted. Sumsub externalUserId.","type":"string","maxLength":20,"example":"09012345002","nullable":true},"phone_number_with_country_code":{"description":"E.164 phone. Required when user_id omitted. Sumsub info.phone.","type":"string","maxLength":32,"example":"+819012345002","nullable":true},"gender":{"type":"string","example":"male","nullable":true},"address":{"properties":{"street":{"type":"string","maxLength":255,"example":"123 Main St"},"city":{"type":"string","maxLength":100,"example":"New York"},"state":{"type":"string","maxLength":100,"example":"NY"},"postal_code":{"type":"string","maxLength":20,"example":"10001"},"country":{"description":"ISO alpha-2 or alpha-3 (converted to alpha-3 for Sumsub, e.g. US \u2192 USA)","type":"string","maxLength":3,"minLength":2,"example":"US"}},"type":"object","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Applicant created successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Create applicant successfully."},"data":{"properties":{"id":{"description":"Sumsub applicant id","type":"string","example":"6a14063d8f5f99497c6ae143"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"},"400":{"description":"Sumsub or business error (error.key e.g. sumsub.create_applicant_failed)"}},"security":[{"bearerAuth":[]}]}},"\/kyc\/generate-sdk-token":{"post":{"tags":["KYC"],"summary":"Generate Sumsub SDK token","description":"Returns SDK access token for the authenticated user's phone number (Sumsub externalUserId).","operationId":"generateKycSdkToken","responses":{"200":{"description":"SDK token generated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Generate sdk access token successfully."},"data":{"properties":{"token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"userId":{"type":"string","example":"09012345678","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/kyc\/init":{"post":{"tags":["KYC"],"summary":"Init KYC (create applicant if needed + SDK token)","description":"Uses authenticated user profile from t_users (no request body). Creates Sumsub applicant when kyc_applicant_id is empty, then returns SDK token.","operationId":"initKycApplicant","responses":{"200":{"description":"SDK token returned (applicant created when missing)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Init applicant successfully."},"data":{"properties":{"token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"userId":{"type":"string","example":"09012345678","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"User not found or Sumsub error"}},"security":[{"bearerAuth":[]}]}},"\/locations\/reverse-geocode":{"get":{"tags":["App locations"],"summary":"Reverse geocode coordinates","description":"Reverse geocode latitude\/longitude to an address.","operationId":"df70ca375c10a58b96e8199834ce34af","parameters":[{"name":"lat","in":"query","description":"Latitude","required":true,"schema":{"type":"number","format":"float","maximum":90,"minimum":-90,"example":35.65858}},{"name":"lon","in":"query","description":"Longitude","required":true,"schema":{"type":"number","format":"float","maximum":180,"minimum":-180,"example":139.745433}}],"responses":{"200":{"description":"Normalized address data","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"formatted_address":{"type":"string","example":"Tokyo Tower, 4-2-8, Shibakoen, Shibakoen, Minato","nullable":true},"prefecture":{"type":"string","example":"Tokyo","nullable":true},"city":{"type":"string","example":"Minato","nullable":true},"ward":{"type":"string","example":"Shibakoen","nullable":true},"postal_code":{"type":"string","example":"105-0011","nullable":true},"country":{"type":"string","example":"jp","nullable":true},"raw":{"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/locations\/geocode":{"get":{"tags":["App locations"],"summary":"Geocode address to coordinates","description":"Geocode a free-text address to latitude\/longitude.","operationId":"1c22bd4d10e031d4ee534bf740796442","parameters":[{"name":"address","in":"query","description":"Free-text address (Japanese recommended)","required":true,"schema":{"type":"string","maxLength":500,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a\u4e38\u306e\u51851-1-1"}}],"responses":{"200":{"description":"Resolved coordinates","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"latitude":{"type":"number","format":"float","example":35.681236},"longitude":{"type":"number","format":"float","example":139.767125},"formatted_address":{"type":"string","example":"1-1 Marunouchi, Chiyoda City, Tokyo 100-0005, Japan","nullable":true},"raw":{"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/masters\/categories":{"get":{"tags":["App"],"summary":"Get medical profile category master data","operationId":"38da5ba0333ec41097f3538d3de365dc","responses":{"200":{"description":"Per-category medical profile master payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"properties":{"categories":{"description":"Per-category medical profile master payload. Unused sections are empty arrays.","type":"array","items":{"properties":{"id":{"type":"integer","example":3},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"},"display_order":{"type":"integer","example":3},"license_required":{"description":"When true, job apply requires at least one t_user_licenses row for jobs in this category.","type":"boolean","example":true},"experience_years":{"type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"workplace_types":{"type":"array","items":{"type":"object"}},"certificates":{"description":"Category certificates including board specialists (scope=board_specialist) with nested children","type":"array","items":{"properties":{"id":{"type":"integer"},"key":{"type":"string"},"name":{"type":"string"},"display_order":{"type":"integer"},"scope":{"type":"string","example":"board_specialist"},"children":{"type":"array","items":{"type":"object"}}},"type":"object"}},"registration_subtypes":{"description":"Insurance physician registration subtype options (doctor category only; empty for other categories)","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"medical"},"name":{"type":"string","example":"\u533b\u79d1"}},"type":"object"}}},"type":"object"}},"current_work_types":{"type":"array","items":{"type":"object"}},"work_preferences":{"type":"array","items":{"type":"object"}},"job_change_interests":{"type":"array","items":{"type":"object"}}},"type":"object"}},"type":"object"}}}},"500":{"description":"Internal Server Error"}}}},"\/masters":{"get":{"tags":["App"],"summary":"Get master data","description":"Get master data for registration and job filters.","operationId":"143715bd61650f0d0a686c697702cc8d","responses":{"200":{"description":"Master data payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"properties":{"countries":{"type":"array","items":{"type":"object"}},"prefectures":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Tokyo"},"short":{"type":"string","example":"TK","nullable":true},"kana":{"type":"string","example":"\u3068\u3046\u304d\u3087\u3046","nullable":true},"en":{"type":"string","example":"Tokyo","nullable":true},"salary":{"description":"Minimum hourly wage (JPY) for this prefecture","type":"number","format":"float","example":1072},"districts":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"prefecture_id":{"type":"integer","example":1},"name":{"type":"string","example":"Chiyoda"}},"type":"object"}}},"type":"object"}},"districts":{"type":"array","items":{"type":"object"}},"job_categories":{"type":"array","items":{"type":"object"}},"job_sub_categories":{"type":"array","items":{"type":"object"}},"experience_years":{"type":"array","items":{"type":"object"}},"registration_subtypes":{"type":"array","items":{"type":"object"}},"current_work_types":{"type":"array","items":{"type":"object"}},"work_preferences":{"type":"array","items":{"type":"object"}},"job_change_interests":{"type":"array","items":{"type":"object"}},"certificates":{"type":"array","items":{"type":"object"}},"travel_methods":{"type":"array","items":{"type":"object"}},"job_conditions":{"type":"array","items":{"type":"object"}},"banks":{"description":"List of banks (m_banks) with their branches","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"\u4e09\u83f1UFJ\u9280\u884c"},"name_half_size":{"type":"string","example":"\uff90\uff82\uff8b\uff9e\uff7cUFJ\uff77\uff9e\uff9d\uff7a\uff73"},"branches":{"description":"Bank branches (m_bank_branches)","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"bank_id":{"type":"integer","example":1},"code":{"type":"string","example":"001"},"name":{"type":"string","example":"\u6771\u4eac\u55b6\u696d\u90e8"},"kana":{"type":"string","example":"\u30c8\u30a6\u30ad\u30e7\u30a6\u30a8\u30a4\u30ae\u30e7\u30a6\u30d6"},"hira":{"type":"string","example":"\u3068\u3046\u304d\u3087\u3046\u3048\u3044\u304e\u3087\u3046\u3076"},"roma":{"type":"string","example":"tokyoeigyobu"}},"type":"object"}}},"type":"object"}},"bank_account_types":{"description":"Bank account types (m_bank_account_types)","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"code":{"type":"string","example":"01"},"name":{"type":"string","example":"\u666e\u901a"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"500":{"description":"Internal Server Error"}}}},"\/notifications":{"get":{"tags":["App - Notifications"],"summary":"List push notifications for the authenticated user","operationId":"1747035a2ef2e3707698574f55215b2e","parameters":[{"name":"page","in":"query","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"type","in":"query","description":"Filter by notification type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated notifications"},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/notifications\/{id}\/read":{"put":{"tags":["App - Notifications"],"summary":"Mark a notification as read","operationId":"9c0da90a875858aea03a9f239fbfdc9c","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Notification marked as read"},"404":{"description":"Notification not found"}},"security":[{"bearerAuth":[]}]}},"\/notifications\/read-all":{"put":{"tags":["App - Notifications"],"summary":"Mark notifications as read (all for user when ids omitted, or specific ids)","operationId":"a160e03d170155a48ecd5c7911c576f9","requestBody":{"required":false,"content":{"application\/json":{"schema":{"properties":{"ids":{"description":"Optional. When omitted or empty, marks all notifications for the authenticated user.","type":"array","items":{"type":"integer","example":1}}},"type":"object"}}}},"responses":{"200":{"description":"Notifications marked as read"}},"security":[{"bearerAuth":[]}]}},"\/salary\/list-year-working":{"get":{"tags":["App\/SalaryExport"],"summary":"List working years and companies for withholding tax certificate","description":"List calendar years and companies where the authenticated user has completed job work.","operationId":"8558bf3026896fa043cfc1fe000f563f","responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"type":"array","items":{"properties":{"year":{"type":"string","example":"2026"},"companies":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Sample Corp KK"}},"type":"object"}}},"type":"object"}}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/salary\/withholding-tax-certificate":{"get":{"tags":["App\/SalaryExport"],"summary":"Get withholding tax certificate preview","description":"SCR-001 detail: payment amount, withholding tax, social insurance (0 when not tracked), payer name and address.","operationId":"83611227edc1e038a631424961d5e1f5","parameters":[{"name":"year","in":"query","description":"Target year (YYYY)","required":true,"schema":{"type":"integer","example":2026}},{"name":"company_id","in":"query","description":"Company ID. Defaults to 1 if omitted. Use 0 for all companies (aggregated totals, payer name All).","required":false,"schema":{"type":"integer","default":1,"minimum":0,"example":1}}],"responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"properties":{"year":{"type":"integer","example":2026},"company_id":{"type":"integer","example":1},"payment_amount":{"description":"\u652f\u6255\u91d1\u984d","type":"number","format":"float","example":1080000},"withholding_tax_amount":{"description":"\u6e90\u6cc9\u5fb4\u53ce\u7a0e\u984d","type":"number","format":"float","example":108000},"social_insurance_amount":{"description":"\u793e\u4f1a\u4fdd\u967a\u6599\u7b49\u306e\u91d1\u984d","type":"number","format":"float","example":0},"payer_name":{"description":"\u652f\u6255\u8005\u306e\u540d\u79f0","type":"string","example":"\u682a\u5f0f\u4f1a\u793e\u30b5\u30f3\u30d7\u30eb"},"payer_address":{"description":"\u652f\u6255\u8005\u306e\u6240\u5728\u5730","type":"string","example":"\u6771\u4eac\u90fd\u65b0\u5bbf\u533a\u3007\u3007"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/salary\/withholding-tax-certificate\/download":{"get":{"tags":["App\/SalaryExport"],"summary":"Download withholding tax certificate file","description":"SCR-001: file download \u6e90\u6cc9\u5fb4\u53ce\u7968. Name: \u6e90\u6cc9\u5fb4\u53ce\u7968_{staff}_{company}_{year}\u5e74.pdf when LibreOffice conversion succeeds; otherwise filled XLSX with the same stem and .xlsx.","operationId":"257a6387f199005fe1845acfe2a3c522","parameters":[{"name":"year","in":"query","description":"Target year (YYYY)","required":true,"schema":{"type":"integer","example":2026}},{"name":"company_id","in":"query","description":"Company ID. Defaults to 1 if omitted. Use 0 for all companies.","required":false,"schema":{"type":"integer","default":1,"minimum":0,"example":1}}],"responses":{"200":{"description":"File download","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}},"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/timekeeping\/{id}":{"get":{"tags":["App\/Timekeeping"],"summary":"Get job working detail","description":"Returns one `t_job_workings` row owned by the authenticated user, including nested `job`, `company`, `company_branch`, `job_apply`, withdraw `transaction_logs`, and the latest `job_working_request` for that shift.","operationId":"e4fa6b76cc3ca9e479d35eea6db92e3a","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Shift detail","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Timekeeping record fetched successfully."},"data":{"description":"`JobWorking` with nested relations","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"Record not found or not owned by the user"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/timekeeping":{"post":{"tags":["App\/Timekeeping"],"summary":"Timekeeping: check-in \/ check-out","description":"Check-in or check-out (same endpoint, server branches by state).","operationId":"1b97488b02c2c429146913b82c730c03","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["job_id","branch_id"],"properties":{"job_id":{"description":"Job ID (`t_jobs.id`)","type":"integer","example":1},"branch_id":{"description":"Branch ID decoded from the branch QR. Must match `t_jobs.company_branch_id`.","type":"integer","example":10}},"type":"object"}}}},"responses":{"200":{"description":"Check-in or check-out success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Check-in \/ Check-out successful."},"data":{"description":"Updated `JobWorking`. After check-out, credits user\/company wallets and creates deposit + pending withdraw transaction logs (status stays `checkout`). Includes nested `job` with `name`, `service_type` (`id`, `name`), and `thumbnail_file` (`id`, `path`, `name`, `extension`) for the same `t_jobs` row.","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation or business rule error"}},"security":[{"bearerAuth":[]}]}},"\/timekeeping\/calculate":{"post":{"tags":["App\/Timekeeping"],"summary":"Preview timekeeping salary","description":"Dry-run calculation for the authenticated user's shift. Uses hourly rates from `t_job_workings`. Optional `start_break_time` \/ `end_break_time` apply a single break window; when omitted, the existing break on `t_job_workings` is used. Does not update `t_job_workings` or create requests.","operationId":"c29c677788fc4f287f61e4e13390ff14","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["job_working_id","start_working_time","end_working_time"],"properties":{"job_working_id":{"type":"integer","example":10},"start_working_time":{"type":"string","format":"date-time","example":"2026-06-08 09:00:00"},"end_working_time":{"type":"string","format":"date-time","example":"2026-06-08 18:00:00"},"start_break_time":{"description":"Break start (H:i), same as company job create","type":"string","example":"12:00","nullable":true},"end_break_time":{"description":"Break end (H:i); required when start_break_time is set","type":"string","example":"13:00","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Preview calculated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Salary preview calculated successfully."},"data":{"description":"Working minutes and salary buckets (same shape as post-calculation shift fields)","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"Shift not found or not owned by the user"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/timekeeping\/request":{"post":{"tags":["App\/Timekeeping"],"summary":"Submit timekeeping change request","description":"Only when `t_job_workings.status` is `checkout` or `company_confirmed` (post QR check-out) and `user_salary_confirmed_at` is null. Creates `t_job_working_requests` (status pending) and sets `t_job_workings.status` to `request_change`. Optional single break window via `start_break_time` \/ `end_break_time`; when omitted, the existing break on `t_job_workings` is used if it lies within the requested check-in\/out window. At most 5 requests per shift row; the 6th returns `timekeeping.max_request_working_time`.","operationId":"e91de07144467ba3bc44fbdeb6b6463b","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["job_id","job_working_id","start_working_time","end_working_time","request_reason"],"properties":{"job_id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":10},"start_working_time":{"type":"string","format":"date-time","example":"2026-06-03 09:00:00"},"end_working_time":{"type":"string","format":"date-time","example":"2026-06-03 18:00:00"},"start_break_time":{"description":"Break start (H:i), same as company job create","type":"string","example":"12:00","nullable":true},"end_break_time":{"description":"Break end (H:i); required when start_break_time is set","type":"string","example":"13:00","nullable":true},"request_reason":{"type":"string","example":"Forgot to check out on time"}},"type":"object"}}}},"responses":{"200":{"description":"Change request created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Timekeeping change request created successfully."},"data":{"description":"Created `JobWorkingRequest` row","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"400":{"description":"Business rule error. `error.key`: `timekeeping.change_request_after_salary_confirmed` when `user_salary_confirmed_at` is set; `timekeeping.change_request_pending_review` when shift status is `request_change`; `timekeeping.change_request_shift_already_paid` when shift status is `payment`; `timekeeping.change_request_company_already_approved` when shift status is `company_confirmed` and a prior request is `approved`; `timekeeping.change_request_requires_checkout` for other non-requestable statuses (e.g. `checkin`); `timekeeping.max_request_working_time` when 5 requests already exist for the shift."},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/timekeeping\/confirm":{"post":{"tags":["App\/Timekeeping"],"summary":"Confirm salary after check-out","description":"Only when `t_job_workings.status` is `checkout` or `company_confirmed`. Sets `user_salary_confirmed_at` and blocks further `POST \/timekeeping\/request` for the shift. Wallet credit happens at QR check-out; this endpoint does not change shift status to `payment`.","operationId":"9f7e7bc64b36f2c3089fa35115fbac66","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["job_id"],"properties":{"job_id":{"type":"integer","example":1},"branch_id":{"description":"Optional; when sent must match the job branch.","type":"integer","example":10}},"type":"object"}}}},"responses":{"200":{"description":"Salary confirmed","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Salary confirmed successfully."},"data":{"description":"Updated `JobWorking` with nested `job`","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation or business rule error"}},"security":[{"bearerAuth":[]}]}},"\/user\/profile":{"get":{"tags":["App"],"summary":"Get authenticated user profile","operationId":"94403608ae232233447fd9989443f1dc","responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"total_withdrawable_amount":{"type":"string","example":"12000.00"},"total_received_amount":{"description":"Cumulative salary credited to the user wallet (`t_user_wallets.total_amount`).","type":"string","example":"15000.00"},"has_unread_notifications":{"description":"True when at least one notification for this user has is_read = 0.","type":"boolean","example":true},"categories":{"description":"Selected medical profile categories (full m_category rows).","type":"array","items":{"type":"object"}},"skills":{"description":"Selected skills (full m_skills rows).","type":"array","items":{"type":"object"}},"workplaces":{"description":"Selected workplaces (full m_workplaces rows).","type":"array","items":{"type":"object"}},"workplace_experiences":{"description":"Workplace type experience rows with nested master objects.","type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"sub_category_details":{"type":"array","items":{"type":"object"}},"certificates":{"description":"Selected certificates (full m_certificates rows).","type":"array","items":{"type":"object"}},"experience_year":{"description":"Primary experience year from t_user_categories.experience_year_id.","type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]},"put":{"tags":["App"],"summary":"Update user profile","description":"Partial update \u2014 send only fields to change. Phone number is excluded (use \/user\/phone\/send-code flow). When any address field is sent, the server geocodes the merged address and updates latitude\/longitude (clients must not send coordinates). Medical profile uses categories[] (same shape as register\/update-info): only blocks sent are upserted; other user categories are preserved. Use DELETE \/user\/profile to remove professions.","operationId":"c1fe4ddeca043281e5eeb7d99788d527","requestBody":{"description":"Use `application\/json` for Swagger testing (no avatar). Use `multipart\/form-data` to upload `avatar`; send `categories` as a JSON string in that case.","required":true,"content":{"multipart\/form-data":{"schema":{"properties":{"first_name":{"type":"string","example":"Taro"},"last_name":{"type":"string","example":"Yamada"},"first_katakana_name":{"type":"string","example":"\u30bf\u30ed\u30a6"},"last_katakana_name":{"type":"string","example":"\u30e4\u30de\u30c0"},"dob":{"type":"string","format":"date","example":"1995-08-20"},"gender":{"type":"string","example":"male","nullable":true},"country_id":{"type":"integer","example":1,"nullable":true},"postal_code":{"type":"string","example":"1000001"},"prefecture_id":{"type":"integer","example":1},"district_id":{"type":"integer","example":1,"nullable":true},"administrative_address":{"type":"string","example":"Chiyoda-ku"},"street_address":{"type":"string","example":"1-1-1 Marunouchi"},"building_address":{"type":"string","example":"ABC Building 101","nullable":true},"self_pr":{"type":"string","nullable":true},"current_work_type_id":{"type":"integer","example":1,"nullable":true},"work_preference_id":{"type":"integer","example":2,"nullable":true},"job_change_interest_id":{"type":"integer","example":1,"nullable":true},"emergency_name":{"type":"string","example":"\u7dca\u6025\u9023\u7d61\u5148 \u592a\u90ce","nullable":true},"emergency_phone":{"type":"string","example":"09012345678","nullable":true},"categories":{"description":"JSON-encoded categories[] blocks (same shape as application\/json request). Example: array of objects with category_id and optional pivot ids.","type":"string"},"avatar":{"description":"Profile image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary","nullable":true}},"type":"object"}},"application\/json":{"schema":{"properties":{"first_name":{"type":"string","example":"Taro"},"last_name":{"type":"string","example":"Yamada"},"first_katakana_name":{"type":"string","example":"\u30bf\u30ed\u30a6"},"last_katakana_name":{"type":"string","example":"\u30e4\u30de\u30c0"},"dob":{"type":"string","format":"date","example":"1995-08-20"},"gender":{"type":"string","example":"male","nullable":true},"country_id":{"description":"Nationality \/ country master id (m_countries.id)","type":"integer","example":1,"nullable":true},"postal_code":{"type":"string","example":"1000001"},"prefecture_id":{"type":"integer","example":1},"district_id":{"type":"integer","example":1,"nullable":true},"administrative_address":{"type":"string","example":"Chiyoda-ku"},"street_address":{"type":"string","example":"1-1-1 Marunouchi"},"building_address":{"type":"string","example":"ABC Building 101","nullable":true},"self_pr":{"type":"string","nullable":true},"current_work_type_id":{"description":"m_current_work_types.id","type":"integer","example":1,"nullable":true},"work_preference_id":{"description":"m_work_preferences.id","type":"integer","example":2,"nullable":true},"job_change_interest_id":{"description":"m_job_change_interests.id","type":"integer","example":1,"nullable":true},"emergency_name":{"type":"string","example":"\u7dca\u6025\u9023\u7d61\u5148 \u592a\u90ce","nullable":true},"emergency_phone":{"type":"string","example":"09012345678","nullable":true},"categories":{"description":"Medical profile blocks (per profession). When sent, upserts only listed categories and their pivots; other categories are unchanged.","type":"array","items":{"$ref":"#\/components\/schemas\/UserMedicalCategoryProfileBlock"}},"avatar":{"description":"Profile image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Profile updated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"description":"Updated user with all relations","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["App"],"summary":"Remove medical profile categories","description":"Deletes the given category_ids and all user pivots scoped to those professions (skills, workplaces, licenses, certificates, \u2026). Other categories are preserved. Idempotent for category_ids the user does not have.","operationId":"d47c3bf63dcfc6262565486993d78b0b","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["category_ids"],"properties":{"category_ids":{"type":"array","items":{"type":"integer","example":3},"minItems":1}},"type":"object"}}}},"responses":{"200":{"description":"Categories removed successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"type":"boolean","example":true}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/user\/license-histories":{"get":{"tags":["App"],"summary":"List user licenses and license history","description":"User licenses and their history (raw lists).","operationId":"3514fed61a36d3eff82bfe72b9cd2b9d","parameters":[{"name":"category_id","in":"query","description":"Filter history by medical category (m_category.id).","required":false,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"user_licenses":{"type":"array","items":{"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/user\/quit-app":{"put":{"tags":["App"],"summary":"Quit \/ deactivate account","description":"Deactivates the user's account after verifying no active job shifts remain. No request parameters are required. Sets status to inactive and invalidates all JWT tokens. Re-registration is allowed after 30 days.","operationId":"8922fc4d8a1e25e0981cd24fdc45273b","responses":{"200":{"description":"Account deactivated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Your account has been deactivated successfully."},"data":{"type":"array","items":[]}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error or active jobs exist"}},"security":[{"bearerAuth":[]}]}},"\/user\/job\/completed":{"get":{"tags":["App jobs"],"summary":"List completed job workings","description":"Paginated JobWorking rows in payment or done only (excludes checkout and request_change). Optional status query filters to one. Date filters: `start_working_date` and `end_working_date` must be sent together; when both are present they take precedence over `year_month` (month filter is ignored). Each row includes selected JobWorking columns, nested job (id, name, status, company with name, company_branch with name), and transaction_logs: single withdraw log object or null \u2014 id, type, user_status, company_status, status, transaction_id, amount.","operationId":"dbb6ddadba3e16165d81b638a24183b9","parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"status","in":"query","description":"Filter by job working status (default: payment, done)","required":false,"schema":{"type":"string","enum":["payment","done"]}},{"name":"year_month","in":"query","description":"Filter by shift month (`t_job_workings.working_date`, format YYYY-MM). Ignored when both `start_working_date` and `end_working_date` are present.","required":false,"schema":{"type":"string","format":"date","example":"2026-06"}},{"name":"start_working_date","in":"query","description":"Working date range start (Y-m-d). Required together with `end_working_date`.","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Working date range end (Y-m-d). Required together with `start_working_date`.","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Paginated completed shifts","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/user\/job\/completed\/export":{"get":{"tags":["App jobs"],"summary":"Export completed shifts as wage ledger","description":"Downloads an XLSX wage ledger for the authenticated user. Requires `year_month` or both `start_working_date` and `end_working_date`. Uses the same status and date filters as GET `\/user\/job\/completed`. Footer row shows \u5408\u8a08\u91d1\u984d with SUM formulas for columns I\u2013L.","operationId":"4171fc191042b56f29f8a320ab27431a","parameters":[{"name":"status","in":"query","description":"Filter by job working status (default: all done statuses)","required":false,"schema":{"type":"string","enum":["checkout","company_confirmed","payment"]}},{"name":"year_month","in":"query","description":"Filter by shift month (`t_job_workings.working_date`, format YYYY-MM). Required when date range is not provided.","required":false,"schema":{"type":"string","format":"date","example":"2026-06"}},{"name":"start_working_date","in":"query","description":"Working date range start (Y-m-d). Required together with `end_working_date` when `year_month` is absent.","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","description":"Working date range end (Y-m-d). Required together with `start_working_date` when `year_month` is absent.","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Wage ledger XLSX file","content":{"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error or no data for selected filters"}},"security":[{"bearerAuth":[]}]}},"\/register\/update-info":{"post":{"tags":["App"],"summary":"Complete user registration","description":"Requires Bearer token from phone OTP verification (`auth:phone`). Phone numbers are taken from that session, not from the request body. Address is stored on registration; latitude and longitude are filled asynchronously via a queued job (do not send coordinates).","operationId":"40cc7e6f523ba78485faa87682079589","requestBody":{"description":"Use `application\/json` for Swagger testing (no avatar). Use `multipart\/form-data` to upload `avatar`; send `categories` as a JSON string in that case.","required":true,"content":{"multipart\/form-data":{"schema":{"required":["first_name","last_name","first_katakana_name","last_katakana_name","dob","country_id","postal_code","prefecture_id","administrative_address","street_address","categories"],"properties":{"first_name":{"type":"string","example":"Taro"},"last_name":{"type":"string","example":"Yamada"},"first_katakana_name":{"type":"string","example":"\u30bf\u30ed\u30a6"},"last_katakana_name":{"type":"string","example":"\u30e4\u30de\u30c0"},"dob":{"type":"string","format":"date","example":"1995-08-20"},"gender":{"type":"string","example":"male","nullable":true},"country_id":{"type":"integer","example":1},"postal_code":{"type":"string","example":"1000001"},"prefecture_id":{"type":"integer","example":1},"district_id":{"type":"integer","example":1,"nullable":true},"administrative_address":{"type":"string","example":"Chiyoda-ku"},"street_address":{"type":"string","example":"1-1-1 Marunouchi"},"building_address":{"type":"string","example":"ABC Building 101","nullable":true},"self_pr":{"type":"string","example":"Backend engineer","nullable":true},"categories":{"description":"Required. JSON-encoded categories[] blocks (same shape as application\/json request). Example: array of objects with category_id and optional pivot ids.","type":"string"},"current_work_type_id":{"type":"integer","example":1,"nullable":true},"work_preference_id":{"type":"integer","example":2,"nullable":true},"job_change_interest_id":{"type":"integer","example":1,"nullable":true},"avatar":{"description":"Profile image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB).","type":"string","format":"binary"}},"type":"object"}},"application\/json":{"schema":{"required":["first_name","last_name","first_katakana_name","last_katakana_name","dob","country_id","postal_code","prefecture_id","administrative_address","street_address","categories"],"properties":{"first_name":{"type":"string","example":"Taro"},"last_name":{"type":"string","example":"Yamada"},"first_katakana_name":{"type":"string","example":"\u30bf\u30ed\u30a6"},"last_katakana_name":{"type":"string","example":"\u30e4\u30de\u30c0"},"dob":{"type":"string","format":"date","example":"1995-08-20"},"gender":{"type":"string","example":"male","nullable":true},"country_id":{"description":"Nationality \/ country master id (m_countries.id)","type":"integer","example":1},"postal_code":{"type":"string","example":"1000001"},"prefecture_id":{"type":"integer","example":1},"district_id":{"type":"integer","example":1,"nullable":true},"administrative_address":{"type":"string","example":"Chiyoda-ku"},"street_address":{"type":"string","example":"1-1-1 Marunouchi"},"building_address":{"type":"string","example":"ABC Building 101","nullable":true},"self_pr":{"type":"string","example":"Backend engineer","nullable":true},"categories":{"description":"Required. One block per medical profession (m_category.id).","type":"array","items":{"$ref":"#\/components\/schemas\/UserMedicalCategoryProfileBlock"},"minItems":1},"current_work_type_id":{"description":"m_current_work_types.id","type":"integer","example":1,"nullable":true},"work_preference_id":{"description":"m_work_preferences.id","type":"integer","example":2,"nullable":true},"job_change_interest_id":{"description":"m_job_change_interests.id","type":"integer","example":1,"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Successful Operation"},"401":{"description":"Unauthenticated (missing or invalid phone OTP token)"},"422":{"description":"Validation Error"},"500":{"description":"Internal Server Error"}},"security":[{"bearerAuth":[]}]}},"\/user\/phone\/send-code":{"post":{"tags":["App"],"summary":"Send OTP to new phone number","description":"Send OTP to new phone number for phone change verification.","operationId":"8b575a9e556e6008decfc589d9333be0","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["phone_number"],"properties":{"phone_number":{"description":"New phone number (8-15 digits, optional leading +)","type":"string","example":"0901234567"}},"type":"object"}}}},"responses":{"200":{"description":"OTP sent successfully (mock OTP: 1234)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"type":"array","items":[]}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error or phone already taken"}},"security":[{"bearerAuth":[]}]}},"\/user\/phone\/verify-code":{"post":{"tags":["App"],"summary":"Verify OTP and update phone number","description":"Verify OTP and update phone number. Returns new JWT token.","operationId":"464b959a88b8f8b20fb6fa47a5e914da","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["phone_number","code"],"properties":{"phone_number":{"type":"string","example":"0901234567"},"code":{"description":"4-digit OTP code","type":"string","example":"1234"}},"type":"object"}}}},"responses":{"200":{"description":"Phone updated. Old token is invalidated \u2014 use the returned token.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"integer","example":3600},"token_type":{"type":"string","example":"bearer"},"user":{"description":"Updated user","type":"object"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Invalid or expired OTP"}},"security":[{"bearerAuth":[]}]}},"\/reviews\/users\/summary":{"get":{"tags":["App Review users"],"summary":"Get worker review summary","description":"Returns aggregated review scores and total review count for the authenticated worker (`t_user_review_summaries`). Only submitted company reviews (`status = reviewed`) are included.","operationId":"c30f02e3200a54e715804abdce8d610d","responses":{"200":{"description":"Review summary","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Worker review summary fetched successfully."},"data":{"properties":{"user_id":{"type":"integer","example":10},"punctuality_avg":{"type":"string","example":"4.25"},"appearance_avg":{"type":"string","example":"4.00"},"communication_avg":{"type":"string","example":"4.50"},"work_attitude_avg":{"type":"string","example":"4.00"},"skill_avg":{"type":"string","example":"4.25"},"total_avg":{"type":"string","example":"4.19"},"total_reviews":{"type":"integer","example":8},"user":{"properties":{"id":{"type":"integer","example":10},"name":{"type":"string","example":"Demo User"},"image":{"type":"string","example":"https:\/\/example.com\/avatar.png","nullable":true}},"type":"object"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/reviews\/users":{"get":{"tags":["App Review users"],"summary":"List worker reviews","description":"Returns paginated company reviews for the authenticated worker. Only submitted reviews (`status = reviewed`) are returned. Sorted by `id` descending (newest first).","operationId":"d3e8ecf6e4c33367d4801b2513e5cf92","parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}}],"responses":{"200":{"description":"Review list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":42},"job_id":{"type":"integer","example":7},"company_branch_id":{"type":"integer","example":3},"punctuality":{"type":"integer","example":5},"appearance":{"type":"integer","example":4},"communication":{"type":"integer","example":5},"work_attitude":{"type":"integer","example":4},"skill":{"type":"integer","example":5},"average_score":{"type":"string","example":"4.60"},"comment":{"type":"string","example":"Great worker.","nullable":true},"created_at":{"type":"string","format":"date-time","example":"2026-06-01 14:30:00"},"company_branch":{"properties":{"id":{"type":"integer","example":3},"name":{"type":"string","example":"Shinjuku Medical Clinic"}},"type":"object"}},"type":"object"}},"total":{"type":"integer","example":8},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/user\/withdraw":{"post":{"tags":["App Wallet"],"summary":"Withdraw from wallet","description":"Sets `t_transaction_logs.user_status` from `pending` to `approved`. When `company_status` is already `approved` on the same withdraw row, the shift moves to `done`. Optional `job_id` scopes to the latest shift for that job.","operationId":"50ae986648fb489eadf05f2b5f7610eb","requestBody":{"required":false,"content":{"application\/json":{"schema":{"properties":{"job_id":{"description":"Optional. Job ID (`t_jobs.id`); when present, only that job's latest shift is withdrawn. Omit or null to withdraw all in-wallet rows.","type":"integer","example":42,"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Withdrawal recorded","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"transaction_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"},"amount":{"type":"string","example":"5000.00"},"job_working_ids":{"type":"array","items":{"type":"integer"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation or business rule error"}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/application-histories":{"get":{"tags":["Company Branch"],"summary":"Get application histories grouped by branch and month","operationId":"595b1681f8d2ec7b0280eee4efd4385e","parameters":[{"name":"approve_month","in":"query","description":"Filter by month (format: YYYY-MM). If omitted, all data is returned.","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-(0[1-9]|1[0-2])$","example":"2026-04"}},{"name":"branch_ids[]","in":"query","description":"Filter by branch IDs","required":false,"schema":{"type":"array","items":{"type":"integer"},"example":[1,2]}},{"name":"order_by","in":"query","description":"Sort column","required":false,"schema":{"type":"string","enum":["approve_month","branch_name","approved_count"],"example":"approve_month"}},{"name":"order_direction","in":"query","description":"Sort direction","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":10}}],"responses":{"200":{"description":"Successful response","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"branch_id":{"type":"integer","example":1},"branch_name":{"type":"string","example":"Demo Branch 01"},"approve_month":{"type":"string","example":"2026-04"},"approved_count":{"type":"integer","example":3}},"type":"object"}},"total":{"type":"integer","example":2},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/application-histories\/export-csv":{"post":{"tags":["Company Branch"],"summary":"Export application histories to CSV","description":"Export approved application histories for the authenticated company. Use optional `year_month` (`YYYY-MM`) and\/or `company_branch_ids[]` filters, or pass `filters` as branch\/month pairs. When `filters` is omitted, `year_month` and `company_branch_ids` are combined with AND logic; omitted filters export all matching company rows.","operationId":"exportApplicationHistoriesCsv","requestBody":{"required":false,"content":{"application\/json":{"schema":{"properties":{"year_month":{"description":"Filter `approve_at` by calendar month (`YYYY-MM`).","type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-01"},"company_branch_ids":{"description":"Filter by company branches. Every id must belong to the authenticated company.","type":"array","items":{"type":"integer","minimum":1},"example":[1,2]},"filters":{"description":"Optional branch\/month pairs. When present, each item is matched as one branch_id + approve_month pair (OR logic). `year_month` \/ `company_branch_ids` are ignored.","type":"array","items":{"required":["branch_id","approve_month"],"properties":{"branch_id":{"type":"integer","example":1},"approve_month":{"type":"string","example":"2026-01"}},"type":"object"},"example":[{"branch_id":1,"approve_month":"2026-01"},{"branch_id":1,"approve_month":"2026-02"}]}},"type":"object"}}}},"responses":{"200":{"description":"CSV file download","headers":{"Content-Disposition":{"description":"attachment; filename=\u5fdc\u52df\u5c65\u6b74.csv","schema":{"type":"string"}}},"content":{"text\/csv":[]}},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/auth\/login":{"post":{"tags":["Company"],"summary":"Login as a company user","description":"Login: email + password, returns JWT access_token and user.","operationId":"84c1ecda349614c12e5d27b2c66948f5","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["email","password"],"properties":{"email":{"type":"string","format":"email","example":"company@example.com"},"password":{"type":"string","format":"password","example":"password"}},"type":"object"}}}},"responses":{"200":{"description":"Successful login","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Login successfully."},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer"},"user":{"$ref":"#\/components\/schemas\/CompanyUser"}},"type":"object"}},"type":"object"}}}},"400":{"description":"Invalid credentials","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"These credentials do not match our records."},"error":{"properties":{"key":{"type":"string","example":"auth.unauthorized"},"content":{"type":"string","example":"These credentials do not match our records."}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/company\/auth\/logout":{"post":{"tags":["Company"],"summary":"Logout","description":"Logout current company account.","operationId":"398d982c205fed86fbb79006061b633e","responses":{"200":{"description":"Successful Operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Logout successfully."},"data":{"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/auth\/forgot-password":{"post":{"tags":["Company"],"summary":"Request password reset email","description":"Request a reset email for company user password. Unlike the admin forgot-password\nendpoint, this one returns a specific {@code admin.password_reset_user_not_found}\nerror (reusing admin lang keys) when the email is not registered.","operationId":"d14901118d7072d67cb6fdc57a58afa8","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["email"],"properties":{"email":{"type":"string","format":"email","example":"company@example.com"}},"type":"object"}}}},"responses":{"200":{"description":"Password reset email sent","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Email was sent successfully."},"data":{"type":"object"}},"type":"object"}}}},"400":{"description":"Email not registered","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"We could not find a user with that email address."},"error":{"properties":{"key":{"type":"string","example":"admin.password_reset_user_not_found"},"content":{"type":"string","example":"We could not find a user with that email address."}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/company\/auth\/reset-password":{"post":{"tags":["Company"],"summary":"Reset company user password using token","description":"Reset company user password using the reset JWT. `password_confirmation` is\nrequired (enforced by the shared {@see \\App\\Http\\Requests\\Api\\Common\\Auth\\ResetPasswordRequest}).\nReuses admin lang keys for error responses.","operationId":"f2bac602ace2b8ae04cc38c12f9af356","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["token","password","password_confirmation"],"properties":{"token":{"type":"string","example":"reset_token_here"},"password":{"type":"string","example":"newPass123!"},"password_confirmation":{"type":"string","example":"newPass123!"}},"type":"object"}}}},"responses":{"200":{"description":"Password reset successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Password has been reset successfully."},"data":{"type":"object"}},"type":"object"}}}},"400":{"description":"Reset failed (invalid\/expired token, wrong token type, stale version, user not found)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Invalid or expired reset token."},"error":{"properties":{"key":{"description":"One of: admin.invalid_or_expired_reset_token, admin.invalid_reset_token, admin.password_reset_user_not_found","type":"string","example":"admin.invalid_or_expired_reset_token"},"content":{"type":"string","example":"Invalid or expired reset token."}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error (missing fields or password_confirmation mismatch)","content":{"application\/json":{"schema":[]}}}}}},"\/company\/auth\/refresh-token":{"post":{"tags":["Company"],"summary":"Refresh JWT token","description":"Refresh company JWT access token with refresh token.","operationId":"ef7df4a8d2bf79cc0ba23f25f77034a2","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["refresh_token"],"properties":{"refresh_token":{"type":"string","example":"refresh_token_here"}},"type":"object"}}}},"responses":{"200":{"description":"Token was refreshed successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Token was refreshed successfully."},"data":{"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer"},"user":{"$ref":"#\/components\/schemas\/CompanyUser"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Invalid or expired refresh token","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"error":{"properties":{"key":{"type":"string","example":"jwt.exception"}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}}}},"\/company\/branch\/user":{"get":{"tags":["Company Branch User"],"summary":"List branch users for the company","description":"Returns branch users whose default branch belongs to the authenticated company. Loads roles from t_branch_user_roles and m_branch_roles, plus default branch info.","operationId":"companyListBranchUsers","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"branch_ids[]","in":"query","description":"Filter by company branch IDs. Supports array, comma-separated, or JSON array formats.","required":false,"schema":{"type":"array","items":{"type":"integer"},"example":[1,2]}},{"name":"branch_role_ids[]","in":"query","description":"Filter users by role IDs (t_branch_user_roles). Supports array, comma-separated, or JSON array formats.","required":false,"schema":{"type":"array","items":{"type":"integer"},"example":[1,2]}},{"name":"search","in":"query","description":"Search name or furigana (partial match)","required":false,"schema":{"type":"string","maxLength":255}},{"name":"order_by","in":"query","description":"Sort column (single field)","required":false,"schema":{"type":"string","enum":["id","name","email","created_at"],"example":"id"}},{"name":"order_direction","in":"query","description":"Used with order_by; asc or desc (case-insensitive)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/BranchUser"}},"total":{"type":"integer","example":100},"last_page":{"type":"integer","example":7},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Company Branch User"],"summary":"Create a branch user","description":"Create branch user.","operationId":"companyCreateBranchUser","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["name","email","password","branch_ids"],"properties":{"name":{"type":"string","maxLength":255,"example":"Yamada Taro"},"email":{"type":"string","format":"email","example":"branch@example.com"},"password":{"type":"string","format":"password","minLength":8,"example":"password"},"branch_ids":{"description":"Assigned branch ids (t_company_branches.id) belonging to the company","type":"array","items":{"type":"integer"},"example":[1,2]},"furigana":{"type":"string","maxLength":255,"nullable":true},"phone_number":{"type":"string","maxLength":64,"example":"0981111111","nullable":true},"branch_role_ids":{"description":"Role ids from m_branch_roles","type":"array","items":{"type":"integer"},"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Branch user created successfully."},"data":{"$ref":"#\/components\/schemas\/BranchUser"}},"type":"object"}}}},"400":{"description":"Default branch does not belong to the authenticated company (secondary guard; validation normally catches this as 422)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"The selected branch does not belong to the company."},"error":{"properties":{"key":{"type":"string","example":"branch_user.invalid_company_branch"},"content":{"type":"string","example":"The selected branch does not belong to the company."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/user\/{id}":{"get":{"tags":["Company Branch User"],"summary":"Get branch user by id","description":"Returns a branch user belonging to the authenticated company.","operationId":"companyShowBranchUser","parameters":[{"name":"id","in":"path","description":"Branch user id (t_branch_user_profiles.id)","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Branch user fetched successfully."},"data":{"$ref":"#\/components\/schemas\/BranchUser"}},"type":"object"}}}},"400":{"description":"Branch user not found or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Branch user not found."},"error":{"properties":{"key":{"type":"string","example":"branch_user.not_found"},"content":{"type":"string","example":"Branch user not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Branch User"],"summary":"Update a branch user","description":"Update branch user.","operationId":"companyUpdateBranchUser","parameters":[{"name":"id","in":"path","description":"Branch user id (t_branch_user_profiles.id)","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"properties":{"name":{"type":"string","maxLength":255,"example":"Yamada Taro"},"email":{"description":"New email \u2014 must be unique across branch users","type":"string","format":"email","maxLength":255,"example":"new@example.com","nullable":true},"furigana":{"type":"string","maxLength":255,"nullable":true},"phone_number":{"type":"string","maxLength":64,"example":"0981111111","nullable":true},"branch_ids":{"description":"Replace assigned branches (must belong to the same company)","type":"array","items":{"type":"integer"},"example":[2,3],"nullable":true},"password":{"description":"New password","type":"string","format":"password","minLength":8,"nullable":true},"branch_role_ids":{"description":"Role ids from m_branch_roles","type":"array","items":{"type":"integer"},"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Updated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Branch user updated successfully."},"data":{"$ref":"#\/components\/schemas\/BranchUser"}},"type":"object"}}}},"400":{"description":"Branch user not found or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Branch user not found."},"error":{"properties":{"key":{"type":"string","example":"branch_user.not_found"},"content":{"type":"string","example":"Branch user not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Company Branch User"],"summary":"Delete a branch user","description":"Soft deletes a branch user whose default branch belongs to the authenticated company. Also removes the user's role assignments.","operationId":"companyDeleteBranchUser","parameters":[{"name":"id","in":"path","description":"Branch user id (t_branch_user_profiles.id)","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"type":"object","nullable":true}},"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"404":{"description":"Not found"}},"security":[{"bearerAuth":[]}]}},"\/company\/branch":{"get":{"tags":["Company Branch"],"summary":"Get a list of company branches","description":"List company branches.","operationId":"f1fac361e9edfcfefa02d05f49942e23","parameters":[{"name":"page","in":"query","description":"Page number for pagination","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Number of items per page","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"region_ids[]","in":"query","description":"Filter by one or more company region IDs (t_company_regions.id). Pass as region_ids[]=1&region_ids[]=2","required":false,"schema":{"type":"array","items":{"type":"integer","example":1}}},{"name":"prefecture_id","in":"query","description":"Filter by prefecture ID","required":false,"schema":{"type":"integer","example":10}},{"name":"district_id","in":"query","description":"Filter by district ID","required":false,"schema":{"type":"integer","example":8}},{"name":"id","in":"query","description":"Filter by company branch ID (must belong to the authenticated company). When set, returns only that branch.","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"search_key","in":"query","description":"Search in branch name and responsible_person_email (partial match)","required":false,"schema":{"type":"string","maxLength":255,"example":"Shibuya"}},{"name":"order_by","in":"query","description":"Sort column (with order_direction)","required":false,"schema":{"type":"string","enum":["id","name","created_at"]}},{"name":"order_direction","in":"query","description":"asc or desc (with order_by)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list of branches scoped to the authenticated company. Response is the bare paginator shape from AppBaseController::pagination() (no success\/message wrapper).","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/CompanyBranch"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Company Branch"],"summary":"Create a new company branch (company is taken from the authenticated company JWT, not the request body)","description":"Use `application\/json` or `multipart\/form-data`. For face image upload, send `face_photo` as a file (multipart).","operationId":"50fed7f0aacd8b8d037aed3b35c945a9","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["name","prefecture_id","address_line","latitude","longitude"],"properties":{"name":{"type":"string","maxLength":255,"example":"Branch A"},"region_ids":{"description":"Company region IDs (t_company_regions.id)","type":"array","items":{"type":"integer","example":1},"nullable":true},"prefecture_id":{"description":"ID of the prefecture, must exist in m_prefectures table","type":"integer","example":13},"district_id":{"description":"ID of the district, must exist in m_districts table","type":"integer","example":5,"nullable":true},"postal_code":{"type":"string","maxLength":32,"example":"1500002","nullable":true},"address_line":{"type":"string","maxLength":500,"example":"123 Some St, City"},"latitude":{"description":"Branch latitude (WGS84)","type":"number","format":"float","maximum":90,"minimum":-90,"example":35.658034},"longitude":{"description":"Branch longitude (WGS84)","type":"number","format":"float","maximum":180,"minimum":-180,"example":139.701636},"access_note":{"type":"string","maxLength":2000,"example":"How to access the branch","nullable":true},"has_on_site_parking":{"type":"boolean","example":true,"nullable":true},"commuting_note":{"type":"string","maxLength":2000,"example":"Commuting information","nullable":true},"responsible_person_name":{"type":"string","maxLength":255,"example":"Mr. Yamada","nullable":true},"greeting_message":{"type":"string","maxLength":2000,"example":"Welcome to our branch!","nullable":true},"worker_contact_name":{"type":"string","maxLength":255,"example":"Jane Smith","nullable":true},"worker_contact_phone":{"type":"string","maxLength":20,"example":"09012345678","nullable":true},"emergency_contact":{"type":"string","maxLength":255,"example":"Call 119","nullable":true},"responsible_person_email":{"type":"string","maxLength":255,"example":"yamada@example.com","nullable":true},"first_confirmation_auto_message":{"type":"string","maxLength":2000,"example":"Thank you for your application.","nullable":true},"facility_open_date":{"type":"string","format":"date","example":"2023-04-01","nullable":true},"unemployment_insurance_office_number":{"type":"string","maxLength":50,"example":"87654321","nullable":true},"category_ids":{"description":"Category IDs assigned to the authenticated company (t_company_category). Stored in t_company_branch_category.","type":"array","items":{"type":"integer","example":1},"nullable":true},"travel_method_ids":{"description":"IDs from m_travel_methods (pivot t_company_branch_travel_methods)","type":"array","items":{"type":"integer","example":1},"nullable":true},"face_photo":{"description":"Branch face \/ facility image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true},"responsible_person_photo":{"description":"Responsible person photo (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true},"worker_contact_photo":{"description":"Worker contact photo (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Successful creation of company branch","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/CompanyBranch"},"message":{"type":"string","example":"Company branch created successfully."}},"type":"object"}}}},"422":{"description":"Unprocessable Entity (validation error; includes missing required fields and invalid prefecture\/region\/district ids)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/{id}":{"get":{"tags":["Company Branch"],"summary":"Show company branch","description":"Retrieve a specific company branch by its ID.","operationId":"showCompanyBranch","parameters":[{"name":"id","in":"path","description":"The ID of the company branch","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful operation","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company branch fetched successfully."},"data":{"$ref":"#\/components\/schemas\/CompanyBranch"}},"type":"object"}}}},"400":{"description":"Branch not found or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company branch not found."},"error":{"properties":{"key":{"type":"string","example":"company_branch.not_found"},"content":{"type":"string","example":"Company branch not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Branch"],"summary":"Update a specific company branch (company scope from JWT)","description":"Update company branch (PUT `\/company\/branch\/{id}`). Company cannot be changed via the body. Use `multipart\/form-data` to upload or replace `face_photo`.","operationId":"e951555623686331db24e3443ded6ccf","parameters":[{"name":"id","in":"path","description":"ID of the company branch to update","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"properties":{"name":{"type":"string","maxLength":255,"example":"Branch A"},"address_line":{"type":"string","maxLength":500,"example":"123 Some St, City"},"prefecture_id":{"description":"ID of the prefecture, must exist in m_prefectures table","type":"integer","example":13},"region_ids":{"description":"Company region IDs (t_company_regions.id)","type":"array","items":{"type":"integer","example":1},"nullable":true},"district_id":{"description":"ID of the district, must exist in m_districts table","type":"integer","example":5,"nullable":true},"postal_code":{"type":"string","maxLength":32,"example":"1500002","nullable":true},"access_note":{"type":"string","maxLength":2000,"example":"How to access the branch","nullable":true},"has_on_site_parking":{"type":"boolean","example":true,"nullable":true},"commuting_note":{"type":"string","maxLength":2000,"example":"Commuting information","nullable":true},"responsible_person_name":{"type":"string","maxLength":255,"example":"Mr. Yamada","nullable":true},"greeting_message":{"type":"string","maxLength":2000,"example":"Welcome to our branch!","nullable":true},"worker_contact_name":{"type":"string","maxLength":255,"example":"Jane Smith","nullable":true},"worker_contact_phone":{"type":"string","maxLength":20,"example":"09012345678","nullable":true},"emergency_contact":{"type":"string","maxLength":255,"example":"Call 119","nullable":true},"responsible_person_email":{"type":"string","maxLength":255,"example":"yamada@example.com","nullable":true},"first_confirmation_auto_message":{"type":"string","maxLength":2000,"nullable":true},"facility_open_date":{"type":"string","format":"date","nullable":true},"unemployment_insurance_office_number":{"type":"string","maxLength":50,"nullable":true},"category_ids":{"description":"Category IDs assigned to the authenticated company (t_company_category). Stored in t_company_branch_category. Empty array clears links.","type":"array","items":{"type":"integer","example":1},"nullable":true},"travel_method_ids":{"type":"array","items":{"type":"integer"},"nullable":true},"face_photo":{"description":"Replace branch face image (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true},"responsible_person_photo":{"description":"Replace responsible person photo (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true},"worker_contact_photo":{"description":"Replace worker contact photo (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Branch updated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company branch updated successfully."},"data":{"$ref":"#\/components\/schemas\/CompanyBranch"}},"type":"object"}}}},"400":{"description":"Branch not found or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Company branch not found."},"error":{"properties":{"key":{"type":"string","example":"company_branch.not_found"},"content":{"type":"string","example":"Company branch not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/{id}\/qr-download":{"get":{"tags":["Company Branch"],"summary":"Download branch attendance QR code (SVG)","description":"Downloads the clock-in\/out QR code SVG for the branch. Branch must belong to the authenticated company and have a generated QR record.","operationId":"downloadCompanyBranchQr","parameters":[{"name":"id","in":"path","description":"The ID of the company branch","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"SVG file download","content":{"image\/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Branch not found, does not belong to the company, or QR code is missing","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"QR code is not available for this branch."},"error":{"properties":{"key":{"type":"string","example":"company_branch.qr_not_found"},"content":{"type":"string","example":"QR code is not available for this branch."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/{id}\/reviews":{"get":{"tags":["Company Branch"],"summary":"List reviews of a company branch","description":"Returns paginated reviews (t_company_branch_reviews) for a branch belonging to the authenticated company.","operationId":"companyListBranchReviews","parameters":[{"name":"id","in":"path","description":"Company branch id (t_company_branches.id)","required":true,"schema":{"type":"integer","example":1}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["id","average_score"],"example":"id"}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer","example":10},"company_branch_id":{"type":"integer","example":1},"user_id":{"type":"integer","example":5},"work_environment":{"type":"integer","example":5},"guidance":{"type":"integer","example":4},"equipment":{"type":"integer","example":5},"average_score":{"type":"number","format":"float","example":4.67},"comment":{"type":"string","example":"Great place.","nullable":true},"created_at":{"type":"string","format":"date-time"},"user":{"properties":{"id":{"type":"integer","example":5},"name":{"type":"string","example":"Yamada Taro"},"katakana_name":{"type":"string","nullable":true},"dob":{"type":"string","format":"date","example":"1990-05-15","nullable":true},"gender":{"type":"string","example":"1","nullable":true},"avatar_file_id":{"type":"integer","nullable":true}},"type":"object"}},"type":"object"}},"total":{"type":"integer","example":23},"last_page":{"type":"integer","example":2},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"400":{"description":"Branch not found or does not belong to the company"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/information":{"get":{"tags":["Company Information"],"summary":"Get company information","description":"Returns the company's information. Requires company admin type.","operationId":"5e449e303f28f3770d84b0cae76d5b08","responses":{"200":{"description":"Company information retrieved successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company information retrieved successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo Company"},"furigana":{"type":"string","example":"\u30c7\u30e2\u30ab\u30f3\u30d1\u30cb\u30fc","nullable":true},"email":{"type":"string","format":"email","example":"company@example.com"},"prefecture_id":{"type":"integer","example":13,"nullable":true},"address":{"type":"string","example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"representative_name":{"type":"string","example":"\u5c71\u7530 \u592a\u90ce","nullable":true},"business_content":{"type":"string","example":"IT staffing services.","nullable":true},"person_in_charge_name":{"type":"string","example":"\u9234\u6728 \u4e00\u90ce","nullable":true},"person_in_charge_email":{"type":"string","format":"email","example":"billing@example.com","nullable":true},"person_in_charge_expenses":{"type":"array","items":{"properties":{"name":{"type":"string","example":"Expense Contact","nullable":true},"email":{"type":"string","format":"email","example":"expense1@example.com"}},"type":"object"},"maxItems":5,"nullable":true},"tax_code":{"type":"string","example":"T1234567890","nullable":true},"bank_account":{"description":"Bank account info (t_company_bank_accounts)","properties":{"bank_id":{"type":"integer","example":1,"nullable":true},"bank_branch_id":{"type":"integer","example":1,"nullable":true},"bank_account_type_id":{"type":"integer","example":1,"nullable":true},"bank_account_number":{"type":"string","example":"1234567","nullable":true},"bank_account_name":{"type":"string","example":"\u30e4\u30de\u30c0\u30bf\u30ed\u30a6","nullable":true},"bank":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"\u4e09\u83f1UFJ\u9280\u884c"},"name_half_size":{"type":"string","example":"\uff90\uff82\uff8b\uff9e\uff7cUFJ\uff77\uff9e\uff9d\uff7a\uff73"}},"type":"object","nullable":true},"bank_branch":{"properties":{"id":{"type":"integer","example":1},"bank_id":{"type":"integer","example":1},"code":{"type":"string","example":"001"},"name":{"type":"string","example":"\u6771\u4eac\u55b6\u696d\u90e8"}},"type":"object","nullable":true},"account_type":{"properties":{"id":{"type":"integer","example":1},"code":{"type":"string","example":"01"},"name":{"type":"string","example":"\u666e\u901a"}},"type":"object","nullable":true}},"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"403":{"description":"Forbidden \u2014 company user is not admin type"}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Information"],"summary":"Update company information","description":"Updates the company's information. Requires company admin type.","operationId":"f11df1bba1903309496c3926e381e55d","requestBody":{"required":true,"content":{"application\/json":{"schema":{"properties":{"name":{"type":"string","maxLength":255,"example":"Demo Company"},"furigana":{"type":"string","maxLength":255,"example":"\u30c7\u30e2\u30ab\u30f3\u30d1\u30cb\u30fc","nullable":true},"email":{"type":"string","format":"email","maxLength":255,"example":"company@example.com","nullable":true},"prefecture_id":{"type":"integer","example":13,"nullable":true},"address":{"type":"string","maxLength":500,"example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"representative_name":{"type":"string","maxLength":255,"example":"\u5c71\u7530 \u592a\u90ce","nullable":true},"business_content":{"type":"string","maxLength":2000,"example":"IT staffing services.","nullable":true},"person_in_charge_name":{"type":"string","maxLength":255,"example":"\u9234\u6728 \u4e00\u90ce","nullable":true},"person_in_charge_email":{"type":"string","format":"email","maxLength":255,"example":"billing@example.com","nullable":true},"person_in_charge_expenses":{"type":"array","items":{"properties":{"name":{"type":"string","maxLength":255,"example":"Expense Contact","nullable":true},"email":{"type":"string","format":"email","maxLength":255,"example":"expense1@example.com"}},"type":"object"},"maxItems":5,"nullable":true},"tax_code":{"type":"string","maxLength":50,"example":"T1234567890","nullable":true},"bank_id":{"description":"Bank id (m_banks.id)","type":"integer","example":1,"nullable":true},"bank_branch_id":{"description":"Bank branch id (m_bank_branches.id)","type":"integer","example":1,"nullable":true},"bank_account_type_id":{"description":"Bank account type id (m_bank_account_types.id)","type":"integer","example":1,"nullable":true},"bank_account_number":{"type":"string","maxLength":50,"example":"1234567","nullable":true},"bank_account_name":{"type":"string","maxLength":255,"example":"\u30e4\u30de\u30c0\u30bf\u30ed\u30a6","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Company information updated successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Company information updated successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo Company"},"furigana":{"type":"string","example":"\u30c7\u30e2\u30ab\u30f3\u30d1\u30cb\u30fc","nullable":true},"email":{"type":"string","format":"email","example":"company@example.com","nullable":true},"prefecture_id":{"type":"integer","example":13,"nullable":true},"address":{"type":"string","example":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a1-1-1","nullable":true},"representative_name":{"type":"string","example":"\u5c71\u7530 \u592a\u90ce","nullable":true},"bank_account":{"properties":{"bank_id":{"type":"integer","example":1,"nullable":true},"bank_branch_id":{"type":"integer","example":1,"nullable":true},"bank_account_type_id":{"type":"integer","example":1,"nullable":true},"bank_account_number":{"type":"string","example":"1234567","nullable":true},"bank_account_name":{"type":"string","example":"\u30e4\u30de\u30c0\u30bf\u30ed\u30a6","nullable":true},"bank":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"\u4e09\u83f1UFJ\u9280\u884c"},"name_half_size":{"type":"string","example":"\uff90\uff82\uff8b\uff9e\uff7cUFJ\uff77\uff9e\uff9d\uff7a\uff73"}},"type":"object","nullable":true},"bank_branch":{"properties":{"id":{"type":"integer","example":1},"bank_id":{"type":"integer","example":1},"code":{"type":"string","example":"001"},"name":{"type":"string","example":"\u6771\u4eac\u55b6\u696d\u90e8"}},"type":"object","nullable":true},"account_type":{"properties":{"id":{"type":"integer","example":1},"code":{"type":"string","example":"01"},"name":{"type":"string","example":"\u666e\u901a"}},"type":"object","nullable":true}},"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"403":{"description":"Forbidden \u2014 company user is not admin type"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications":{"get":{"tags":["Company Notification"],"summary":"Get paginated list of notifications","description":"Returns paginated notifications for the authenticated company user. Can be filtered by is_read status.","operationId":"getCompanyNotifications","parameters":[{"name":"page","in":"query","description":"Page number for pagination","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"is_read","in":"query","description":"Filter by read status (0 = unread, 1 = read)","required":false,"schema":{"type":"integer","enum":[0,1]}},{"name":"order_by","in":"query","description":"Field to order by (id, created_at, updated_at)","required":false,"schema":{"type":"string","enum":["id","created_at","updated_at"],"example":"id"}},{"name":"order_direction","in":"query","description":"Sort direction (asc or desc)","required":false,"schema":{"type":"string","enum":["asc","desc"],"example":"desc"}}],"responses":{"200":{"description":"Paginated notification list","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Notifications retrieved successfully."},"data":{"$ref":"#\/components\/schemas\/NotificationList"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/unread-count":{"get":{"tags":["Company Notification"],"summary":"Get unread notification count","description":"Returns the count of unread notifications for the authenticated company user.","operationId":"getUnreadNotificationCount","responses":{"200":{"description":"Successfully retrieved unread count","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Unread count retrieved successfully."},"data":{"properties":{"unread_count":{"type":"integer","example":5}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/{id}\/read":{"put":{"tags":["Company Notification"],"summary":"Mark a notification as read","description":"Marks a specific notification as read. The notification must belong to the authenticated company user's company\/branch.","operationId":"markNotificationAsRead","parameters":[{"name":"id","in":"path","description":"Notification ID","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Notification marked as read","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Notification marked as read."}},"type":"object"}}}},"400":{"description":"Notification not found or does not belong to the company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Notification not found."},"error":{"properties":{"key":{"type":"string","example":"notification.not_found"},"content":{"type":"string","example":"Notification not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/read":{"put":{"tags":["Company Notification"],"summary":"Mark multiple notifications as read","description":"Marks multiple notifications as read by an array of IDs.","operationId":"markNotificationsAsReadBulk","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[1,2,3]}},"type":"object"}}}},"responses":{"200":{"description":"Notifications marked as read","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Notifications marked as read."},"data":{"properties":{"count":{"type":"integer","example":3}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/unread":{"put":{"tags":["Company Notification"],"summary":"Mark multiple notifications as unread","description":"Marks multiple notifications as unread by an array of IDs.","operationId":"markNotificationsAsUnreadBulk","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[1,2,3]}},"type":"object"}}}},"responses":{"200":{"description":"Notifications marked as unread","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Notifications marked as unread."},"data":{"properties":{"count":{"type":"integer","example":3}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation Error","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/read-all":{"put":{"tags":["Company Notification"],"summary":"Mark all notifications as read","description":"Marks all notifications for the authenticated company user as read.","operationId":"markAllNotificationsAsRead","responses":{"200":{"description":"All notifications marked as read","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"All notifications marked as read."}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/company\/notifications\/{id}":{"get":{"tags":["Company Notification"],"summary":"Get notification detail","description":"Returns the detail of a specific notification by ID. The notification must belong to the authenticated company user's company\/branch.","operationId":"getNotificationDetail","parameters":[{"name":"id","in":"path","description":"Notification ID","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Notification detail retrieved successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Notification detail retrieved successfully."},"data":{"$ref":"#\/components\/schemas\/NotificationItem"}},"type":"object"}}}},"400":{"description":"Notification not found or does not belong to the company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Notification not found."},"error":{"properties":{"key":{"type":"string","example":"notification.not_found"},"content":{"type":"string","example":"Notification not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated"}},"security":[{"bearerAuth":[]}]}},"\/company\/dashboard":{"get":{"tags":["Company Dashboard"],"summary":"Company dashboard summary","description":"Returns count metrics for published jobs, pending applicants (\u5fdc\u52df\u4e2d), today's work shifts, pending cancel requests, weighted branch rating average, and registered branches.","operationId":"30e970baa7ee179858ae6f2fcdba1275","responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Dashboard fetched successfully."},"data":{"properties":{"published_jobs_count":{"type":"integer","example":3},"applying_workers_count":{"description":"Job applications with status pending (\u5fdc\u52df\u4e2d\u306e\u30ef\u30fc\u30ab\u30fc)","type":"integer","example":8},"today_workings_count":{"type":"integer","example":5},"cancellations_count":{"type":"integer","example":2},"branch_rating_average":{"type":"number","format":"float","example":4.5,"nullable":true},"registered_branches_count":{"type":"integer","example":4}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]}},"\/company\/documents\/terms-of-use":{"get":{"tags":["Company Documents"],"summary":"Get terms-of-use PDF URL","description":"Get terms-of-use PDF URL.","operationId":"c209b9c31287087ef0a699b5672d9394","responses":{"200":{"description":"Presigned URL","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"url":{"type":"string","example":"https:\/\/example.com\/presigned-url"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/documents\/privacy-policy":{"get":{"tags":["Company Documents"],"summary":"Get privacy-policy PDF URL","description":"Get privacy-policy PDF URL.","operationId":"e65740e331b03615d476627d9655b30e","responses":{"200":{"description":"Presigned URL","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"url":{"type":"string","example":"https:\/\/example.com\/presigned-url"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/documents\/usage-guide":{"get":{"tags":["Company Documents"],"summary":"Get usage-guide PDF URL","description":"Get usage-guide PDF URL.","operationId":"35939a6e2f3b9218b2e545d0336e5c5f","responses":{"200":{"description":"Presigned URL","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"url":{"type":"string","example":"https:\/\/example.com\/presigned-url"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/google-maps\/api-key":{"get":{"tags":["Company Google Maps"],"summary":"Get Google Maps API key","operationId":"companyGoogleMapsApiKey","responses":{"200":{"description":"Google Maps API key fetched","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Google Maps API key fetched successfully."},"data":{"properties":{"api_key":{"type":"string","example":"AIzaSyD-EXAMPLE"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job\/applies\/calendar":{"get":{"tags":["Company Job Apply"],"summary":"Job apply calendar by month (company)","description":"Monthly job apply calendar grouped by working date.","operationId":"833eb265966ad3fb5566267f0ee302ee","parameters":[{"name":"year_month","in":"query","description":"Filter by job working month (`t_jobs.start_working_date`, format YYYY-MM).","required":true,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-04"}},{"name":"company_branch_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"status[]","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"category_ids[]","in":"query","description":"Filter by job category IDs (`t_job_categories`). Jobs matching any of the given category IDs are returned.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"search_key","in":"query","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Monthly calendar with jobs grouped by working date.","content":{"application\/json":{"schema":{"properties":{"daily_jobs":{"type":"array","items":{"properties":{"working_date":{"type":"string","format":"date","example":"2026-04-05"},"job_count":{"type":"integer","example":2},"jobs":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string"},"start_working_time":{"type":"string","example":"09:00:00"},"end_working_time":{"type":"string","example":"15:00:00"},"total_user":{"type":"integer","example":5},"approved_count":{"description":"Count of approved applies for the job (`t_job_applies.status = approved`), ignoring request `status` and `search_key` filters.","type":"integer","example":2},"company_branch":{"type":"object"},"categories":{"type":"array","items":{"type":"object"}},"applied_users":{"type":"array","items":{"properties":{"apply_id":{"type":"integer"},"apply_status":{"type":"string"},"user_id":{"type":"integer"},"name":{"type":"string","nullable":true},"katakana_name":{"type":"string","nullable":true},"certificates":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"categories":{"description":"Only categories that overlap with the job's categories.","type":"array","items":{"type":"object"}}},"type":"object"}}},"type":"object"}}},"type":"object"}}},"type":"object"}}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job\/applies":{"get":{"tags":["Company Job Apply"],"summary":"List job applications (company)","description":"List job applications for the authenticated company (optionally one job).","operationId":"b59544246161d23875748e310f44296d","parameters":[{"name":"job_id","in":"query","description":"Optional: limit to applications for this job id","required":false,"schema":{"type":"integer","minimum":1}},{"name":"company_branch_id","in":"query","description":"Optional: limit to applications whose job belongs to this company branch. Must belong to the authenticated company, otherwise 422.","required":false,"schema":{"type":"integer"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1}},{"name":"status[]","in":"query","description":"Filter by application status. Pass multiple values as status[]=pending&status[]=approved. Allowed: pending, approved, rejected, cancelled, cancel_requested, approve_cancelled, user_cancelled.","required":false,"schema":{"type":"array","items":{"type":"string","enum":["pending","approved","rejected","cancelled","cancel_requested","approve_cancelled","user_cancelled"]}}},{"name":"year_month","in":"query","description":"Year-month filter in format YYYY-MM (filters by `t_jobs.start_working_date`).","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-04"}},{"name":"search_key","in":"query","description":"Free-text search (job name, branch name, applicant profile name).","required":false,"schema":{"type":"string","maxLength":255}},{"name":"order_by","in":"query","description":"Sort field (requires order_direction)","required":false,"schema":{"type":"string","example":"id"}},{"name":"order_direction","in":"query","description":"Sort direction (requires order_by)","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list: each row has `user` (t_users) and `company_branch` only \u2014 no full job object.","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"description":"t_job_applies.id","type":"integer"},"job_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"type":"string","enum":["pending","approved","rejected","cancelled","cancel_requested","approve_cancelled","user_cancelled"]},"user":{"description":"Worker user (t_users)","properties":{"id":{"description":"t_users.id","type":"integer"},"name":{"type":"string","nullable":true},"katakana_name":{"type":"string","nullable":true},"phone_number":{"type":"string","nullable":true},"avatar_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"categories":{"type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"workplace_experiences":{"type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"sub_category_details":{"type":"array","items":{"type":"object"}},"certificates":{"type":"array","items":{"type":"object"}},"experience_year":{"type":"object","nullable":true}},"type":"object"},"company_branch":{"description":"Applicant profile (t_user_profiles)","type":"object","nullable":true},"job":{"description":"Job summary with category, companyBranch, prefecture, thumbnailFile","type":"object","nullable":true}},"type":"object"}},"total":{"type":"integer"},"last_page":{"type":"integer"},"current_page":{"type":"integer"},"company_id":{"type":"integer"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g., invalid status value, company_branch_id not owned by the authenticated company, invalid order_by, etc.)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job\/applies\/{id}":{"get":{"tags":["Company Job Apply"],"summary":"Get a job application by ID","description":"Get a job application by ID (must belong to the authenticated company).","operationId":"f86be8af30a80584f061490ca7b67877","parameters":[{"name":"id","in":"path","description":"The ID of the job application","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Job application detail (includes applicant profile, user certificates, bank account, job with branch\/prefecture\/media, and status change history).","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Application detail fetched successfully."},"data":{"properties":{"id":{"type":"integer"},"job_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"type":"string"},"user_profile":{"type":"object","nullable":true},"job":{"type":"object","nullable":true},"status_histories":{"description":"Status change history ordered by creation time.","type":"array","items":{"properties":{"id":{"type":"integer"},"job_apply_id":{"type":"integer"},"status":{"type":"string","enum":["approved","rejected","cancelled","cancel_requested","approve_cancelled","user_cancelled"]},"note":{"type":"string","nullable":true},"changed_by":{"description":"t_company_users.id","type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"Application not found (either does not exist, soft-deleted, or its job belongs to another company).","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Application not found."},"error":{"properties":{"key":{"type":"string","example":"job_apply.not_found"},"content":{"type":"string","example":"Application not found."}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job\/applies\/{id}\/cancel":{"put":{"tags":["Company Job Apply"],"summary":"Approve or reject a user cancellation request","description":"Resolve a user-submitted cancellation request.\n- `action=approved` \u2192 cancel_requested \u2192 approve_cancelled (reopens job if slot available)\n- `action=rejected` \u2192 cancel_requested \u2192 approved (application restored)","operationId":"565871f9f085130eff6ff659f666c4e2","parameters":[{"name":"id","in":"path","description":"t_job_applies.id of the application","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["action","note"],"properties":{"action":{"description":"`approved` \u2192 approve_cancelled; `rejected` \u2192 approved","type":"string","enum":["approved","rejected"],"example":"approved"},"note":{"description":"Mandatory note recorded in status history.","type":"string","maxLength":2000}},"type":"object"}}}},"responses":{"200":{"description":"Cancel request resolved. Message and resulting status depend on action.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"description":"'Cancellation request approved.' for action=approved; 'Cancellation request rejected.' for action=rejected.","type":"string"},"data":{"properties":{"id":{"type":"integer"},"job_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"description":"'approve_cancelled' after action=approved; 'approved' after action=rejected.","type":"string","enum":["approve_cancelled","approved"]}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (missing or invalid action).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}},"400":{"description":"Business rule error. Possible `error.key` values:\n     *       - `job_apply.not_found` \u2014 application not found or soft-deleted\n     *       - `job_apply.forbidden` \u2014 job belongs to another company\n     *       - `job_apply.cannot_cancel` \u2014 application is not in `cancel_requested` status (action=approved)\n     *       - `job_apply.cannot_reject_cancel` \u2014 application is not in `cancel_requested` status (action=rejected)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string"},"error":{"properties":{"key":{"type":"string","example":"job_apply.cannot_cancel"},"content":{"type":"string"}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job\/applies\/{id}\/status":{"put":{"tags":["Company Job Apply"],"summary":"Update status or note of a job application","description":"Update status or note of a job application.\n- With `status`: change application status (approved\/rejected\/cancelled).\n- Without `status`: update note only. `note` is required in both cases.","operationId":"f0f01a1d5ca83527cd4a43d166920255","parameters":[{"name":"id","in":"path","description":"t_job_applies.id of the application","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["note"],"properties":{"status":{"description":"Omit or pass null to only update the note without changing status.","type":"string","enum":["approved","rejected","cancelled"],"example":"approved","nullable":true},"note":{"type":"string","maxLength":2000,"example":"Confirmed via phone."},"severance_type":{"description":"Required when status=cancelled and the application is approved. 1=with severance, 2=no severance (force majeure), 3=no severance (worker fault).","type":"integer","enum":[1,2,3],"example":1,"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Status changed or note updated. Returns the refreshed job application record.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Application approved successfully."},"data":{"properties":{"id":{"type":"integer"},"job_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"type":"string","enum":["pending","approved","rejected","cancelled","cancel_requested","approve_cancelled","user_cancelled"]}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g. missing note, invalid status value).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}},"400":{"description":"Business rule error. Possible `error.key` values:\n     *       - `job_apply.not_found` (application missing \/ soft-deleted)\n     *       - `job_apply.forbidden` (job belongs to another company)\n     *       - `job_apply.job_not_found` \/ `job_apply.job_not_open` \/ `job_apply.apply_deadline_passed`\n     *       - `job_apply.user_not_found` \/ `job_apply.forbidden_role` \/ `job_apply.user_not_active` \/ `job_apply.kyc_not_approved`\n     *       - `bank_account.not_found`\n     *       - `job_apply.job_full` (capacity reached; only for approved)\n     *       - `job_apply.already_approved` \/ `job_apply.already_rejected` \/ `job_apply.already_cancelled`\n     *       - `job_apply.time_overlap` (overlapping apply; only for approved)\n     *       - `job_apply.already_cancelled` (cancel requires status=approved)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string"},"error":{"properties":{"key":{"type":"string","example":"job_apply.already_approved"},"content":{"type":"string","example":"This application has already been approved."}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/jobs":{"get":{"tags":["Company Job"],"summary":"List jobs (company)","description":"List job postings for the authenticated company.","operationId":"baf2c9d3ef5722833003737f3c9f2f83","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"status[]","in":"query","description":"Filter by status (repeatable array). Allowed: un_published, published, paused, expired, cancelled, completed","required":false,"schema":{"type":"array","items":{"type":"string","enum":["un_published","published","paused","expired","cancelled","completed"]},"example":["published"]}},{"name":"order_by","in":"query","description":"Sort field. Allowed: id, start_working_date, created_at","required":false,"schema":{"type":"string","enum":["id","start_working_date","created_at"]}},{"name":"order_direction","in":"query","description":"Sort direction (used with order_by)","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"search_key","in":"query","required":false,"schema":{"type":"string","maxLength":255}},{"name":"prefecture_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"company_branch_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"start_working_date","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"end_working_date","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Paginated job list. Bare paginator shape from AppBaseController::pagination() (no success\/message wrapper).","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"company_branch_id":{"type":"integer"},"total_user":{"type":"integer"},"status":{"type":"string"},"favorite_count":{"description":"Number of users who favorited this job","type":"integer","example":2},"company_branch":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"company_id":{"type":"integer"}},"type":"object","nullable":true}},"type":"object"}},"total":{"type":"integer","example":100},"last_page":{"type":"integer","example":5},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Company Job"],"summary":"Create job","description":"Accepts JSON or multipart\/form-data (file: thumbnail). Thumbnail: jpeg, jpg, png, gif, webp, heic, heif; max 5 MB. Server runs schedule + payroll calculations and may return 400 with a specific business-rule error key.","operationId":"7e4e9970048647b7261584747af98b4d","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["name","company_branch_id","hourly_salary","transport_expenses","total_user","travel_method_ids","category_id","description","note","appearance_option_ids"],"properties":{"name":{"type":"string"},"company_branch_id":{"description":"t_company_branches.id for this company (required). Job prefecture_id and district_id are derived from the branch.","type":"integer","example":1},"condition_ids":{"description":"m_job_conditions ids (t_job_conditions)","type":"array","items":{"type":"integer"},"nullable":true},"latitude":{"description":"Map latitude (-90..90)","type":"number","format":"float","example":35.681236,"nullable":true},"longitude":{"description":"Map longitude (-180..180)","type":"number","format":"float","example":139.767125,"nullable":true},"is_repeat":{"description":"When true, root schedule creates the first row, and repeat_jobs[] creates additional rows.","type":"boolean","nullable":true},"repeat_jobs":{"description":"Required when is_repeat=true. Each item defines one job row (working window, optional break, apply deadline). Max 31 items.","type":"array","items":{"required":["start_working_date","start_working_time","end_working_time","end_apply_date","end_apply_time"],"properties":{"start_working_date":{"type":"string","format":"date","example":"2026-04-01"},"start_working_time":{"type":"string","example":"09:00"},"end_working_time":{"type":"string","example":"18:00"},"start_break_time":{"type":"string","example":"12:00","nullable":true},"end_break_time":{"type":"string","example":"13:00","nullable":true},"end_apply_date":{"type":"string","format":"date","example":"2026-03-31"},"end_apply_time":{"type":"string","example":"08:00"}},"type":"object"},"nullable":true},"start_working_date":{"type":"string","format":"date","example":"2026-04-01"},"start_working_time":{"type":"string","example":"09:00"},"end_working_time":{"type":"string","example":"18:00"},"start_break_time":{"type":"string","example":"12:00","nullable":true},"end_break_time":{"type":"string","example":"13:00","nullable":true},"end_apply_date":{"type":"string","format":"date","nullable":true},"end_apply_time":{"type":"string","example":"08:00"},"hourly_salary":{"type":"number","format":"float"},"transport_expenses":{"description":"Transport expense amount in yen (0\u20133000)","type":"number","format":"float"},"total_user":{"type":"integer","example":2},"certificate_ids":{"description":"Optional FK ids from m_certificates (t_job_certificates)","type":"array","items":{"type":"integer"},"nullable":true},"travel_method_ids":{"type":"array","items":{"type":"integer"}},"category_id":{"description":"Single category ID assigned to the selected branch (t_company_branch_category). Stored in t_job_categories.","type":"integer"},"skill_ids":{"description":"FK ids from m_skills (t_job_skills)","type":"array","items":{"type":"integer"},"nullable":true},"workplace_ids":{"description":"FK ids from m_workplaces (t_job_workplaces)","type":"array","items":{"type":"integer"},"nullable":true},"service_type_job_ids":{"description":"FK ids from m_service_type_job (t_job_service_type_jobs)","type":"array","items":{"type":"integer"},"nullable":true},"description":{"type":"string"},"note":{"type":"string"},"appearance_option_ids":{"description":"Leaf `m_appearance_items.id` values (clothing, hair, nails). Multiple options per section allowed.","type":"array","items":{"type":"integer","example":1}},"belongings":{"description":"Things to bring (\u6301\u3061\u7269), legacy field name","type":"string","nullable":true},"facility_types":{"description":"\u65bd\u8a2d\u5f62\u614b (checkbox)","type":"array","items":{"type":"string","enum":["medical_care","childcare_education"]},"nullable":true},"special_conditions":{"description":"\u3053\u3060\u308f\u308a\u6761\u4ef6 (checkbox)","type":"array","items":{"type":"string","enum":["spot_ok","near_station","parking","bicycle_parking"]},"nullable":true},"thumbnail":{"description":"Job thumbnail (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job created successfully."},"data":{"oneOf":[{"description":"Single job object (is_repeat=false)","type":"object"},{"description":"Repeat create result (is_repeat=true)","properties":{"repeat_id":{"type":"string","example":"uuid"},"jobs":{"type":"array","items":{"type":"object"}}},"type":"object"}]}},"type":"object"}}}},"400":{"description":"Business rule error. Possible `error.key` values: `job.minimum_working_time`, `job.maximum_working_time`, `job.working_time_past`, `job.apply_time_past`, `job.apply_before_working_required`, `job.break_time_outside_shift`, `job.break_time_min_60`, `job.break_time_min_45`.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Working time must be at least 1 hour."},"error":{"properties":{"key":{"type":"string","example":"job.minimum_working_time"},"content":{"type":"string","example":"Working time must be at least 1 hour."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/jobs\/{id}":{"get":{"tags":["Company Job"],"summary":"Get job detail (company)","description":"Get job detail by id for the authenticated company.","operationId":"c287e10693c92d4a3cd962c1b9422323","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job detail fetched successfully."},"data":{"type":"object"}},"type":"object"}}}},"400":{"description":"Job not found (soft-delete race) or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Job not found."},"error":{"properties":{"key":{"type":"string","example":"job.not_found"},"content":{"type":"string","example":"Job not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Id validation failed (non-existent t_jobs.id)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Job"],"summary":"Update job","description":"JSON or multipart\/form-data. Only fields sent are updated. When schedule fields change, server re-runs working-time calculation and payroll math. Bracket of possible business-rule errors is the same as create.","operationId":"438a6a73f7bc46e31b64827344a18743","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"description":"JSON or multipart\/form-data (file: thumbnail). Thumbnail: jpeg, jpg, png, gif, webp, heic, heif; max 5 MB. transport_expenses is always required.","required":true,"content":{"application\/json":{"schema":{"required":["transport_expenses"],"properties":{"name":{"type":"string","nullable":true},"company_branch_id":{"description":"Required by validation; may be omitted if unchanged (merged from existing job). When changed, job prefecture_id and district_id are synced from the branch.","type":"integer","example":1,"nullable":true},"condition_ids":{"description":"m_job_conditions ids \u2014 replaces all existing conditions when sent","type":"array","items":{"type":"integer"},"nullable":true},"latitude":{"description":"Map latitude (-90..90)","type":"number","format":"float","example":35.681236,"nullable":true},"longitude":{"description":"Map longitude (-180..180)","type":"number","format":"float","example":139.767125,"nullable":true},"is_repeat":{"description":"When true, repeat_jobs[] appends new rows to the repeat group (existing repeat rows are not modified).","type":"boolean","nullable":true},"repeat_jobs":{"description":"Required when is_repeat=true. Each item appends one new job row. Overlap rules match create (adjacent windows on the same day are allowed).","type":"array","items":{"required":["start_working_date","start_working_time","end_working_time","end_apply_date","end_apply_time"],"properties":{"start_working_date":{"type":"string","format":"date","example":"2026-04-01"},"start_working_time":{"type":"string","example":"09:00"},"end_working_time":{"type":"string","example":"18:00"},"start_break_time":{"type":"string","example":"12:00","nullable":true},"end_break_time":{"type":"string","example":"13:00","nullable":true},"end_apply_date":{"type":"string","format":"date","example":"2026-03-31"},"end_apply_time":{"type":"string","example":"08:00"}},"type":"object"},"nullable":true},"start_working_date":{"type":"string","format":"date","nullable":true},"start_working_time":{"type":"string","example":"09:00","nullable":true},"end_working_time":{"type":"string","example":"18:00","nullable":true},"start_break_time":{"type":"string","example":"12:00","nullable":true},"end_break_time":{"type":"string","example":"13:00","nullable":true},"end_apply_date":{"type":"string","format":"date","nullable":true},"end_apply_time":{"type":"string","example":"08:00","nullable":true},"hourly_salary":{"type":"number","format":"float","nullable":true},"transport_expenses":{"description":"Transport expense amount in yen (0\u20133000)","type":"number","format":"float"},"total_user":{"type":"integer","nullable":true},"certificate_ids":{"description":"m_certificates ids (t_job_certificates) \u2014 replaces all existing when sent","type":"array","items":{"type":"integer"},"nullable":true},"travel_method_ids":{"type":"array","items":{"type":"integer"},"nullable":true},"category_id":{"description":"Single category ID assigned to the job branch (t_company_branch_category). Stored in t_job_categories \u2014 replaces the existing category when sent","type":"integer"},"skill_ids":{"description":"m_skills ids (t_job_skills) \u2014 replaces all existing when sent","type":"array","items":{"type":"integer"},"nullable":true},"workplace_ids":{"description":"m_workplaces ids (t_job_workplaces) \u2014 replaces all existing when sent","type":"array","items":{"type":"integer"},"nullable":true},"service_type_job_ids":{"description":"m_service_type_job ids (t_job_service_type_jobs) \u2014 replaces all existing when sent","type":"array","items":{"type":"integer"},"nullable":true},"description":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"appearance_option_ids":{"type":"array","items":{"type":"integer"}},"belongings":{"type":"string","nullable":true},"facility_types":{"description":"\u65bd\u8a2d\u5f62\u614b (checkbox)","type":"array","items":{"type":"string","enum":["medical_care","childcare_education"]},"nullable":true},"special_conditions":{"description":"\u3053\u3060\u308f\u308a\u6761\u4ef6 (checkbox)","type":"array","items":{"type":"string","enum":["spot_ok","near_station","parking","bicycle_parking"]},"nullable":true},"thumbnail":{"description":"Job thumbnail (jpeg, jpg, png, gif, webp, heic, heif; max 5 MB). Multipart only.","type":"string","format":"binary","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Updated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job updated successfully."},"data":{"oneOf":[{"description":"Single job object (is_repeat=false or omitted)","type":"object"},{"description":"Repeat append result (is_repeat=true)","properties":{"repeat_id":{"type":"string","example":"uuid"},"jobs":{"type":"array","items":{"type":"object"}}},"type":"object"}]}},"type":"object"}}}},"400":{"description":"Job not found (soft-delete race) or does not belong to the authenticated company, or business rule error. Additional `error.key` values: `job.not_modifiable` (expired\/cancelled\/completed), `job.has_applies` (published\/paused with applicants), `job.has_non_cancelled_workings` (attendance rows not in `cancel` status).","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Job not found."},"error":{"properties":{"key":{"type":"string","example":"job.not_found"},"content":{"type":"string","example":"Job not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (includes non-existent id, company_branch_id not owned by company, etc.)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Company Job"],"summary":"Delete a job","description":"Delete a job. Only allowed if no one has applied.","operationId":"959e3577ad1ca5e1aa4161c8b58e33a2","parameters":[{"name":"id","in":"path","description":"t_jobs.id \u2014 must belong to the authenticated company","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Job deleted successfully.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job deleted successfully."},"data":{"example":null,"nullable":true}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"Business rule error. Possible `error.key` values:\n     *       - `job.not_found` (job does not exist or belongs to another company)\n     *       - `job.has_applies` (published\/paused job already has applicants)\n     *       - `job.not_deletable` (expired, cancelled, or completed job)\n     *       - `job.has_non_cancelled_workings` (job has attendance rows not in `cancel` status)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string"},"error":{"properties":{"key":{"type":"string","example":"job.has_applies"},"content":{"type":"string","example":"Cannot delete a job that already has applicants."}},"type":"object"}},"type":"object"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/jobs\/{id}\/contract-pdf":{"get":{"tags":["Company Job"],"summary":"Export job contract PDF","description":"Export a job contract PDF.","operationId":"86d88bc93b658bb92eee68649a57db40","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"PDF file download","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Job not found or does not belong to the authenticated company","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Job not found."},"error":{"properties":{"key":{"type":"string","example":"job.not_found"},"content":{"type":"string","example":"Job not found."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Id validation failed (non-existent t_jobs.id)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/jobs\/{id}\/status":{"put":{"tags":["Company Job"],"summary":"Update job status","description":"Transition a job to a new status. Only the transitions listed above are permitted. Terminal statuses (expired, cancelled, completed) have no outgoing transitions.","operationId":"0e36d12540a60bdd6dfe49f6a8e7f24e","parameters":[{"name":"id","in":"path","description":"t_jobs.id \u2014 must belong to the authenticated company","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["status"],"properties":{"status":{"description":"Target status. Must be a valid transition from the job's current status.","type":"string","enum":["un_published","published","paused","expired","cancelled"],"example":"published"}},"type":"object"}}}},"responses":{"200":{"description":"Job status updated successfully.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Job status updated successfully."},"data":{"description":"Updated job object","type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"Business rule error. Possible `error.key` values:\n     *       - `job.not_found` (job does not exist or belongs to another company)\n     *       - `job.invalid_status_transition` (the requested transition is not allowed from the current status)","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"This status transition is not allowed."},"error":{"properties":{"key":{"type":"string","example":"job.invalid_status_transition"},"content":{"type":"string","example":"This status transition is not allowed."}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation error (status value is not one of the allowed enum values)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job-working-requests":{"get":{"tags":["Company Job Working Request"],"summary":"List timekeeping change requests","description":"Paginated rows from `t_job_working_requests` for the authenticated company. Company admins see all branches; branch users only see assigned branches.","operationId":"companyListJobWorkingRequests","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","approved","rejected"]}},{"name":"company_branch_id","in":"query","description":"Filter by branch. Branch users may only request branches they are assigned to.","required":false,"schema":{"type":"integer"}},{"name":"job_working_id","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"job_id","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"year_month","in":"query","description":"Filter by calendar month (`YYYY-MM`, e.g. `2026-06`).","required":false,"schema":{"type":"string","example":"2026-06"}},{"name":"search_key","in":"query","description":"Partial match on job name or worker name \/ katakana_name.","required":false,"schema":{"type":"string","maxLength":255}},{"name":"order_by","in":"query","description":"Sort field (requires order_direction). Default: created_at desc.","required":false,"schema":{"type":"string","enum":["id","working_date","created_at"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list of change requests","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"type":"object"}},"total":{"type":"integer","example":3},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"400":{"description":"Forbidden branch filter for branch user"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job-working-requests\/{id}":{"get":{"tags":["Company Job Working Request"],"summary":"Get timekeeping change request detail","description":"Returns one `t_job_working_requests` row for the authenticated company, including nested `job_working` with the same relations as `GET \/company\/timekeepings\/{id}`.","operationId":"companyShowJobWorkingRequest","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Change request detail with nested job_working and job_apply","content":{"application\/json":{"schema":{"properties":{"data":{"properties":{"job_apply":{"properties":{"id":{"type":"integer","example":10},"date":{"description":"Application working date (`start_working_date`), or apply date (`created_at`) when unset","type":"string","format":"date","example":"2026-06-01","nullable":true},"status":{"type":"string","example":"approved"}},"type":"object","nullable":true},"user":{"properties":{"id":{"type":"integer","example":5},"name":{"type":"string","example":"Worker One"},"late_cancel_rate_within_1h":{"description":"Percentage of late cancellations within 1 hour before shift start.","type":"number","format":"float","example":12.34},"rating_avg":{"description":"Worker average review score (0\u20135) from `t_user_review_summaries.total_avg`","type":"number","format":"float","example":4.12},"rating_count":{"description":"Total worker reviews from `t_user_review_summaries.total_reviews`","type":"integer","example":18}},"type":"object","nullable":true},"job":{"properties":{"id":{"type":"integer","example":12},"name":{"type":"string","example":"Morning shift"},"categories":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"}},"type":"object"}}},"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"400":{"description":"Forbidden branch access or shift not found"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/job-working-requests\/{id}\/status":{"put":{"tags":["Company Job Working Request"],"summary":"Approve or reject timekeeping change request","description":"Updates `t_job_working_requests.status` to `approved` or `rejected`. On approve or reject, `t_job_workings.status` becomes `company_confirmed` when check-out times are present (leaves `request_change`). On approve, shift metrics are applied, wallets \/ transaction logs are adjusted to the approved amounts, and a `before_*` row is stored in `t_job_working_histories` (`note` optional). On reject, the `before_*` snapshot is restored without wallet changes (`note` required). Use `approval_scope` for check-in (`checkin`), check-out (`checkout`), or both (`both`, default). Only `pending` requests may be updated.","operationId":"companyUpdateJobWorkingRequestStatus","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["status"],"properties":{"status":{"type":"string","enum":["approved","rejected"]},"approval_scope":{"description":"Only when status=approved. Default `both` (accept requested check-in and check-out).","type":"string","enum":["checkin","checkout","both"]},"note":{"description":"Optional when approved; required when rejected.","type":"string","maxLength":2000}},"type":"object"}}}},"responses":{"200":{"description":"Updated change request row"},"400":{"description":"Business rule error (not pending, branch access, shift not in request_change)"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"404":{"description":"Request not found"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/masters":{"get":{"tags":["Company Master"],"summary":"Get company master data","description":"Get all company-facing master data in a single payload.","operationId":"3faa1a40df838ef6ace148193591273a","responses":{"200":{"description":"Master data payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Get master data successfully."},"data":{"properties":{"travel_methods":{"type":"array","items":{"type":"object"}},"branch_roles":{"type":"array","items":{"type":"object"}},"categories":{"description":"Per-category medical profile master payload (same shape as App)","type":"array","items":{"properties":{"id":{"type":"integer","example":3},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"},"display_order":{"type":"integer","example":3},"license_required":{"type":"boolean","example":true},"experience_years":{"type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"certificates":{"type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"workplace_types":{"type":"array","items":{"type":"object"}}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/masters\/locations":{"get":{"tags":["Company Master"],"summary":"Get location master data (prefectures and districts)","description":"Get prefecture and district master data.","operationId":"a324bd14d6bb739eb61e2d4308fb81c2","responses":{"200":{"description":"Location master data payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Get master data successfully."},"data":{"properties":{"prefectures":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Tokyo"},"short":{"type":"string","example":"TK","nullable":true},"kana":{"type":"string","example":"\u3068\u3046\u304d\u3087\u3046","nullable":true},"en":{"type":"string","example":"Tokyo","nullable":true},"salary":{"description":"Minimum hourly wage (JPY) for this prefecture","type":"number","format":"float","example":1072},"districts":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"prefecture_id":{"type":"integer","example":1},"name":{"type":"string","example":"Chiyoda"}},"type":"object"}}},"type":"object"}},"districts":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"prefecture_id":{"type":"integer","example":1},"name":{"type":"string","example":"Chiyoda"},"prefecture":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Tokyo"},"short":{"type":"string","nullable":true},"kana":{"type":"string","nullable":true},"en":{"type":"string","nullable":true}},"type":"object"}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/profile":{"get":{"tags":["Company Profile"],"summary":"Get profile","description":"Get profile for the authenticated company user.","operationId":"891ba9cdbd9400dd2068ee5a2e9c7391","responses":{"200":{"description":"Company profile","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"The company profile was retrieved successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"user_id":{"type":"integer","example":3},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo Company"},"email":{"type":"string","format":"email","example":"company@example.com"},"phone_number":{"type":"string","example":null,"nullable":true}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Profile"],"summary":"Update company email","description":"Update the authenticated company user's email. On success, the current JWT is\ninvalidated by bumping `token_version` (logout side-effect) \u2014 the client must\nre-login.","operationId":"cec140559218cd6b40110cca6f0e6f62","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["email","email_confirmation","password"],"properties":{"email":{"description":"New email. Must be unique across t_company_profiles, ignoring the authenticated user.","type":"string","format":"email","maxLength":255,"example":"company@example.com"},"email_confirmation":{"description":"Must match email","type":"string","format":"email","maxLength":255,"example":"company@example.com"},"password":{"description":"Current password; required to confirm the change.","type":"string","maxLength":255,"minLength":6,"example":"secret123"}},"type":"object"}}}},"responses":{"200":{"description":"Update successful","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Information updated successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"user_id":{"type":"integer","example":3},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo Company"},"email":{"type":"string","format":"email","example":"company@example.com"},"phone_number":{"type":"string","example":null,"nullable":true}},"type":"object"}},"type":"object"}}}},"400":{"description":"Current password incorrect","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Password incorrect."},"error":{"properties":{"key":{"type":"string","example":"messages.auth.password_incorrect"},"content":{"type":"string","example":"Password incorrect."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (missing field, email_confirmation mismatch, or email already in use)","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/profile\/password":{"put":{"tags":["Company Profile"],"summary":"Update company password","description":"Update the authenticated company user's password. On success, the current JWT is\ninvalidated by bumping `token_version` \u2014 the client must re-login.","operationId":"979011585b805bb5c6071fdbd0430d6e","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["current_password","password","password_confirmation"],"properties":{"current_password":{"type":"string","maxLength":255,"minLength":6,"example":"secret123"},"password":{"type":"string","maxLength":255,"minLength":6,"example":"newSecret123"},"password_confirmation":{"description":"Must match password","type":"string","maxLength":255,"minLength":6,"example":"newSecret123"}},"type":"object"}}}},"responses":{"200":{"description":"Update successful","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Information updated successfully."},"data":{"properties":{"id":{"type":"integer","example":1},"user_id":{"type":"integer","example":3},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Demo Company"},"email":{"type":"string","format":"email","example":"company@example.com"},"phone_number":{"type":"string","example":null,"nullable":true}},"type":"object"}},"type":"object"}}}},"400":{"description":"Current password incorrect","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Password incorrect."},"error":{"properties":{"key":{"type":"string","example":"messages.auth.password_incorrect"},"content":{"type":"string","example":"Password incorrect."}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (missing field, too short, or confirmation mismatch)","content":{"application\/json":{"schema":[]}}}},"security":[{"bearerAuth":[]}]}},"\/company\/regions":{"get":{"tags":["Company Region"],"summary":"List regions for the authenticated company","operationId":"companyListRegions","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["id","name","created_at"],"example":"name"}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"example":"asc"}},{"name":"search_key","in":"query","description":"Partial match on name","required":false,"schema":{"type":"string","maxLength":255}},{"name":"company_branch_id","in":"query","description":"Return only regions linked to this company branch (t_company_region_branches)","required":false,"schema":{"type":"integer","minimum":1,"example":1}}],"responses":{"200":{"description":"Paginated list","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Kanto"},"description":{"type":"string","nullable":true},"branches":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"face_photo_file_id":{"type":"integer","nullable":true},"thumbnail":{"type":"string","format":"uri","nullable":true},"face_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true}},"type":"object"}}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Company Region"],"summary":"Create a region for the authenticated company","operationId":"companyStoreRegion","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["name"],"properties":{"name":{"type":"string","maxLength":255,"example":"Kanto"},"description":{"type":"string","maxLength":2000,"example":"Kanto area","nullable":true},"branch_ids":{"description":"Optional. Company branch ids to assign to this region. Omit or send null to create without branches.","type":"array","items":{"type":"integer","example":1},"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Region created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"id":{"type":"integer"},"company_id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"branches":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"face_photo_file_id":{"type":"integer","nullable":true},"thumbnail":{"type":"string","format":"uri","nullable":true},"face_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/regions\/{id}":{"get":{"tags":["Company Region"],"summary":"Get region detail","operationId":"companyShowRegion","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Region detail with branches","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"id":{"type":"integer"},"company_id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"branches":{"type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"face_photo_file_id":{"type":"integer","nullable":true},"thumbnail":{"type":"string","format":"uri","nullable":true},"face_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not found"}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Company Region"],"summary":"Update a region","operationId":"companyUpdateRegion","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"description":"All fields are optional on update. Omit `branch_ids` to keep current branch assignments; send an empty array to clear all assignments.","required":true,"content":{"application\/json":{"schema":{"properties":{"name":{"type":"string","maxLength":255,"example":"Kanto"},"description":{"type":"string","maxLength":2000,"nullable":true},"branch_ids":{"description":"Optional. Replaces all branch assignments for this region when provided. Send `[]` to detach every branch.","type":"array","items":{"type":"integer","example":1},"example":[1,2],"nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Region updated","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Company Region"],"summary":"Delete a region","operationId":"companyDeleteRegion","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Region deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Not found"}},"security":[{"bearerAuth":[]}]}},"\/company\/source-income-slips":{"get":{"tags":["Company\/SourceIncomeSlip"],"summary":"List workers for source income slip download","description":"Returns paginated workers with report-eligible job workings (`checkout`, `company_confirmed`, `payment`) for the authenticated company in the given calendar year. Each row aggregates all branches for that user (one row per user).","operationId":"ff3fb25d12cac47ef95b4128ea4aaf8c","parameters":[{"name":"year","in":"query","description":"Target calendar year.","required":true,"schema":{"type":"integer","maximum":2100,"minimum":2000,"example":2026}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":15,"maximum":100,"minimum":1}},{"name":"order_by","in":"query","description":"Sort column. user_id maps to t_job_workings.user_id.","required":false,"schema":{"type":"string","enum":["user_id","income_after_tax"]}},{"name":"order_direction","in":"query","description":"Sort direction.","required":false,"schema":{"type":"string","default":"asc","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated worker list.","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"user_id":{"type":"integer","example":10},"user_name":{"type":"string","example":"Test Worker"},"katakana_name":{"type":"string","nullable":true},"avatar_file_id":{"type":"integer","example":123,"nullable":true},"avatar_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"worked_count":{"type":"integer","example":2},"income_before_tax":{"type":"number","format":"float","example":1080000},"income_tax":{"type":"number","format":"float","example":108000},"income_after_tax":{"type":"number","format":"float","example":972000},"transport_expenses":{"type":"number","format":"float","example":12000},"first_working_date":{"type":"string","format":"date","example":"2026-01-15","nullable":true},"last_working_date":{"type":"string","format":"date","example":"2026-12-20","nullable":true}},"type":"object"}},"total":{"type":"integer","example":1},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/source-income-slips\/{userId}\/download":{"get":{"tags":["Company\/SourceIncomeSlip"],"summary":"Download worker withholding tax certificate","description":"Downloads the withholding tax certificate for a worker who has report-eligible job workings (`checkout`, `company_confirmed`, `payment`) for the authenticated company in the given calendar year. Income totals aggregate all branches; no branch_id query filter.","operationId":"fa48aac60ac0c0679d39c879e0ddeac3","parameters":[{"name":"userId","in":"path","description":"App user id from the list endpoint.","required":true,"schema":{"type":"integer","minimum":1}},{"name":"year","in":"query","description":"Target calendar year.","required":true,"schema":{"type":"integer","maximum":2100,"minimum":2000,"example":2026}}],"responses":{"200":{"description":"File download. PDF when conversion succeeds, XLSX fallback otherwise.","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}},"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Target worker not found for the authenticated company\/year"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/timekeepings":{"get":{"tags":["Company Timekeeping"],"summary":"List timekeeping records (company)","operationId":"2120ad066ec12a21e6b491106ea17dcd","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1}},{"name":"search_key","in":"query","description":"Partial match on job name, worker name (t_user_profiles.name), or worker katakana_name.","required":false,"schema":{"type":"string","maxLength":255}},{"name":"order_by","in":"query","description":"Sort field (requires order_direction). Default: working_date desc, id desc.","required":false,"schema":{"type":"string","enum":["id","working_date","created_at"]}},{"name":"order_direction","in":"query","description":"Sort direction (requires order_by).","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"user_id","in":"query","description":"Filter by worker user id","required":false,"schema":{"type":"integer","minimum":1}},{"name":"job_id","in":"query","description":"Filter by job id","required":false,"schema":{"type":"integer","minimum":1}},{"name":"company_branch_id","in":"query","description":"Filter by company branch (job's branch). Must belong to the authenticated company \u2014 otherwise 422.","required":false,"schema":{"type":"integer"}},{"name":"status","in":"query","description":"Comma-separated t_job_workings.status values (e.g. `checked_in,checked_out`)","required":false,"schema":{"type":"string"}},{"name":"working_date_from","in":"query","description":"Lower bound for working_date (inclusive, format YYYY-MM-DD).","required":false,"schema":{"type":"string","format":"date"}},{"name":"working_date_to","in":"query","description":"Upper bound for working_date (inclusive, format YYYY-MM-DD). Must be >= working_date_from.","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Paginated list of t_job_workings belonging to the authenticated company.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"description":"t_job_workings.id","type":"integer"},"user_id":{"type":"integer"},"job_id":{"type":"integer"},"company_id":{"type":"integer"},"company_branch_id":{"type":"integer","nullable":true},"working_date":{"type":"string","format":"date","nullable":true},"start_working_time":{"type":"string","nullable":true},"end_working_time":{"type":"string","nullable":true},"status":{"type":"string"},"user":{"properties":{"profile":{"properties":{"name":{"type":"string","nullable":true},"katakana_name":{"type":"string","nullable":true}},"type":"object","nullable":true}},"type":"object","nullable":true},"job_summary":{"properties":{"id":{"type":"integer"},"name":{"type":"string"},"company_branch":{"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"type":"object","nullable":true}},"type":"object","nullable":true}},"type":"object"}},"total":{"type":"integer"},"last_page":{"type":"integer"},"current_page":{"type":"integer"}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g., invalid order_by, company_branch_id not owned by the authenticated company, working_date_to < working_date_from).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/timekeepings\/{id}":{"get":{"tags":["Company Timekeeping"],"summary":"Get timekeeping record by id (company)","operationId":"10ca9d444517fa0c6dcc459cc8b45464","parameters":[{"name":"id","in":"path","description":"t_job_workings.id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Timekeeping record detail.","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Timekeeping record fetched successfully."},"data":{"properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"job_id":{"type":"integer"},"company_id":{"type":"integer"},"status":{"type":"string"},"user":{"type":"object","nullable":true},"job_summary":{"type":"object","nullable":true},"job_apply":{"properties":{"id":{"type":"integer","example":10},"status":{"type":"string","example":"approved"},"start_working_date":{"type":"string","format":"date","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true}},"type":"object","nullable":true},"user_review":{"description":"Company review of the worker for this shift (`t_user_reviews`). Null when salary is not yet confirmed.","properties":{"id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":100},"status":{"type":"string","enum":["not_reviewed","reviewed"]},"punctuality":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"appearance":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"communication":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"work_attitude":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"skill":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"average_score":{"type":"number","format":"float","nullable":true},"comment":{"type":"string","nullable":true},"reviewed_by":{"type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true}},"type":"object","nullable":true},"transaction_logs":{"description":"Withdraw transaction logs for this job working, newest first.","type":"array","items":{"properties":{"id":{"type":"integer"},"job_working_id":{"type":"integer"},"type":{"type":"string","example":"withdraw"},"status":{"type":"string","enum":["processing","success","failed"]},"transaction_id":{"type":"string"},"amount":{"type":"string","example":"3000.00"},"action":{"type":"string","nullable":true}},"type":"object"}}},"type":"object"}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"400":{"description":"Record exists but belongs to another company (tenant isolation).","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Timekeeping record not found."},"error":{"properties":{"key":{"type":"string","example":"timekeeping.not_found"},"content":{"type":"string","example":"Timekeeping record not found."}},"type":"object"}},"type":"object"}}}},"422":{"description":"Validation error (e.g., non-existent id or soft-deleted record).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/transactions\/approve":{"post":{"tags":["Company Transactions"],"summary":"Approve withdraw transactions (bulk)","description":"Sets `company_status` to `approved` on withdraw rows for each `transaction_id` (`t_transaction_logs.transaction_id`). Shift must be `payment`. When both `user_status` and `company_status` are `approved`, `job_working` becomes `done` (same rule as `POST \/api\/user\/withdraw`).","operationId":"companyApproveWithdrawTransactions","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["transaction_ids"],"properties":{"transaction_ids":{"description":"Withdraw transaction IDs (`t_transaction_logs.transaction_id`)","type":"array","items":{"type":"string","format":"uuid","example":"9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"},"example":["9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d","1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"]}},"type":"object"}}}},"responses":{"200":{"description":"Approved","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"data":{"properties":{"total_amount":{"type":"string","example":"15000.00"},"items":{"type":"array","items":{"type":"object"}}},"type":"object"}},"type":"object"}}}},"400":{"description":"Business rule error"},"401":{"description":"Unauthorized"},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-costs":{"get":{"tags":["Company Usage Costs"],"summary":"List branch billing period headers","description":"Returns paginated rollup rows from `t_company_branch_used_cost`. Optional `year_month` (`YYYY-MM`) filter on `start_date`, optional `company_branch_ids[]`. Each row eager-loads `company_branch` (use `company_branch.name` for \u4e8b\u696d\u6240).","operationId":"companyUsageCostsList","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","description":"Requires `order_direction`. Default: `start_date` desc, `id` desc.","required":false,"schema":{"type":"string","enum":["id","start_date","end_date"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"year_month","in":"query","description":"Filter `start_date` by calendar month (`YYYY-MM`).","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}},{"name":"company_branch_ids[]","in":"query","description":"Filter by company branches. Every id must belong to the authenticated company or 422.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}}],"responses":{"200":{"description":"Pagination envelope (`AppBaseController::pagination`).","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"id":{"description":"t_company_branch_used_cost.id","type":"integer"},"company_branch_id":{"type":"integer","nullable":true},"company_branch":{"oneOf":[{"$ref":"#\/components\/schemas\/CompanyBranch"}],"nullable":true,"description":"Eager-loaded when `company_branch_id` is set; otherwise null. Branch name: `name`."},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"total_member":{"type":"integer"},"total_job":{"type":"integer"},"total_job_working":{"type":"integer"},"total_job_working_complete":{"type":"integer"},"status":{"description":"not_sent | not_paid | partial_not_payment | complete_payment","type":"string","example":"not_sent"},"total_user_salary":{"type":"string","example":"0.00"},"total_user_salary_tax_value":{"type":"string","example":"0.00"},"total_user_salary_after_tax":{"type":"string","example":"0.00"},"total_money_payment":{"type":"integer"}},"type":"object"}},"total":{"type":"integer","example":10},"last_page":{"type":"integer","example":1},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g. invalid branch, order pair).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-costs\/export-csv":{"post":{"tags":["Company Usage Costs"],"summary":"Export usage-cost headers CSV","description":"CSV columns: \u8acb\u6c42\u5e74\u6708\u5ea6, \u4e8b\u696d\u6240, \u6c42\u4eba\u6570, \u63a1\u7528\u3057\u305f\u30ef\u30fc\u30ab\u30fc\u6570, \u8acb\u6c42\u7dcf\u984d (`total_money_payment`). Same query params \/ sorting as `GET \/company\/usage-costs`.","operationId":"companyUsageCostsExportCsv","parameters":[{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["id","start_date","end_date"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"company_branch_ids[]","in":"query","description":"Filter by company branches. Every id must belong to the authenticated company.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"year_month","in":"query","description":"Filter `start_date` by calendar month (`YYYY-MM`).","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}}],"responses":{"200":{"description":"CSV file download.","content":{"text\/csv":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g. invalid branch, order pair).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-costs\/export-excel":{"post":{"tags":["Company Usage Costs"],"summary":"Export company issued invoice XLSX","description":"Downloads the `company_issued_invoices.xlsx` invoice for authenticated-company billing rows. Optional `year_month` (`YYYY-MM`) \/ `company_branch_ids[]` filters match list\/export-csv behavior; omitted filters export all matching company rows. Bank fields are populated from `t_company_bank_accounts` for the authenticated company.","operationId":"companyUsageCostsExportExcel","parameters":[{"name":"year_month","in":"query","description":"Filter billing rows by `start_date` month (`YYYY-MM`).","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}},{"name":"company_branch_ids[]","in":"query","description":"Filter by company branches. Every id must belong to the authenticated company.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}}],"responses":{"200":{"description":"XLSX file download.","content":{"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"404":{"description":"Usage cost not found","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (invalid year_month or branch).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-costs\/export-pdf":{"post":{"tags":["Company Usage Costs"],"summary":"Export company issued invoice PDF","description":"Downloads the same company issued invoice as export-excel, converted from the filled XLSX template to PDF. Optional `year_month` (`YYYY-MM`) \/ `company_branch_ids[]`; PDF accepts the same array shape but only one branch id.","operationId":"companyUsageCostsExportPdf","parameters":[{"name":"year_month","in":"query","description":"Filter billing rows by `start_date` month (`YYYY-MM`).","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}},{"name":"company_branch_ids[]","in":"query","description":"Filter by one company branch. Must belong to the authenticated company.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":1}}],"responses":{"200":{"description":"PDF file download.","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"404":{"description":"Usage cost not found","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (invalid year_month or branch).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-details":{"get":{"tags":["Company Usage Details"],"summary":"List usage details (completed job workings)","description":"Returns paginated rows from `t_job_workings` with report-eligible statuses (`checkout`, `company_confirmed`, `payment`). Date filter: `start_date` (`YYYY-MM-DD`, inclusive range through the same calendar day one month later) takes precedence over `year_month` (`YYYY-MM`). Also optional `company_branch_ids[]`, `category_ids[]` \/ legacy `user_category_ids[]` (worker has any selected `m_category` via `t_user_categories`).","operationId":"companyUsageDetailsList","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"order_by","in":"query","description":"Requires `order_direction`. Default: `working_date` desc, `id` desc.","required":false,"schema":{"type":"string","enum":["id","working_date"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"company_branch_ids[]","in":"query","description":"Filter by company branches. Every id must belong to the authenticated company.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"category_ids[]","in":"query","description":"Filter by worker medical profile categories (`m_category.id`).","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"user_category_ids[]","in":"query","description":"Deprecated alias of `category_ids[]`.","required":false,"deprecated":true,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"start_date","in":"query","description":"Filter `working_date` from this date through the same day one month later (inclusive). Overrides `year_month` when both are sent.","required":false,"schema":{"type":"string","format":"date","example":"2026-05-15"}},{"name":"year_month","in":"query","description":"Filter `working_date` to this calendar month (`YYYY-MM`). Ignored when `start_date` is set.","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}}],"responses":{"200":{"description":"Pagination envelope (`AppBaseController::pagination`).","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"description":"`t_job_workings` columns plus billing helper fields such as `company_branch_name`, `payment`, and `total_money`.","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"job_id":{"type":"integer"},"company_branch_id":{"type":"integer","nullable":true},"company_branch_name":{"description":"From `t_company_branches.name` via relation.","type":"string","nullable":true},"user":{"properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"katakana_name":{"type":"string","nullable":true},"avatar_file_id":{"type":"integer","nullable":true},"avatar_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"categories":{"description":"Worker categories (full m_category rows).","type":"array","items":{"type":"object"}},"skills":{"type":"array","items":{"type":"object"}},"workplaces":{"type":"array","items":{"type":"object"}},"workplace_experiences":{"type":"array","items":{"type":"object"}},"sub_categories":{"type":"array","items":{"type":"object"}},"sub_category_details":{"type":"array","items":{"type":"object"}},"certificates":{"type":"array","items":{"type":"object"}},"experience_year":{"type":"object","nullable":true}},"type":"object","nullable":true},"working_date":{"type":"string","format":"date","nullable":true},"income_before_tax":{"type":"number","format":"float","nullable":true}},"type":"object"}},"total":{"type":"integer","example":42},"last_page":{"type":"integer","example":3},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g. invalid branch, order pair).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/usage-details\/export-csv":{"post":{"tags":["Company Usage Details"],"summary":"Export usage details CSV","description":"Exports usage details to CSV with the same query params \/ sorting as `GET \/company\/usage-details`.","operationId":"companyUsageDetailsExportCsv","parameters":[{"name":"order_by","in":"query","required":false,"schema":{"type":"string","enum":["id","working_date"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"company_branch_ids[]","in":"query","description":"Filter by company branches. Every id must belong to the authenticated company.","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"category_ids[]","in":"query","description":"Filter by worker medical profile categories (`m_category.id`).","required":false,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"user_category_ids[]","in":"query","description":"Deprecated alias of `category_ids[]`.","required":false,"deprecated":true,"schema":{"type":"array","items":{"type":"integer","minimum":1}}},{"name":"start_date","in":"query","description":"Filter `working_date` from this date through the same day one month later (inclusive). Overrides `year_month` when both are sent.","required":false,"schema":{"type":"string","format":"date","example":"2026-05-15"}},{"name":"year_month","in":"query","description":"Filter `working_date` to this calendar month (`YYYY-MM`). Ignored when `start_date` is set.","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-05"}}],"responses":{"200":{"description":"CSV file download.","content":{"text\/csv":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthenticated","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error (e.g. invalid branch, order pair).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/user-reviews":{"get":{"tags":["Company User Review"],"summary":"List reviewable job workings","description":"Returns paginated rows from `t_user_reviews` (created when a shift becomes salary-confirmed or paid). Each row matches GET \/user-reviews\/{id} (review fields at root + nested `job_working`; no `review_summary`). Company admins see all branches; branch users only see assigned branches.","operationId":"companyListUserReviews","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"example":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"example":15}},{"name":"review_status","in":"query","description":"Filter by whether a review exists for the shift.","required":false,"schema":{"type":"string","enum":["not_reviewed","reviewed"]}},{"name":"company_branch_id","in":"query","description":"Filter by branch. Branch users may only request branches they are assigned to.","required":false,"schema":{"type":"integer","example":1}},{"name":"working_date_from","in":"query","required":false,"schema":{"type":"string","format":"date","example":"2026-05-01"}},{"name":"working_date_to","in":"query","required":false,"schema":{"type":"string","format":"date","example":"2026-05-31"}},{"name":"search_key","in":"query","description":"Partial match on job name or worker name \/ katakana_name.","required":false,"schema":{"type":"string","maxLength":255}},{"name":"order_by","in":"query","description":"Sort field (requires order_direction). Default: working_date desc.","required":false,"schema":{"type":"string","enum":["id","working_date"]}},{"name":"order_direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated list of reviewable shifts","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/CompanyUserReviewListItem"}},"total":{"type":"integer","example":42},"last_page":{"type":"integer","example":3},"current_page":{"type":"integer","example":1}},"type":"object"}}}},"400":{"description":"Forbidden branch filter for branch user"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Company User Review"],"summary":"Submit worker review","description":"Submits scores for an existing pending `t_user_reviews` row (`status` becomes `reviewed`). Duplicate submit returns 400 (`user_review.already_exists`). Shift must be `payment`. Updates `t_user_review_summaries` for the worker.","operationId":"companyStoreUserReview","requestBody":{"required":true,"content":{"application\/json":{"schema":{"required":["id","punctuality","appearance","communication","work_attitude","skill"],"properties":{"id":{"description":"t_user_reviews.id from the list response","type":"integer","example":1},"punctuality":{"description":"On-time (\u6642\u9593\u53b3\u5b88)","type":"integer","maximum":5,"minimum":1,"example":5},"appearance":{"description":"Appearance (\u8eab\u3060\u3057\u306a\u307f)","type":"integer","maximum":5,"minimum":1,"example":4},"communication":{"description":"Communication (\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3)","type":"integer","maximum":5,"minimum":1,"example":5},"work_attitude":{"description":"Work attitude (\u52e4\u52d9\u614b\u5ea6)","type":"integer","maximum":5,"minimum":1,"example":4},"skill":{"description":"Skill (\u30b9\u30ad\u30eb)","type":"integer","maximum":5,"minimum":1,"example":5},"comment":{"type":"string","maxLength":2000,"example":"Great worker.","nullable":true}},"type":"object"}}}},"responses":{"200":{"description":"Review created","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Worker review submitted successfully."},"data":{"$ref":"#\/components\/schemas\/CompanyUserReview"}},"type":"object"}}}},"400":{"description":"Business error: not eligible, already exists, forbidden, or job working not found"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/user-reviews\/{id}":{"get":{"tags":["Company User Review"],"summary":"Get worker review by id","description":"Returns `job_working` and `t_user_reviews` fields at the root of `data` (scores null while pending). `review_summary` aggregates all submitted reviews for the worker (all companies). Use GET \/company\/user-reviews\/{id}\/recent for recent review history.","operationId":"companyShowUserReview","parameters":[{"name":"id","in":"path","description":"t_user_reviews.id","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Shift and optional review","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Worker review fetched successfully."},"data":{"properties":{"job_working":{"$ref":"#\/components\/schemas\/CompanyUserReviewJobWorkingMeta"},"id":{"description":"t_user_reviews.id","type":"integer","example":1},"job_working_id":{"type":"integer","example":100},"job_id":{"type":"integer","example":20},"user_id":{"type":"integer","example":5},"company_id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":1},"reviewed_by":{"type":"integer","nullable":true},"status":{"type":"string","enum":["not_reviewed","reviewed"]},"punctuality":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"appearance":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"communication":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"work_attitude":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"skill":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"average_score":{"type":"number","format":"float","nullable":true},"comment":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"review_summary":{"description":"Worker aggregate from all companies; null when no submitted reviews","properties":{"punctuality_avg":{"type":"number","format":"float"},"appearance_avg":{"type":"number","format":"float"},"communication_avg":{"type":"number","format":"float"},"work_attitude_avg":{"type":"number","format":"float"},"skill_avg":{"type":"number","format":"float"},"total_avg":{"type":"number","format":"float"},"total_reviews":{"type":"integer"}},"type":"object","nullable":true}},"type":"object"}},"type":"object"}}}},"400":{"description":"Forbidden or review not found"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/user-reviews\/{id}\/recent":{"get":{"tags":["Company User Review"],"summary":"List worker's recent submitted reviews","description":"Returns submitted reviews as a flat list (oldest \u2192 newest) for the worker across all companies. Default `limit` is 1 and server-side max cap is 15.","operationId":"companyUserReviewRecent","parameters":[{"name":"id","in":"path","description":"t_user_reviews.id (used to resolve worker + access)","required":true,"schema":{"type":"integer","example":1}},{"name":"limit","in":"query","description":"Latest N submitted reviews only; omit to use default 1 (server caps at 15)","required":false,"schema":{"type":"integer","default":1,"maximum":15,"minimum":1,"example":15}}],"responses":{"200":{"description":"Recent reviews payload","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Recent worker reviews fetched successfully."},"data":{"$ref":"#\/components\/schemas\/CompanyUserReviewRecent"}},"type":"object"}}}},"400":{"description":"Forbidden or review not found"},"401":{"description":"Unauthorized","content":{"application\/json":{"schema":[]}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UnprocessableEntity"}}}}},"security":[{"bearerAuth":[]}]}},"\/company\/branch\/calendar":{"get":{"tags":["Company Working Time Calendar"],"summary":"Get working time calendar: completed shift minutes for a branch with daily breakdown","operationId":"631a146e11dccce07e8d995a65ac2975","parameters":[{"name":"year_month","in":"query","description":"Filter by month (`t_job_workings.working_date`, format YYYY-MM). Required.","required":true,"schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$","example":"2026-04"}},{"name":"company_branch_id","in":"query","description":"Filter by company branch ID (`t_company_branches.id`). Omit to include all branches accessible to the user.","required":false,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"Successful response","content":{"application\/json":{"schema":{"properties":{"data":{"type":"array","items":{"properties":{"branch_id":{"type":"integer","example":1},"branch_name":{"type":"string","example":"Demo Branch 01"},"total_actual_working_minutes":{"type":"integer","example":360},"completed_shift_count":{"type":"integer","example":3},"apply_count":{"description":"Total job applies for the branch in the month (all statuses).","type":"integer","example":5},"daily_stats":{"type":"array","items":{"properties":{"working_date":{"type":"string","format":"date","example":"2026-04-11"},"total_actual_working_minutes":{"type":"integer","example":300},"completed_shift_count":{"type":"integer","example":2},"apply_count":{"description":"Job applies on this date (all statuses).","type":"integer","example":3}},"type":"object"}}},"type":"object"}}},"type":"object"}}}},"422":{"description":"Validation error"}},"security":[{"bearerAuth":[]}]}},"\/healthcheck":{"get":{"tags":["Healthcheck"],"summary":"App healthcheck (liveness\/readiness)","description":"Returns the status of the application and database connection.","operationId":"36aa242901966c71ee8e9806980157bc","responses":{"200":{"description":"Healthy app","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"status":{"type":"string","example":"ok"},"app":{"type":"string","example":"running"},"database":{"type":"string","example":"connected"}},"type":"object"}},"type":"object"}}}},"500":{"description":"App or database unhealthy","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Internal server error"},"data":{"type":"object","nullable":true}},"type":"object"}}}}}}},"\/worker\/healthcheck":{"get":{"tags":["Healthcheck"],"summary":"Worker healthcheck","description":"Checks whether Supervisor is running and its processes report RUNNING state.","operationId":"b037906f4978567c1c946bd27ff4a5b5","responses":{"200":{"description":"Supervisor healthy","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"status":{"type":"string","example":"ok"},"supervisor":{"type":"string","example":"running"},"details":{"type":"string","nullable":true}},"type":"object"}},"type":"object"}}}},"500":{"description":"Supervisor unhealthy","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Internal server error"},"data":{"type":"object","nullable":true}},"type":"object"}}}}}}},"\/schedule\/healthcheck":{"get":{"tags":["Healthcheck"],"summary":"Schedule healthcheck","description":"Checks whether scheduler\/cron service is running.","operationId":"2b873539c485ea7292ea0e296bd80049","responses":{"200":{"description":"Scheduler healthy","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"properties":{"status":{"type":"string","example":"ok"},"scheduler":{"type":"string","example":"running"},"details":{"type":"string","nullable":true}},"type":"object"}},"type":"object"}}}},"500":{"description":"Scheduler unhealthy","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Internal server error"},"data":{"type":"object","nullable":true}},"type":"object"}}}}}}},"\/test\/log":{"get":{"tags":["Test"],"summary":"Test structured logging (INFO)","description":"Triggers a manual Log::info() with structured context to verify CloudWatch JSON formatting.","operationId":"f2f61a574fb0876990036021b9ea8d50","responses":{"200":{"description":"Log sent successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Log sent successfully"}},"type":"object"}}}}}}},"\/test\/log-error":{"get":{"tags":["Test"],"summary":"Test structured logging (ERROR)","description":"Triggers a manual Log::error() with structured context to verify CloudWatch JSON formatting.","operationId":"0fb6168ad6d18e75c94fef5ddcc5b50e","responses":{"200":{"description":"Log sent successfully","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Log sent successfully"}},"type":"object"}}}}}}},"\/test\/exception\/base":{"get":{"tags":["Test"],"summary":"Test BaseException handling","description":"Throws a BaseException to verify JSON rendering and logging behavior (should NOT show stack trace in production).","operationId":"a07986fd9fcf77891e0f6f1650ac0678","responses":{"400":{"description":"BaseException triggered","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Test BaseException message"},"error":{"properties":{"key":{"type":"string","example":"auth.failed"},"content":{"type":"string","example":"Test BaseException message"}},"type":"object"}},"type":"object"}}}}}}},"\/test\/exception\/generic":{"get":{"tags":["Test"],"summary":"Test generic Exception handling","description":"Throws a generic Exception to verify 500 JSON rendering and logging behavior (should show full stack trace).","operationId":"2d51e5f727e95c4675b6b656381f4392","responses":{"500":{"description":"Internal Server Error","content":{"application\/json":{"schema":{"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Internal server error."}},"type":"object"}}}}}}}},"components":{"schemas":{"AdminSystemFeeExportRequest":{"properties":{"branch_ids":{"type":"array","items":{"type":"integer","example":1}},"year_month":{"type":"string","example":"2026-01"},"order_by":{"type":"string","enum":["branch_id"]},"order_direction":{"type":"string","enum":["asc","desc"]}},"type":"object"},"NotificationItem":{"description":"Single notification object","properties":{"id":{"description":"Single notification object.","type":"integer","example":1},"notification_type":{"type":"string","enum":["job_apply","timekeeping_request","user_cancel","company_job_done","auto_cancel_absent_work"],"example":"job_apply"},"title":{"type":"string","example":"New job application received"},"body":{"type":"string","example":"User Yamada San has applied for Night shift position."},"data":{"description":"Additional metadata (contextual data)","type":"object","example":{"type":"job_apply","target_id":"4821","deep_link":"\/job-applies\/4821"},"nullable":true},"target_id":{"description":"Detail resource ID for navigable notification types","type":"string","example":"4821","nullable":true},"deep_link":{"description":"Company portal relative path for detail navigation","type":"string","example":"\/job-applies\/4821","nullable":true},"detail_hint":{"type":"string","example":"\u8a73\u7d30\u753b\u9762\u306b\u3066\u5185\u5bb9\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002","nullable":true},"action_label":{"type":"string","example":"\u8a73\u7d30\u3092\u78ba\u8a8d\u3059\u308b","nullable":true},"is_read":{"type":"integer","enum":[0,1],"example":0},"read_at":{"type":"string","format":"date-time","example":null,"nullable":true},"created_at":{"type":"string","format":"date-time"}},"type":"object"},"NotificationList":{"description":"Paginated notification list response","properties":{"current_page":{"description":"Paginated notification list response.","type":"integer","example":1},"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/NotificationItem"}},"first_page_url":{"type":"string"},"from":{"type":"integer","example":1},"last_page":{"type":"integer","example":5},"last_page_url":{"type":"string"},"links":{"type":"array","items":{"type":"object"}},"next_page_url":{"type":"string","nullable":true},"path":{"type":"string"},"per_page":{"type":"integer","example":15},"prev_page_url":{"type":"string","nullable":true},"to":{"type":"integer","example":15},"total":{"type":"integer","example":50}},"type":"object"},"CompanyUserReviewJobWorkingMeta":{"description":"Nested `job_working` on list\/detail user-review responses","properties":{"id":{"description":"t_user_reviews.id","type":"integer","example":1},"job_working_id":{"type":"integer","example":100},"review_status":{"type":"string","enum":["not_reviewed","reviewed"],"example":"not_reviewed"},"average_score":{"description":"Null when not_reviewed","type":"number","format":"float","example":4.5,"nullable":true},"working_date":{"type":"string","format":"date","example":"2026-05-31","nullable":true},"status":{"description":"t_job_workings.status","type":"string","example":"payment"},"completed_at":{"type":"string","format":"date-time","nullable":true},"start_working_time":{"type":"string","example":"2026-05-31 09:00:00","nullable":true},"end_working_time":{"type":"string","example":"2026-05-31 18:00:00","nullable":true},"job_apply":{"properties":{"id":{"type":"integer","example":10},"status":{"type":"string","example":"approved"},"created_at":{"type":"string","format":"date-time","nullable":true}},"type":"object","nullable":true},"user":{"properties":{"id":{"type":"integer","example":5},"name":{"type":"string","example":"Yamada Taro"},"katakana_name":{"type":"string","nullable":true},"avatar_file_id":{"type":"integer","nullable":true},"avatar_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"late_cancel_rate_within_1h":{"description":"Percentage of late cancellations within 1 hour before shift start.","type":"number","format":"float","example":12.34}},"type":"object","nullable":true},"job":{"properties":{"id":{"type":"integer","example":20},"name":{"type":"string","example":"Night shift"},"start_working_date":{"type":"string","format":"date","example":"2026-05-31","nullable":true},"start_working_time":{"description":"Scheduled start from t_jobs","type":"string","example":"09:00:00","nullable":true},"end_working_time":{"description":"Scheduled end from t_jobs","type":"string","example":"18:00:00","nullable":true}},"type":"object","nullable":true},"company_branch":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Shinjuku Clinic"}},"type":"object","nullable":true}},"type":"object"},"CompanyUserReviewListItem":{"description":"One row in GET \/company\/user-reviews (same shape as GET \/user-reviews\/{id} without review_summary)","properties":{"id":{"description":"t_user_reviews.id","type":"integer","example":1},"job_working_id":{"type":"integer","example":100},"job_id":{"type":"integer","example":20},"user_id":{"type":"integer","example":5},"company_id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":1},"status":{"description":"t_user_reviews.status","type":"string","enum":["not_reviewed","reviewed"]},"reviewed_by":{"type":"integer","nullable":true},"punctuality":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"appearance":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"communication":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"work_attitude":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"skill":{"type":"integer","maximum":5,"minimum":1,"nullable":true},"average_score":{"type":"number","format":"float","nullable":true},"comment":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"job_working":{"$ref":"#\/components\/schemas\/CompanyUserReviewJobWorkingMeta"}},"type":"object"},"CompanyUserReviewRecentItem":{"description":"One submitted review in GET \/company\/user-reviews\/{id}\/recent","properties":{"id":{"type":"integer","example":2},"job_working_id":{"type":"integer","example":100},"job_id":{"type":"integer","example":20},"user_id":{"type":"integer","example":5},"company_id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":1},"status":{"type":"string","enum":["reviewed"],"example":"reviewed"},"punctuality":{"type":"integer","maximum":5,"minimum":1,"example":5},"appearance":{"type":"integer","maximum":5,"minimum":1,"example":4},"communication":{"type":"integer","maximum":5,"minimum":1,"example":5},"work_attitude":{"type":"integer","maximum":5,"minimum":1,"example":4},"skill":{"type":"integer","maximum":5,"minimum":1,"example":5},"average_score":{"type":"number","format":"float","example":4.6},"comment":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"job_working":{"properties":{"id":{"type":"integer","example":100},"working_date":{"type":"string","format":"date","example":"2026-01-15","nullable":true},"status":{"type":"string","example":"payment"},"completed_at":{"type":"string","format":"date-time","nullable":true}},"type":"object","nullable":true},"job":{"properties":{"id":{"type":"integer","example":20},"name":{"type":"string","example":"Night shift"}},"type":"object","nullable":true},"company_branch":{"properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Shinjuku Clinic"},"company_id":{"type":"integer","example":1}},"type":"object","nullable":true}},"type":"object"},"CompanyUserReviewRecent":{"description":"Payload for GET \/company\/user-reviews\/{id}\/recent","properties":{"user":{"properties":{"id":{"type":"integer","example":5},"name":{"type":"string","example":"Yamada Taro"},"katakana_name":{"type":"string","nullable":true}},"type":"object","nullable":true},"meta":{"properties":{"limit":{"description":"Echo of query limit; null when omitted","type":"integer","example":13,"nullable":true},"count":{"type":"integer","example":10}},"type":"object"},"reviews":{"description":"Submitted reviews oldest \u2192 newest","type":"array","items":{"$ref":"#\/components\/schemas\/CompanyUserReviewRecentItem"}}},"type":"object"},"CompanyUserReview":{"description":"t_user_reviews row (company evaluates worker)","properties":{"id":{"type":"integer","example":1},"job_working_id":{"type":"integer","example":100},"job_id":{"type":"integer","example":20},"user_id":{"type":"integer","example":5},"company_id":{"type":"integer","example":1},"company_branch_id":{"type":"integer","example":1},"reviewed_by":{"description":"t_company_user.id","type":"integer","example":2,"nullable":true},"punctuality":{"type":"integer","maximum":5,"minimum":1,"example":5,"nullable":true},"appearance":{"type":"integer","maximum":5,"minimum":1,"example":4,"nullable":true},"communication":{"type":"integer","maximum":5,"minimum":1,"example":5,"nullable":true},"work_attitude":{"type":"integer","maximum":5,"minimum":1,"example":4,"nullable":true},"skill":{"type":"integer","maximum":5,"minimum":1,"example":5,"nullable":true},"status":{"type":"string","enum":["not_reviewed","reviewed"],"example":"reviewed"},"average_score":{"type":"number","format":"float","example":4.6},"comment":{"type":"string","example":"Great worker.","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"},"user":{"description":"User model","properties":{"id":{"description":"OpenAPI definition: root + components (schemas, security).","type":"integer","example":1},"name":{"type":"string","example":"John Doe"},"email":{"type":"string","format":"email","example":"john@example.com"},"email_verified_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"},"api_response":{"description":"Standard API response wrapper","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Succeed"},"data":{"description":"Response payload (object, array or null)"}},"type":"object"},"UnprocessableEntity":{"description":"Laravel validation error (HTTP 422)","properties":{"message":{"type":"string","example":"The given data was invalid."},"errors":{"description":"Field name to list of validation messages","type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"type":"object"},"paginated_response":{"description":"Paginator object (value of response.data for list endpoints)","properties":{"current_page":{"type":"integer","example":1},"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/user"}},"first_page_url":{"type":"string"},"from":{"type":"integer"},"last_page":{"type":"integer"},"last_page_url":{"type":"string"},"links":{"type":"array","items":{"type":"object"}},"next_page_url":{"type":"string","nullable":true},"path":{"type":"string"},"per_page":{"type":"integer","example":15},"prev_page_url":{"type":"string","nullable":true},"to":{"type":"integer"},"total":{"type":"integer"}},"type":"object"},"company":{"description":"Company model","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Comedi Inc."},"status":{"description":"1=active 2=inactive","type":"integer","example":1},"furigana":{"type":"string","example":"\u30b3\u30e1\u30c7\u30a3"},"email":{"type":"string","format":"email","example":"contact@example.com"},"tax_code":{"description":"Business \/ corporate registration number (\u6cd5\u4eba\u756a\u53f7).","type":"string","example":"1234567890123","nullable":true},"address":{"type":"string","example":"1-2-3 Shibuya"},"latitude":{"type":"number","format":"float","example":35.681236,"nullable":true},"longitude":{"type":"number","format":"float","example":139.767125,"nullable":true},"company_file_id":{"type":"integer","example":10,"nullable":true},"company_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"company_avatar_id":{"type":"integer","example":11,"nullable":true},"company_avatar":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"branch_count":{"description":"Current non-deleted company branch count, included in admin company list and detail.","type":"integer","example":3},"prefecture_id":{"type":"integer","example":13},"district_id":{"type":"integer","example":101,"nullable":true},"representative_name":{"type":"string","example":"Tanaka Taro"},"business_content":{"type":"string","example":"Software development"},"area":{"description":"Company area \/ region label.","type":"string","example":"Kanto","nullable":true},"categories":{"description":"Company-level job categories (m_category via t_company_category)","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"},"display_order":{"type":"integer","example":1}},"type":"object"}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"},"CompanyUser":{"description":"Company user (login account linked to a company)","properties":{"id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"type":{"description":"1=admin 2=branch","type":"integer","example":1},"status":{"description":"1=active 2=inactive","type":"integer","example":1},"name":{"type":"string","example":"ABC Clinic"},"email":{"type":"string","format":"email","example":"clinic@example.com"},"token_version":{"type":"integer","example":0},"phone_number":{"type":"string","example":"08012345678","nullable":true},"branch_user_roles":{"description":"Assigned branch roles (empty for company admin accounts)","type":"array","items":{"$ref":"#\/components\/schemas\/BranchUserRole"}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"},"FileUpload":{"description":"t_file_uploads: `path` is the S3 object key (persisted). `url` is a temporary presigned URL for S3 (fallback: public base + path if signing is unavailable).","properties":{"id":{"type":"integer","example":1},"path":{"description":"Object key on S3 (always stored)","type":"string","example":"uploads\/avatars\/abc.png"},"url":{"description":"Temporary presigned URL (TTL controlled by FILE_UPLOAD_PRESIGNED_TTL_MINUTES). Falls back to public base URL if signing is unavailable; null only when path\/base is missing.","type":"string","format":"uri","nullable":true},"name":{"type":"string","example":"photo.jpg"},"extension":{"type":"string","example":"jpg"}},"type":"object"},"CompanyBranch":{"description":"Company branch (t_company_branches)","properties":{"id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Shibuya Branch"},"prefecture_id":{"type":"integer","example":13,"nullable":true},"district_id":{"type":"integer","example":101,"nullable":true},"postal_code":{"type":"string","example":"1500002","nullable":true},"address_line":{"type":"string","nullable":true},"latitude":{"type":"number","format":"float","example":35.658034,"nullable":true},"longitude":{"type":"number","format":"float","example":139.701636,"nullable":true},"access_note":{"type":"string","nullable":true},"has_on_site_parking":{"type":"boolean","example":true},"commuting_note":{"type":"string","nullable":true},"responsible_person_name":{"type":"string","nullable":true},"face_photo_file_id":{"type":"integer","nullable":true},"face_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"responsible_person_photo_file_id":{"type":"integer","nullable":true},"responsible_person_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"greeting_message":{"type":"string","nullable":true},"worker_contact_name":{"type":"string","nullable":true},"worker_contact_photo_file_id":{"type":"integer","nullable":true},"worker_contact_photo_file":{"oneOf":[{"$ref":"#\/components\/schemas\/FileUpload"}],"nullable":true},"worker_contact_phone":{"type":"string","nullable":true},"emergency_contact":{"type":"string","nullable":true},"responsible_person_email":{"type":"string","format":"email","nullable":true},"first_confirmation_auto_message":{"type":"string","nullable":true},"facility_open_date":{"type":"string","format":"date","nullable":true},"unemployment_insurance_office_number":{"type":"string","nullable":true},"company_regions":{"description":"Company regions this branch belongs to (t_company_regions via pivot)","type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"}},"categories":{"description":"Branch job categories (m_category via t_company_branch_category)","type":"array","items":{"properties":{"id":{"type":"integer","example":1},"key":{"type":"string","example":"nurse"},"name":{"type":"string","example":"\u770b\u8b77\u5e2b"},"display_order":{"type":"integer","example":1}},"type":"object"}},"travel_methods":{"description":"Commute options (m_travel_methods via pivot)","type":"array","items":{"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"type":"object"},"BranchRole":{"description":"Branch role master (m_branch_roles)","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Manager"},"description":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}},"type":"object"},"BranchUserRole":{"description":"Pivot row (t_branch_user_roles) with nested role","properties":{"id":{"type":"integer","example":1},"branch_user_profile_id":{"type":"integer","example":1},"branch_role_id":{"type":"integer","example":1},"branch_role":{"$ref":"#\/components\/schemas\/BranchRole"}},"type":"object"},"CompanyRegion":{"description":"Company region (t_company_regions)","properties":{"id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Kanto"}},"type":"object"},"BranchUser":{"description":"Branch user profile (t_branch_user_profiles) with relations","properties":{"id":{"type":"integer","example":1},"company_id":{"type":"integer","example":1},"name":{"type":"string","example":"Yamada Taro"},"furigana":{"type":"string","nullable":true},"phone_number":{"type":"string","nullable":true},"company_user":{"description":"Login credentials (t_company_user)","properties":{"id":{"type":"integer"},"email":{"type":"string","format":"email"}},"type":"object","nullable":true},"branches":{"description":"Assigned branches (t_branch_user_branches pivot)","type":"array","items":{"$ref":"#\/components\/schemas\/CompanyBranch"}},"regions":{"description":"Assigned regions (t_branch_user_regions pivot)","type":"array","items":{"$ref":"#\/components\/schemas\/CompanyRegion"}},"branch_user_roles":{"type":"array","items":{"$ref":"#\/components\/schemas\/BranchUserRole"}},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}},"type":"object"},"Region":{"description":"Region master (m_regions)","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"Kanto"},"key":{"type":"string","example":"kanto"},"description":{"type":"string","example":"Kanto region of Japan","nullable":true}},"type":"object"},"UserMedicalWorkplaceExperience":{"required":["workplace_type_id","experience_year_id"],"properties":{"workplace_type_id":{"description":"m_workplace_types.id","type":"integer","example":1},"experience_year_id":{"description":"m_experience_years.id","type":"integer","example":2}},"type":"object"},"UserMedicalLicenseInput":{"required":["type"],"properties":{"id":{"description":"Existing t_user_licenses.id when updating","type":"integer","example":1,"nullable":true},"type":{"type":"string","example":"doctor"},"category_id":{"type":"integer","example":1,"nullable":true},"license_number":{"type":"string","example":"123456","nullable":true},"registration_subtype_id":{"type":"integer","example":1,"nullable":true},"acquired_at":{"type":"string","format":"date","example":"2020-04-01","nullable":true},"clinical_training_end_at":{"type":"string","format":"date","example":"2025-03-31","nullable":true}},"type":"object"},"UserMedicalCategoryProfileBlock":{"description":"Medical profile data for one profession (m_category.id). Certificates and licenses must be nested here \u2014 root-level certificate_ids \/ licenses are rejected.","required":["category_id"],"properties":{"category_id":{"type":"integer","example":1},"experience_year_id":{"description":"m_experience_years.id","type":"integer","example":2,"nullable":true},"skill_ids":{"type":"array","items":{"type":"integer","example":1},"nullable":true},"workplace_ids":{"type":"array","items":{"type":"integer","example":1},"nullable":true},"workplace_experiences":{"type":"array","items":{"$ref":"#\/components\/schemas\/UserMedicalWorkplaceExperience"},"nullable":true},"sub_category_ids":{"type":"array","items":{"type":"integer","example":1},"nullable":true},"sub_category_detail_ids":{"type":"array","items":{"type":"integer","example":1},"nullable":true},"certificate_ids":{"type":"array","items":{"type":"integer","example":1},"nullable":true},"licenses":{"type":"array","items":{"$ref":"#\/components\/schemas\/UserMedicalLicenseInput"},"nullable":true}},"type":"object"}},"securitySchemes":{"bearerAuth":{"type":"http","description":"JWT access token (tymon\/jwt-auth); send as Authorization: Bearer <token>","bearerFormat":"JWT","scheme":"bearer"}}},"tags":[{"name":"Admin","description":"Authentication API"},{"name":"Admin Google Maps","description":"Admin Google Maps helper endpoints"},{"name":"Admin Master","description":"Admin master data (reference tables)"},{"name":"App company branches","description":"Company branch resources for the mobile app"},{"name":"App","description":"App API"},{"name":"App Bank Account","description":"Bank account management for app users"},{"name":"App\/Documents","description":"Policy documents (presigned URLs)"},{"name":"App jobs","description":"Job listings for the mobile app"},{"name":"App locations","description":"Location utilities for the mobile app"},{"name":"App\/SalaryExport","description":"Withholding tax certificate (\u6e90\u6cc9\u5fb4\u53ce\u7968) exports"},{"name":"App\/Timekeeping","description":"App user check-in, check-out (credits wallet on check-out), salary confirm, and time-change requests"},{"name":"App Wallet","description":"Wallet and withdrawals (app users)"},{"name":"Company","description":"Authentication endpoints for Companies"},{"name":"Company Branch","description":"Company branch management (scoped to authenticated company)"},{"name":"Company Information","description":"Company information endpoints (admin only)"},{"name":"Company Notification","description":"Company notification management (scoped to authenticated company user)"},{"name":"Company Documents","description":"Company document presigned URLs"},{"name":"Company Google Maps","description":"Company Google Maps helper endpoints"},{"name":"Company Job","description":"Job postings for company accounts (CRUD scoped to authenticated company)"},{"name":"Company Job Working Request","description":"Company portal \u2014 worker timekeeping change requests (`t_job_working_requests`)"},{"name":"Company Master","description":"Company master data (reference tables)"},{"name":"Company Profile","description":"Company profile"},{"name":"Company Region","description":"Company-owned regions (t_company_regions)"},{"name":"Company\/SourceIncomeSlip","description":"Company source income slip \/ withholding tax certificate APIs"},{"name":"Company Timekeeping","description":"Timekeeping (job working) records for company accounts"},{"name":"Company Transactions","description":"Company portal \u2014 approve worker salary payout (withdraw) transactions"},{"name":"Company Usage Costs","description":"Branch billing periods (`t_company_branch_used_cost`) \u2014 list headers per company \/ branch"},{"name":"Company Usage Details","description":"\u5229\u7528\u660e\u7d30 (SCR-047) \u2014 completed shifts for billing-style list"},{"name":"Company User Review","description":"Company portal \u2014 evaluate workers after completed shifts (t_user_reviews per job_working)"},{"name":"Healthcheck","description":"Healthcheck endpoints"},{"name":"Test","description":"Test endpoints for logging and exception handling"},{"name":"Admin Company Branch","description":"Admin Company Branch"},{"name":"Admin Company","description":"Admin Company"},{"name":"Admin Dashboard","description":"Admin Dashboard"},{"name":"Admin Monthly Payment Stats","description":"Admin Monthly Payment Stats"},{"name":"Admin Salary Payment","description":"Admin Salary Payment"},{"name":"Admin System Fee","description":"Admin System Fee"},{"name":"App favorites","description":"App favorites"},{"name":"App Review company branches","description":"App Review company branches"},{"name":"App - FCM","description":"App - FCM"},{"name":"KYC","description":"KYC"},{"name":"App - Notifications","description":"App - Notifications"},{"name":"App Review users","description":"App Review users"},{"name":"Company Branch User","description":"Company Branch User"},{"name":"Company Dashboard","description":"Company Dashboard"},{"name":"Company Job Apply","description":"Company Job Apply"},{"name":"Company Working Time Calendar","description":"Company Working Time Calendar"}]}