681 lines
20 KiB
JSON
681 lines
20 KiB
JSON
{
|
|
"openapi": "3.0.0",
|
|
"info": {
|
|
"title": "Migrant Mobile API",
|
|
"description": "Comprehensive API endpoints for the Migrant Mobile Application, covering worker registration, password login, token authentication, profile management, and interactive job offer responses.",
|
|
"version": "1.0.0"
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "/api",
|
|
"description": "Local development API prefix"
|
|
}
|
|
],
|
|
"security": [
|
|
{
|
|
"bearerAuth": []
|
|
}
|
|
],
|
|
"paths": {
|
|
"/workers/register": {
|
|
"post": {
|
|
"summary": "Register Worker & Upload Documents (Unified API)",
|
|
"description": "Performs worker registration and uploads their passport/visa documents in a single, robust multipart form request. Generates and returns a secure stateless bearer token upon success. Password is required (min 6 characters).",
|
|
"security": [],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"name",
|
|
"phone",
|
|
"salary",
|
|
"password",
|
|
"passport_file"
|
|
],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"example": "Amina Al-Masry",
|
|
"description": "Full legal name of the worker. (REQUIRED)"
|
|
},
|
|
"phone": {
|
|
"type": "string",
|
|
"example": "+971509998888",
|
|
"description": "Contact mobile phone number (must be unique). (REQUIRED)"
|
|
},
|
|
"salary": {
|
|
"type": "number",
|
|
"format": "float",
|
|
"example": 1500.00,
|
|
"description": "Desired minimum monthly salary in AED. (REQUIRED)"
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"format": "password",
|
|
"example": "securepassword123",
|
|
"description": "Secret password for subsequent mobile logins (min 6 chars). (REQUIRED)"
|
|
},
|
|
"passport_file": {
|
|
"type": "string",
|
|
"format": "binary",
|
|
"description": "Physical scan or image of the Passport (Max 10MB). (REQUIRED)"
|
|
},
|
|
"skills": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer"
|
|
},
|
|
"example": [6, 8],
|
|
"description": "Optional array of Skill IDs (can be sent as comma-separated string e.g. '6,8' or json '[6,8]' in multipart)."
|
|
},
|
|
"visa_file": {
|
|
"type": "string",
|
|
"format": "binary",
|
|
"description": "Optional physical scan or image of the Visa (Max 10MB)."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Worker registered and authenticated successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Worker registered and authenticated successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"worker": {
|
|
"$ref": "#/components/schemas/Worker"
|
|
},
|
|
"token": {
|
|
"type": "string",
|
|
"example": "abc123xyz456...secureToken..."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"422": {
|
|
"description": "Validation error details.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": false
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Validation error."
|
|
},
|
|
"errors": {
|
|
"type": "object",
|
|
"properties": {
|
|
"phone": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"example": [
|
|
"This mobile number is already registered."
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/workers/login": {
|
|
"post": {
|
|
"summary": "Authenticate Worker",
|
|
"description": "Validates worker credentials (mobile phone number and password) and generates a secure, stateless Bearer token for api access.",
|
|
"security": [],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"phone",
|
|
"password"
|
|
],
|
|
"properties": {
|
|
"phone": {
|
|
"type": "string",
|
|
"example": "+971509998888",
|
|
"description": "Registered mobile phone number."
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"format": "password",
|
|
"example": "securepassword123",
|
|
"description": "Secret account password."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Worker logged in successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Worker logged in successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"worker": {
|
|
"$ref": "#/components/schemas/Worker"
|
|
},
|
|
"token": {
|
|
"type": "string",
|
|
"example": "abc123xyz456...secureToken..."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Unauthorized access.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": false
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Invalid mobile number or password."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/workers/profile": {
|
|
"get": {
|
|
"summary": "Get Profile details",
|
|
"description": "Retrieves the authenticated worker's profile details including their selected job category, connected skills, and uploaded documents.",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Worker profile details retrieved.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"worker": {
|
|
"$ref": "#/components/schemas/Worker"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/workers/profile/update": {
|
|
"post": {
|
|
"summary": "Update Profile details",
|
|
"description": "Allows workers to customize and complete their profiles by updating age, nationality, desired salary, bio, availability, experience, religion, categories, and master skills list.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"example": "Amina Al-Masry"
|
|
},
|
|
"age": {
|
|
"type": "integer",
|
|
"example": 28
|
|
},
|
|
"nationality": {
|
|
"type": "string",
|
|
"example": "Egypt"
|
|
},
|
|
"salary": {
|
|
"type": "number",
|
|
"example": 1800.00
|
|
},
|
|
"availability": {
|
|
"type": "string",
|
|
"example": "Immediate"
|
|
},
|
|
"experience": {
|
|
"type": "string",
|
|
"example": "4 Years"
|
|
},
|
|
"religion": {
|
|
"type": "string",
|
|
"example": "Muslim"
|
|
},
|
|
"bio": {
|
|
"type": "string",
|
|
"example": "Highly certified housekeeper and babysitter with cooking experience."
|
|
},
|
|
"category_id": {
|
|
"type": "integer",
|
|
"example": 8
|
|
},
|
|
"skills": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer"
|
|
},
|
|
"example": [6, 8]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Profile updated successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Profile updated successfully."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"worker": {
|
|
"$ref": "#/components/schemas/Worker"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/workers/offers": {
|
|
"get": {
|
|
"summary": "View Received Job Offers",
|
|
"description": "Returns a list of all custom job/hiring offers received by the worker from different employers (e.g. Work Date, location, salaries, and notes).",
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of job offers retrieved.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"offers": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/JobOffer"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/workers/offers/{id}/respond": {
|
|
"post": {
|
|
"summary": "Accept or Reject Job Offer",
|
|
"description": "Responds to a pending job offer. If accepted, the job offer status becomes 'accepted' and the worker's status is automatically changed to 'Hired', which reflects immediately in the Employer panel.",
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "The Job Offer ID reference.",
|
|
"schema": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"status"
|
|
],
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"accepted",
|
|
"rejected"
|
|
],
|
|
"example": "accepted",
|
|
"description": "Response action (accepted or rejected)."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Job offer response saved successfully.",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"example": true
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"example": "Job offer successfully accepted."
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"offer": {
|
|
"$ref": "#/components/schemas/JobOffer"
|
|
},
|
|
"worker_status": {
|
|
"type": "string",
|
|
"example": "Hired"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"securitySchemes": {
|
|
"bearerAuth": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "JWT"
|
|
}
|
|
},
|
|
"schemas": {
|
|
"Worker": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 136
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"example": "Amina Al-Masry"
|
|
},
|
|
"email": {
|
|
"type": "string",
|
|
"example": "worker.971509998888@migrant.com"
|
|
},
|
|
"phone": {
|
|
"type": "string",
|
|
"example": "+971509998888"
|
|
},
|
|
"nationality": {
|
|
"type": "string",
|
|
"example": "Egypt"
|
|
},
|
|
"age": {
|
|
"type": "integer",
|
|
"example": 28
|
|
},
|
|
"salary": {
|
|
"type": "string",
|
|
"example": "1500.00"
|
|
},
|
|
"availability": {
|
|
"type": "string",
|
|
"example": "Immediate"
|
|
},
|
|
"experience": {
|
|
"type": "string",
|
|
"example": "4 Years"
|
|
},
|
|
"religion": {
|
|
"type": "string",
|
|
"example": "Muslim"
|
|
},
|
|
"bio": {
|
|
"type": "string",
|
|
"example": "Certified infant caregiver and housekeeper with excellent cooking skills."
|
|
},
|
|
"category_id": {
|
|
"type": "integer",
|
|
"example": 7
|
|
},
|
|
"verified": {
|
|
"type": "boolean",
|
|
"example": false
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"example": "active"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"example": "2026-05-20T14:54:26.000000Z"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"example": "2026-05-20T14:54:26.000000Z"
|
|
},
|
|
"category": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 7
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"example": "General Helper"
|
|
}
|
|
}
|
|
},
|
|
"skills": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 6
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"example": "Cleaning"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"documents": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/WorkerDocument"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"WorkerDocument": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 15
|
|
},
|
|
"worker_id": {
|
|
"type": "integer",
|
|
"example": 136
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"example": "passport"
|
|
},
|
|
"number": {
|
|
"type": "string",
|
|
"example": "P345892"
|
|
},
|
|
"issue_date": {
|
|
"type": "string",
|
|
"format": "date",
|
|
"example": "2024-05-20"
|
|
},
|
|
"expiry_date": {
|
|
"type": "string",
|
|
"format": "date",
|
|
"example": "2034-05-20"
|
|
},
|
|
"ocr_accuracy": {
|
|
"type": "number",
|
|
"example": 98.5
|
|
},
|
|
"file_path": {
|
|
"type": "string",
|
|
"example": "uploads/documents/1716200000_passport_my_file.jpg"
|
|
}
|
|
}
|
|
},
|
|
"JobOffer": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 1
|
|
},
|
|
"employer_id": {
|
|
"type": "integer",
|
|
"example": 2
|
|
},
|
|
"worker_id": {
|
|
"type": "integer",
|
|
"example": 136
|
|
},
|
|
"work_date": {
|
|
"type": "string",
|
|
"format": "date",
|
|
"example": "2026-06-01"
|
|
},
|
|
"location": {
|
|
"type": "string",
|
|
"example": "Dubai Marina, Silverene Towers"
|
|
},
|
|
"salary": {
|
|
"type": "string",
|
|
"example": "2500.00"
|
|
},
|
|
"notes": {
|
|
"type": "string",
|
|
"example": "Require housekeeping support starting from June 1st."
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"example": "pending"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"example": "2026-05-20T15:23:44.000000Z"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"example": "2026-05-20T15:23:44.000000Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|