{
    "openapi": "3.0.0",
    "info": {
        "title": "South City Hospital API",
        "description": "Patient mobile app API for OPD appointment booking",
        "contact": {
            "email": "admin@southcityhospital.pk"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "/api/v1",
            "description": "API v1"
        }
    ],
    "paths": {
        "/appointments": {
            "get": {
                "tags": [
                    "Appointments"
                ],
                "summary": "List authenticated patient's appointments",
                "operationId": "a093a92271ae0faf0346a57612db24c6",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "from_date",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to_date",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated appointment list"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Appointments"
                ],
                "summary": "Book an appointment",
                "operationId": "b029272b237cdbcfb43c0ff9c2240da2",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "consultant_uuid",
                                    "appointment_date",
                                    "slot_start",
                                    "visit_type"
                                ],
                                "properties": {
                                    "consultant_uuid": {
                                        "type": "string"
                                    },
                                    "appointment_date": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "slot_start": {
                                        "type": "string",
                                        "example": "09:00"
                                    },
                                    "visit_type": {
                                        "type": "string",
                                        "enum": [
                                            "opd",
                                            "follow_up",
                                            "emergency"
                                        ]
                                    },
                                    "schedule_id": {
                                        "type": "integer"
                                    },
                                    "notes": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Appointment booked"
                    },
                    "409": {
                        "description": "Slot unavailable"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/appointments/{booking_ref}": {
            "get": {
                "tags": [
                    "Appointments"
                ],
                "summary": "Get appointment detail",
                "operationId": "5b041cb6079d4c320c0ccb66f6852b58",
                "parameters": [
                    {
                        "name": "booking_ref",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Appointment detail"
                    },
                    "403": {
                        "description": "Forbidden — not your appointment"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/appointments/{booking_ref}/cancel": {
            "post": {
                "tags": [
                    "Appointments"
                ],
                "summary": "Cancel an appointment",
                "operationId": "b0e95a683ea9171e49aa17f082f50c72",
                "parameters": [
                    {
                        "name": "booking_ref",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "reason": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Cancelled"
                    },
                    "422": {
                        "description": "Cannot cancel in current state"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/appointments/{booking_ref}/reschedule": {
            "post": {
                "tags": [
                    "Appointments"
                ],
                "summary": "Reschedule an appointment to a new date/slot",
                "operationId": "24bd86ebe91e5601eea0e211d31ed836",
                "parameters": [
                    {
                        "name": "booking_ref",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "date",
                                    "slot_start"
                                ],
                                "properties": {
                                    "date": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "slot_start": {
                                        "type": "string",
                                        "example": "11:00"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Rescheduled — new booking ref in response"
                    },
                    "409": {
                        "description": "New slot unavailable"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/auth/check-mr": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Pre-registration: verify MR number, check uniqueness, send OTP to HIMS phone",
                "operationId": "6f8c1481d24afc21cacef95c64703cba",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "mr_number",
                                    "email",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "mr_number": {
                                        "type": "string",
                                        "example": "MR-247891"
                                    },
                                    "email": {
                                        "type": "string",
                                        "example": "patient@example.com"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "secret1234"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "secret1234"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "MR found — OTP sent to registered phone"
                    },
                    "404": {
                        "description": "MR number not found in HIMS"
                    },
                    "409": {
                        "description": "MR or email already registered"
                    }
                }
            }
        },
        "/auth/register": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Step 1: Initiate registration — sends OTP to phone",
                "operationId": "1ad4e4447f4ef3eb632ed2691c00c0e8",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "phone",
                                    "password",
                                    "password_confirmation",
                                    "mr_number"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "Ahmed Khan"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "example": "03001234567"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "secret1234"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "secret1234"
                                    },
                                    "mr_number": {
                                        "type": "string",
                                        "example": "MR-0012345"
                                    },
                                    "date_of_birth": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "gender": {
                                        "type": "string",
                                        "enum": [
                                            "male",
                                            "female",
                                            "other"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OTP sent"
                    },
                    "409": {
                        "description": "Phone or MR already registered"
                    }
                }
            }
        },
        "/auth/register/verify": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Step 2: Verify OTP and complete registration",
                "operationId": "cfe5bc2604e731a078c5c777f93fc062",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "phone",
                                    "password",
                                    "password_confirmation",
                                    "mr_number",
                                    "otp"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "password": {
                                        "type": "string"
                                    },
                                    "password_confirmation": {
                                        "type": "string"
                                    },
                                    "mr_number": {
                                        "type": "string"
                                    },
                                    "otp": {
                                        "type": "string",
                                        "example": "693726"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Registration successful"
                    },
                    "422": {
                        "description": "Invalid or expired OTP"
                    }
                }
            }
        },
        "/auth/login": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Password-based login — accepts phone or MR number as identifier",
                "operationId": "e5e32c5c121d50e864abf0f704b71593",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "identifier",
                                    "password"
                                ],
                                "properties": {
                                    "identifier": {
                                        "description": "Phone number or MR number",
                                        "type": "string",
                                        "example": "03001234567"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "secret1234"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login successful"
                    },
                    "401": {
                        "description": "Invalid credentials"
                    },
                    "403": {
                        "description": "Account deactivated"
                    }
                }
            }
        },
        "/auth/send-otp": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Send OTP for login or password reset",
                "operationId": "de26f533ab0c8f810e857a53f97a0b0f",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "phone",
                                    "purpose"
                                ],
                                "properties": {
                                    "phone": {
                                        "type": "string",
                                        "example": "03001234567"
                                    },
                                    "purpose": {
                                        "type": "string",
                                        "enum": [
                                            "registration",
                                            "login",
                                            "password_reset"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OTP sent"
                    }
                }
            }
        },
        "/auth/verify-otp": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Verify OTP and receive Bearer token (OTP login)",
                "operationId": "35b3750ecf38da86eb585b77ae69e279",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "phone",
                                    "otp",
                                    "purpose"
                                ],
                                "properties": {
                                    "phone": {
                                        "type": "string"
                                    },
                                    "otp": {
                                        "type": "string",
                                        "example": "693726"
                                    },
                                    "purpose": {
                                        "type": "string",
                                        "enum": [
                                            "login",
                                            "password_reset"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OTP verified — returns Bearer token"
                    },
                    "422": {
                        "description": "Invalid or expired OTP"
                    }
                }
            }
        },
        "/auth/me": {
            "get": {
                "tags": [
                    "Auth"
                ],
                "summary": "Get authenticated user profile",
                "operationId": "bf21b27a7e826768548b5b14ee2d44f2",
                "responses": {
                    "200": {
                        "description": "User profile"
                    },
                    "401": {
                        "description": "Unauthenticated"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Logout — revoke current Bearer token",
                "operationId": "1536ec034ecbb551483aeacfd4eea588",
                "responses": {
                    "200": {
                        "description": "Logged out"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/consultants": {
            "get": {
                "tags": [
                    "Consultants"
                ],
                "summary": "List active consultants",
                "operationId": "47ab10ce4310e0a617a37f7fc7a329a7",
                "parameters": [
                    {
                        "name": "department_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "visit_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "opd",
                                "online",
                                "follow_up"
                            ]
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Consultant list"
                    }
                }
            }
        },
        "/consultants/{consultant}": {
            "get": {
                "tags": [
                    "Consultants"
                ],
                "summary": "Get consultant details",
                "operationId": "5605bf6929bc34689bc22bb8d37d852f",
                "parameters": [
                    {
                        "name": "consultant",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Consultant detail"
                    },
                    "404": {
                        "description": "Not found"
                    }
                }
            }
        },
        "/consultants/{consultant}/available-dates": {
            "get": {
                "tags": [
                    "Consultants"
                ],
                "summary": "Get dates with available slots",
                "operationId": "4584deace3a0e66ef22b7939ef091be9",
                "parameters": [
                    {
                        "name": "consultant",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "visit_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "opd"
                        }
                    },
                    {
                        "name": "days",
                        "in": "query",
                        "description": "Lookahead window (1-60)",
                        "schema": {
                            "type": "integer",
                            "default": 30
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Available dates list"
                    }
                }
            }
        },
        "/consultants/{consultant}/slots": {
            "get": {
                "tags": [
                    "Consultants"
                ],
                "summary": "Get time slots for a consultant on a date",
                "operationId": "205c3f5a50efca22dd9a10614427a932",
                "parameters": [
                    {
                        "name": "consultant",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "date",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-05-25"
                        }
                    },
                    {
                        "name": "visit_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "opd"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Slots with availability"
                    },
                    "422": {
                        "description": "Validation error"
                    }
                }
            }
        },
        "/departments": {
            "get": {
                "tags": [
                    "Departments"
                ],
                "summary": "List all active departments",
                "operationId": "c5c56f5313e2f611b1fef1d5e18cad04",
                "responses": {
                    "200": {
                        "description": "Department list"
                    }
                }
            }
        },
        "/departments/{department}": {
            "get": {
                "tags": [
                    "Departments"
                ],
                "summary": "Get department with specialities",
                "operationId": "cf07fc85a4c0f13b36c44c2430ccf3ad",
                "parameters": [
                    {
                        "name": "department",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Department detail"
                    },
                    "404": {
                        "description": "Not found"
                    }
                }
            }
        },
        "/pharmacy/categories": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List active pharmacy categories",
                "operationId": "6cb836123a716c23c0696a997c600f1c",
                "responses": {
                    "200": {
                        "description": "Categories list"
                    }
                }
            }
        },
        "/pharmacy/products": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List active pharmacy products",
                "operationId": "8cbe19c4f94cfe9c6c9dc7efceb572bd",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "description": "Category slug",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "in_stock",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Products list"
                    }
                }
            }
        },
        "/pharmacy/products/{id}": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Get a single pharmacy product",
                "operationId": "9e45e1c2183e38ee14d567c89f93c844",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Product detail"
                    }
                }
            }
        },
        "/pharmacy/delivery-methods": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List active delivery methods with computed fees",
                "operationId": "5fb695bb961b6cb0cd93594ef89b546f",
                "parameters": [
                    {
                        "name": "subtotal",
                        "in": "query",
                        "description": "Cart subtotal to compute actual fee",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Delivery methods"
                    }
                }
            }
        },
        "/pharmacy/payment-methods": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List active payment methods",
                "operationId": "0bc16e462a44e5cf953aa8ea0e4d652d",
                "responses": {
                    "200": {
                        "description": "Payment methods"
                    }
                }
            }
        },
        "/pharmacy/offers/validate": {
            "post": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Validate a promo code and preview discount",
                "operationId": "a80186c91265224101f38997cb5d37ad",
                "responses": {
                    "200": {
                        "description": "Offer details"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/homepage": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Get homepage layout: categories, promo banners, and configured sections with products",
                "operationId": "cc9c49bca63a7e526c06d37413cdf9bb",
                "responses": {
                    "200": {
                        "description": "Homepage layout"
                    }
                }
            }
        },
        "/pharmacy/orders": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List authenticated patient's pharmacy orders",
                "operationId": "dbae8e7d355e9f396c8775b5d840336d",
                "responses": {
                    "200": {
                        "description": "Paginated order list"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Place a new pharmacy order",
                "operationId": "d1d307e1699a29514e6ca96d62d697fe",
                "responses": {
                    "201": {
                        "description": "Order placed"
                    },
                    "422": {
                        "description": "Validation or stock error"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/orders/{reference}": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Get a single pharmacy order detail",
                "operationId": "4b597e9fb29a4c663762a0dc28dcb921",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order detail"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/orders/{reference}/cancel": {
            "post": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Cancel a pharmacy order",
                "operationId": "c5d106380e3fb7ef4234ce435f1b9a96",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order cancelled"
                    },
                    "422": {
                        "description": "Cannot cancel in current status"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/orders/{reference}/pickup-token": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Get pickup QR token for a pickup order",
                "operationId": "032ca5d6b6e408b4942fc2e9fe7926e1",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Pickup token"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/orders/{reference}/prescriptions": {
            "get": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "List prescriptions uploaded for an order",
                "operationId": "5c91c289be0934da58f4c57faa4c2688",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Prescriptions list"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Upload a prescription file for an order",
                "operationId": "148a68dab07ce66e39148432067821ef",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Prescription uploaded"
                    },
                    "422": {
                        "description": "Upload not allowed in current status"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        },
        "/pharmacy/orders/{reference}/prescriptions/{id}": {
            "delete": {
                "tags": [
                    "Pharmacy"
                ],
                "summary": "Remove an uploaded prescription",
                "operationId": "369df2b259523b8c9dad545bb3d0d48f",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Prescription removed"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "BearerToken": {
                "type": "http",
                "bearerFormat": "Sanctum",
                "scheme": "bearer"
            }
        }
    },
    "tags": [
        {
            "name": "Appointments",
            "description": "Appointments"
        },
        {
            "name": "Auth",
            "description": "Auth"
        },
        {
            "name": "Consultants",
            "description": "Consultants"
        },
        {
            "name": "Departments",
            "description": "Departments"
        },
        {
            "name": "Pharmacy",
            "description": "Pharmacy"
        }
    ]
}