{
    "openapi": "3.0.0",
    "info": {
        "title": "Kapitano — Dashboard API",
        "description": "The Kapitano Logistic **dashboard API** (`/api/dashboard/*`) used by the back office:\nadmin sign in, admin & role management, the captain review queue, vehicle management,\norder assignment with nearest-first captain suggestions, and push notifications.\n\n**Required headers.** Every `api/*` route passes `CheckApiHeaderMiddleware` first:\n\n- `Accept: application/json` — anything else answers `401`.\n- `Accept-Language: en` (or `ar`) — missing answers `401`; accepted values are the\n  `app.supported_locales` list, anything else falls back to the fallback locale.\n\n**Authentication.** Every dashboard endpoint takes the `adminAuth` bearer token\nissued by `POST /api/dashboard/auth/login` (a Laravel Sanctum token).\n\n**Response envelope.** Every endpoint answers the same shape:\n`{ \"Model\", \"Status\", \"Message\", \"MessageDebug\", \"Total\", \"Page\", \"Records\" }`.\nOn paginated lists `Total` is the number of pages, `Page` the current one and\n`Records` the total record count.",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://captain.kapitano.shop",
            "description": "Production API"
        },
        {
            "url": "http://127.0.0.1:8000",
            "description": "Local — php artisan serve"
        },
        {
            "url": "http://localhost/kapitano_logistic",
            "description": "Local — XAMPP (htdocs)"
        }
    ],
    "paths": {
        "/api/dashboard/admins": {
            "get": {
                "tags": [
                    "Dashboard — Admins"
                ],
                "summary": "List the back office accounts",
                "description": "Paginated. Filters: search by name/email/phone, is_active, role name. Requires `admins.view`.",
                "operationId": "adminIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "maxLength": 255
                        }
                    },
                    {
                        "name": "is_active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "role",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "example": "operations-manager"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of admins.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Admin"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing admins.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing/invalid page or rows.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Admins"
                ],
                "summary": "Create a back office account",
                "description": "Creates the account and grants the roles sent with it. Requires `admins.create`.",
                "operationId": "adminStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "Monte Kilback",
                                        "maxLength": 255
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "enrique.walker@example.org",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^\\+[0-9]{8,15}$",
                                        "example": "+966500379188"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "date_of_birth": {
                                        "type": "string",
                                        "format": "date",
                                        "example": "1979-09-23",
                                        "nullable": true
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "roles": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "example": [
                                            "operations-manager"
                                        ],
                                        "minItems": 1
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "Monte Kilback",
                                "email": "enrique.walker@example.org",
                                "phone": "+966500379188",
                                "password": "123456",
                                "password_confirmation": "123456",
                                "date_of_birth": "1979-09-23",
                                "is_active": true,
                                "roles": [
                                    "operations-manager"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Account created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing admins.create permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/admins/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Admins"
                ],
                "summary": "One back office account",
                "description": "With the roles held and the permissions they grant. Requires `admins.view`. Admin records use UUIDs.",
                "operationId": "adminShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a08600-86f8-72c5-9307-feeac9ae0b5b"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The admin record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing admins.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Admin not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Admins"
                ],
                "summary": "Change a back office account",
                "description": "Updates the sent fields and syncs the roles. Requires `admins.update`.",
                "operationId": "adminUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a08600-86f8-72c5-9307-feeac9ae0b5b"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "Monte Kilback",
                                        "maxLength": 255
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "enrique.walker@example.org",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^\\+[0-9]{8,15}$",
                                        "example": "+966500379188"
                                    },
                                    "date_of_birth": {
                                        "type": "string",
                                        "format": "date",
                                        "example": "1979-09-23",
                                        "nullable": true
                                    },
                                    "roles": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "example": [
                                            "operations-manager"
                                        ],
                                        "minItems": 1
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "Monte Kilback",
                                "email": "enrique.walker@example.org",
                                "phone": "+966500379188",
                                "date_of_birth": "1979-09-23",
                                "roles": [
                                    "operations-manager"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Account updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing admins.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Admin not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/admins/{uuid}/activation": {
            "patch": {
                "tags": [
                    "Dashboard — Admins"
                ],
                "summary": "Activate or deactivate an account",
                "description": "Turns the account on, or off together with every session it is signed in from. Requires `admins.update`.",
                "operationId": "adminToggleActivation",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a08600-86f8-72c5-9307-feeac9ae0b5b"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "State changed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing admins.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Admin not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/auth/login": {
            "post": {
                "tags": [
                    "Dashboard — Authentication"
                ],
                "summary": "Sign in to the dashboard",
                "description": "Exchanges an email and password for a Sanctum token plus the admin record. Throttle\n`admin-auth`: 5 requests per minute per email **and** per IP. A disabled account or\nwrong credentials are refused with their own status.",
                "operationId": "adminLogin",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "super-admin@kapitano-logiistic.com",
                                        "maxLength": 255
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "device_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "email": "super-admin@kapitano-logiistic.com",
                                "password": "123456"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Signed in.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/AdminAuthResult"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "Signed in successfully"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid credentials (or headers missing).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Disabled account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Email not registered.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "admin-auth throttle (5/min).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorTooManyRequests"
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/api/dashboard/auth/logout": {
            "post": {
                "tags": [
                    "Dashboard — Authentication"
                ],
                "summary": "Sign out",
                "description": "Revokes every Sanctum token the signed in admin holds.",
                "operationId": "adminLogout",
                "responses": {
                    "200": {
                        "description": "Signed out.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "null"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "Logged out successfully"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/auth/forgot-password": {
            "post": {
                "tags": [
                    "Dashboard — Authentication"
                ],
                "summary": "Send a password reset code",
                "description": "Sends a code to the phone number on the admin record so they can set a new password.",
                "operationId": "adminForgotPassword",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "super-admin@kapitano-logiistic.com",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "email": "super-admin@kapitano-logiistic.com"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Code sent."
                    },
                    "401": {
                        "description": "headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Disabled account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Email not registered.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "admin-auth throttle (5/min).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorTooManyRequests"
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/api/dashboard/auth/resend-code": {
            "post": {
                "tags": [
                    "Dashboard — Authentication"
                ],
                "summary": "Resend the password reset code",
                "description": "Sends the code again to the same phone number, for an admin who never received the first one.",
                "operationId": "adminResendCode",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "super-admin@kapitano-logiistic.com",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "email": "super-admin@kapitano-logiistic.com"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "New code sent."
                    },
                    "401": {
                        "description": "headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Disabled account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Email not registered.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "admin-auth throttle (5/min).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorTooManyRequests"
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/api/dashboard/auth/reset-password": {
            "post": {
                "tags": [
                    "Dashboard — Authentication"
                ],
                "summary": "Set a new password with the code",
                "description": "Sets the new password once the code checks out. Password must be confirmed.",
                "operationId": "adminResetPassword",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "super-admin@kapitano-logiistic.com",
                                        "maxLength": 255
                                    },
                                    "code": {
                                        "type": "string",
                                        "pattern": "^[0-9]{6}$",
                                        "example": "257843"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "123456"
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "email": "super-admin@kapitano-logiistic.com",
                                "code": "257843",
                                "password": "123456",
                                "password_confirmation": "123456"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password reset."
                    },
                    "401": {
                        "description": "headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Disabled account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Email not registered.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Code wrong/expired/exhausted or validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "admin-auth throttle (5/min).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorTooManyRequests"
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/api/dashboard/captain-ledger": {
            "get": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "Who owes and who is owed",
                "description": "The desk's main screen: one row per captain per currency, **largest amount first whichever\ndirection** — a captain holding 2,000 of the company's cash matters more than one owed 15.\n\nEach row carries `settle_with`, the movement that brings that captain back to zero, so the\nscreen offers \"pay out\" or \"take cash\" without the cashier working out which.\n\n`Totals` is the headline per currency: how much the company owes captains, how much\ncaptains owe it, and how many are on each side. Each captain is netted first — a captain\nwho paid 300 and collected 380 counts once, as owing 80.\n\nRequires `captain_ledger.view`.",
                "operationId": "captainLedgerDesk",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "state",
                        "in": "query",
                        "description": "`owed` — the desk pays out; `owes` — the desk takes cash in; `clear` — square.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "owed",
                                "owes",
                                "clear"
                            ]
                        }
                    },
                    {
                        "name": "currency",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 3,
                            "minLength": 3
                        },
                        "example": "SYP"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of balances, and the totals.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/CaptainBalance"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Pages.",
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Page": {
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Records": {
                                            "type": "integer",
                                            "example": 2
                                        },
                                        "Totals": {
                                            "description": "currency => totals",
                                            "type": "object",
                                            "additionalProperties": {
                                                "$ref": "#/components/schemas/CaptainLedgerTotals"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "`rows`/`page` missing, or an unknown `state`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/captain-ledger/entries": {
            "get": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "Every movement of money, newest first",
                "description": "The audit trail behind the balances: every line written for any captain, newest first, with\nthe captain named on each row.\n\n**This is a different question from the desk's list.** That one says where money is sitting\nnow; this one says what happened. A captain who took 5,000 and handed 5,000 back this\nmorning has a balance of zero, and the balances list has nothing to say about their day.\n\n`Totals` follows the filters and reports money **in and out separately** rather than netted,\nper currency, because the day above nets to nothing and a cashier needs the two figures.\n\nFilters: `type`, `currency`, `captain_uuid` (a ULID), `order_uuid`, and a `from`/`to` window\nthat covers the whole of both days it names. A filter naming a captain or an order that does\nnot exist answers with an empty page — not with every row.\n\nRequires `captain_ledger.view`.",
                "operationId": "captainLedgerFeed",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "supplier_payment",
                                "cash_collected",
                                "cash_paid_out",
                                "cash_handed_in",
                                "adjustment"
                            ]
                        }
                    },
                    {
                        "name": "currency",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 3,
                            "minLength": 3
                        },
                        "example": "SYP"
                    },
                    {
                        "name": "captain_uuid",
                        "in": "query",
                        "description": "Captain ULID.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    },
                    {
                        "name": "order_uuid",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "description": "Inclusive, from the start of that day.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "description": "Inclusive, to the end of that day.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of movements, and what they add up to.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/CaptainLedgerEntry"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Pages.",
                                            "type": "integer",
                                            "example": 3
                                        },
                                        "Page": {
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Records": {
                                            "type": "integer",
                                            "example": 64
                                        },
                                        "Totals": {
                                            "description": "currency => what the filtered set moved",
                                            "type": "object",
                                            "additionalProperties": {
                                                "$ref": "#/components/schemas/CaptainLedgerFeedTotals"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "`rows`/`page` missing, an unknown `type`, or `to` before `from`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/captains/{uuid}/ledger": {
            "get": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "One captain: balance and every movement",
                "description": "The captain's balance in every currency (`Balances`) and the statement behind it, newest\nfirst. Each line says who recorded it — the captain on their phone, or the back office —\nand, for delivery lines, what was expected beside what happened.\n\n`{uuid}` is the captain's **ULID**. Requires `captain_ledger.view`.",
                "operationId": "captainLedgerStatement",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    },
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "currency",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 3,
                            "minLength": 3
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The statement.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/CaptainLedgerEntry"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Records": {
                                            "type": "integer",
                                            "example": 4
                                        },
                                        "Captain": {
                                            "properties": {
                                                "uuid": {
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "type": "string"
                                                },
                                                "phone": {
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "Balances": {
                                            "description": "currency => balance",
                                            "type": "object",
                                            "example": {
                                                "SYP": 300
                                            }
                                        },
                                        "Totals": {
                                            "description": "currency => what that balance is made of. A cashier settling up is answering \"how did this number happen?\", and a net balance cannot say.",
                                            "type": "object",
                                            "additionalProperties": {
                                                "$ref": "#/components/schemas/CaptainBalanceBreakdown"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/captains/{uuid}/ledger/settle": {
            "post": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "Pay a captain out, or take cash from them",
                "description": "Records cash changing hands at the desk. **Only towards zero, and never past it:**\n\n| Captain is | `direction` | `amount` may be |\n|---|---|---|\n| owed | `cash_paid_out` | up to what they are owed |\n| owing | `cash_handed_in` | up to what they owe |\n\nPartial settlement is fine — the drawer may not hold the full amount. The wrong direction,\nmore than the balance, or a captain who is already square all answer **422** and write\nnothing. Each is a silent mistake otherwise: paying a captain who owes turns their debt\ninto a credit.\n\nThe balance is checked under a lock on the captain, so two cashiers settling the same\ncaptain at once cannot both pay.\n\n`currency` defaults to `SYP`. `reference` is the voucher or receipt number.\nRequires `captain_ledger.settle`.",
                "operationId": "captainLedgerSettle",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "direction",
                                    "amount"
                                ],
                                "properties": {
                                    "direction": {
                                        "type": "string",
                                        "example": "cash_paid_out",
                                        "enum": [
                                            "cash_paid_out",
                                            "cash_handed_in"
                                        ]
                                    },
                                    "amount": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 300,
                                        "maximum": 999999.98999999999068677425384521484375,
                                        "minimum": 0.01000000000000000020816681711721685132943093776702880859375
                                    },
                                    "currency": {
                                        "type": "string",
                                        "example": "SYP",
                                        "nullable": true,
                                        "maxLength": 3,
                                        "minLength": 3
                                    },
                                    "reference": {
                                        "type": "string",
                                        "example": "VCH-2001",
                                        "nullable": true,
                                        "maxLength": 100
                                    },
                                    "note": {
                                        "type": "string",
                                        "example": null,
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Recorded. `Model` is the new ledger line.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/CaptainLedgerEntry"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "The cash movement has been recorded."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.settle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Wrong direction for this captain, more than the balance, nothing outstanding, or invalid input.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/captains/{uuid}/ledger/adjust": {
            "post": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "Correct a captain's balance, with a reason",
                "description": "The ledger is append-only, so this is the only way a wrong entry is ever put right: not by\nediting it, but by a second line beside it that says what it corrects.\n\n`amount` is **signed** — positive credits the captain, negative debits them — because a\ncorrection is the one entry whose direction is not implied by what happened. `note` is\nrequired: a balance that moved for a reason nobody wrote down is worse than one that never\nmoved.\n\nRequires `captain_ledger.settle`.",
                "operationId": "captainLedgerAdjust",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "amount",
                                    "note"
                                ],
                                "properties": {
                                    "amount": {
                                        "description": "Signed; not zero.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 20
                                    },
                                    "note": {
                                        "type": "string",
                                        "example": "Customer paid 360, captain mis-entered 380.",
                                        "maxLength": 255,
                                        "minLength": 3
                                    },
                                    "currency": {
                                        "type": "string",
                                        "example": "SYP",
                                        "nullable": true,
                                        "maxLength": 3,
                                        "minLength": 3
                                    },
                                    "reference": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 100
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Recorded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/CaptainLedgerEntry"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.settle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No reason, or a zero amount.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/cash-hand-ins": {
            "get": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "Captains waiting to hand cash in",
                "description": "Captains who have said they are bringing the company's cash in and have not been answered\nyet, **oldest first** — the queue serves whoever has been waiting, not the largest sum.\n\n`declared_amount` is a claim and nothing more: while a row is here the captain still owes\nevery riyal of it and their balance is untouched. `Totals` is what the desk should expect\nto receive per currency, with how many captains it is spread across.\n\nRequires `captain_ledger.view`.",
                "operationId": "cashHandInQueue",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "currency",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 3,
                            "minLength": 3
                        },
                        "example": "SYP"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The queue, and what it adds up to.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/CashHandIn"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Pages.",
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Page": {
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Records": {
                                            "type": "integer",
                                            "example": 2
                                        },
                                        "Totals": {
                                            "description": "currency => {declared, captains, hand_ins}",
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/cash-hand-ins/{uuid}/confirm": {
            "post": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "The cash is in the drawer",
                "description": "**This is the call that clears the balance**, because it is the only point at which the\ncompany has the money.\n\n`amount` is what was actually counted. It defaults to the declared figure, and it is allowed\nto be less: a captain fifty short is recorded as fifty short, the ledger moves by what\narrived, and the captain keeps owing the difference. Making the two agree would only mean\nthe gap went unwritten.\n\nThe movement is written by the same service a manual hand-in goes through, so the direction\ncheck, the ceiling at the outstanding balance and the lock against two cashiers taking the\nsame cash twice all apply here unchanged. The entry it wrote comes back as\n`ledger_entry_uuid`.\n\nRequires `captain_ledger.settle` — reading the desk is not enough to move money.",
                "operationId": "cashHandInConfirm",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Hand-in UUID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "amount": {
                                        "description": "What was counted. Defaults to the declared figure.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 350,
                                        "nullable": true
                                    },
                                    "reference": {
                                        "type": "string",
                                        "example": "VCH-9001",
                                        "nullable": true,
                                        "maxLength": 100
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Received. The balance has moved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/CashHandIn"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.settle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such hand-in.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already answered — a second confirmation would take the cash twice.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A zero amount, or more than the captain owes.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/cash-hand-ins/{uuid}/decline": {
            "post": {
                "tags": [
                    "Dashboard — Cash Desk"
                ],
                "summary": "The cash never arrived",
                "description": "The captain did not come, or what they brought did not match at all. The balance is left\nexactly where it was: the captain is still holding the company's cash.\n\nA reason is required. The next person to look at that balance needs to know why the last\nattempt failed, and it is shown to the captain in their app.\n\nRequires `captain_ledger.settle`.",
                "operationId": "cashHandInDecline",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Hand-in UUID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "note"
                                ],
                                "properties": {
                                    "note": {
                                        "type": "string",
                                        "example": "The captain never came to the office.",
                                        "maxLength": 255,
                                        "minLength": 3
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Turned away. The balance is unchanged.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/CashHandIn"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing captain_ledger.settle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such hand-in.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already answered.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No reason given.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers": {
            "get": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Review queue / captain list",
                "description": "Paginated. Filters: search, status, employment_type, ownership_type, is_active. Requires `drivers.view`. Captain records use ULIDs.",
                "operationId": "captainIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Name, email, phone or national id.",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "maxLength": 255
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "pending",
                                "documents_required",
                                "approved",
                                "rejected",
                                "suspended"
                            ]
                        }
                    },
                    {
                        "name": "employment_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "employee",
                                "freelance"
                            ]
                        }
                    },
                    {
                        "name": "ownership_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "company_owned",
                                "personal"
                            ]
                        }
                    },
                    {
                        "name": "is_active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of captains.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Driver"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing/invalid page or rows.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "One captain application",
                "description": "The full application: personal data, documents, vehicle, review fields. Requires `drivers.view`.",
                "operationId": "captainShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The application.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Correct a captain's record",
                "description": "Updates the sent fields. Phone, email and national id must stay unique. Requires `drivers.update`.",
                "operationId": "captainUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "Nasser Al Otaibi",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^\\+[0-9]{8,15}$",
                                        "example": "+966500000002"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "nasser.employee@example.com",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "national_id": {
                                        "type": "string",
                                        "example": "1000000002",
                                        "maxLength": 50
                                    },
                                    "date_of_birth": {
                                        "description": "Must be before today.",
                                        "type": "string",
                                        "format": "date",
                                        "example": "1988-09-23"
                                    },
                                    "employment_type": {
                                        "type": "string",
                                        "example": "employee",
                                        "enum": [
                                            "employee",
                                            "freelance"
                                        ]
                                    },
                                    "driving_license_number": {
                                        "type": "string",
                                        "example": "DL-10002",
                                        "maxLength": 50
                                    },
                                    "driving_license_expires_at": {
                                        "description": "Must be after today.",
                                        "type": "string",
                                        "format": "date",
                                        "example": "2029-09-12"
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "Nasser Al Otaibi",
                                "phone": "+966500000002",
                                "email": "nasser.employee@example.com",
                                "national_id": "1000000002",
                                "date_of_birth": "1988-09-23",
                                "employment_type": "employee",
                                "driving_license_number": "DL-10002",
                                "driving_license_expires_at": "2029-09-12"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Record updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers/{uuid}/activation": {
            "patch": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Activate or deactivate a captain",
                "description": "Turns the account on, or off together with every session the app is signed in from. Requires `drivers.update`.",
                "operationId": "captainToggleActivation",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "State changed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers/{uuid}/approve": {
            "patch": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Approve an application",
                "description": "Approves the application. Company-owned vehicles must be handed over (the `vehicle`\nblock is required for them); personal vehicles are optional — an empty vehicle object\nis treated as \"no car sent\". Approval is final: an approved captain can no longer be\nrejected, only deactivated. Requires `drivers.review`.",
                "operationId": "captainApprove",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "vehicle": {
                                        "properties": {
                                            "plate_number": {
                                                "type": "string",
                                                "example": "AZZ-8008",
                                                "maxLength": 20
                                            },
                                            "brand": {
                                                "type": "string",
                                                "example": "GMC",
                                                "maxLength": 100
                                            },
                                            "model": {
                                                "type": "string",
                                                "example": "Terrain",
                                                "maxLength": 100
                                            },
                                            "manufacture_year": {
                                                "type": "integer",
                                                "example": 2021,
                                                "maximum": 2027,
                                                "minimum": 1950
                                            },
                                            "color": {
                                                "type": "string",
                                                "example": "red",
                                                "maxLength": 50
                                            }
                                        },
                                        "type": "object"
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "vehicle": {
                                    "plate_number": "AZZ-8008",
                                    "brand": "GMC",
                                    "model": "Terrain",
                                    "manufacture_year": 2021,
                                    "color": "red"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Application approved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.review permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already decided.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Illegal transition or missing company vehicle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers/{uuid}/reject": {
            "patch": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Reject an application",
                "description": "Turns the application down on the reason sent. A rejected captain may still be reconsidered later. Requires `drivers.review`.",
                "operationId": "captainReject",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "review_note": {
                                        "type": "string",
                                        "maxLength": 1000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Application rejected.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.review permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already decided.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Illegal transition or missing note.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/drivers/{uuid}/request-documents": {
            "patch": {
                "tags": [
                    "Dashboard — Captains"
                ],
                "summary": "Request missing documents",
                "description": "Sends the application back, naming what is missing in the note. Requires `drivers.review`.",
                "operationId": "captainRequestDocuments",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "description": "Captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "review_note": {
                                        "type": "string",
                                        "maxLength": 1000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Documents requested.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Driver"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing drivers.review permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already decided.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Illegal transition or missing note.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/cities": {
            "get": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "Every city with its districts",
                "description": "The whole tree, unpaginated: this is a map of where the company works, read as a whole by the\nscreen that edits it. A page of cities would be a page of something nobody thinks of in pages.\n\nEach city carries `districts_with_own_earning` — how many of its districts would be\noverwritten by a rate change — so the editing screen can warn before it asks, without a\nsecond request.\n\nRequires `cities.view`.",
                "operationId": "citiesIndex",
                "responses": {
                    "200": {
                        "description": "The tree.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/City"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "Add a city or a district",
                "description": "With `parent_uuid` this is a district inside that city; without it, a city.\n\n**A district left without `delivery_earning` inherits its city's**, which is the ordinary\ncase: somebody adding six districts to a city they have already priced should not type the\nsame figure six times, because five of them end up right. A **city** without one is refused —\nthere is nothing above it to inherit from, so silence would mean every delivery there earns\nnothing until somebody noticed.\n\nA district cannot be given a parent that is itself a district: the tree is two deep.\n\nRequires `cities.manage`.",
                "operationId": "citiesStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "lat",
                                    "lng",
                                    "radius_m"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "Mezzeh",
                                        "maxLength": 120
                                    },
                                    "parent_uuid": {
                                        "description": "The city this district belongs to. Omit for a city.",
                                        "type": "string",
                                        "format": "uuid",
                                        "nullable": true
                                    },
                                    "lat": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 33.50750000000000028421709430404007434844970703125
                                    },
                                    "lng": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 36.24000000000000198951966012828052043914794921875
                                    },
                                    "radius_m": {
                                        "type": "integer",
                                        "example": 1000,
                                        "maximum": 100000,
                                        "minimum": 100
                                    },
                                    "delivery_earning": {
                                        "description": "Omit on a district to follow the city's rate.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 80,
                                        "nullable": true
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "example": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Added.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/City"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A city with no rate, a third level, or a name already used in that city.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/cities/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "One area, with its districts",
                "operationId": "citiesShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The area.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/City"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such area.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "Remove an area that nothing depends on",
                "description": "Refused with `409` while a city still has districts, and refused while any delivery earning\nnames the area: money that has been paid keeps its explanation. The answer to \"we no longer\ndeliver there\" is `is_active: false`, which stops new deliveries matching it and leaves its\nhistory readable.\n\nRequires `cities.manage`.",
                "operationId": "citiesDestroy",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "string",
                                            "example": null,
                                            "nullable": true
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such area.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "It still has districts, or captains have been paid for deliveries there.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "Change an area, and decide what that does below it",
                "description": "Every field is optional; what is absent is left alone.\n\n**On a city, `delivery_earning` cascades.** Districts that have never been given a rate of\ntheir own always follow. Districts somebody set deliberately are left alone **unless**\n`overwrite_own_children` is true — and a district overwritten that way is marked as following\nthe city from then on, which is what \"overwrite\" was asked to mean.\n\n**On a district, nothing cascades upward.** Pricing a district never changes its city. That\nasymmetry is the whole point of the feature.\n\n`inherit: true` puts a district back on its city's rate. Sending it together with\n`delivery_earning` is refused rather than resolved by precedence — two different rates in one\nrequest is not a request anybody should have to remember the direction of.\n\nThe response carries `Districts`: how many followed, how many were overwritten, and how many\nkept their own rate. \"Saved\" is not an answer to a question that may have changed nine rows.\n\nRequires `cities.manage`.",
                "operationId": "citiesUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "lat": {
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "lng": {
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "radius_m": {
                                        "type": "integer",
                                        "maximum": 100000,
                                        "minimum": 100
                                    },
                                    "delivery_earning": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 70
                                    },
                                    "inherit": {
                                        "description": "Put this district back on its city's rate.",
                                        "type": "boolean",
                                        "example": false
                                    },
                                    "overwrite_own_children": {
                                        "description": "Reset districts that carry their own rate.",
                                        "type": "boolean",
                                        "example": false
                                    },
                                    "is_active": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Changed, and what it did below.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/City"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Districts": {
                                            "properties": {
                                                "followed": {
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "overwritten": {
                                                    "type": "integer",
                                                    "example": 0
                                                },
                                                "kept": {
                                                    "type": "integer",
                                                    "example": 1
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such area.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A rate and `inherit` together, or `inherit` on a city.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/delivery-earnings": {
            "get": {
                "tags": [
                    "Dashboard — Cities and earnings"
                ],
                "summary": "What deliveries have earned, and what each area cost",
                "description": "Every delivery earning, newest first, with `Totals` per currency and `ByCity` — the same\nfiltered set grouped by area, largest first, which is the reason to read this report.\n\n**The rows that earned nothing are in here on purpose.** Filter `status=unresolved` to see\nthe deliveries whose drop-off matched no area: that list is both the money nobody was paid and\nthe map of where a district is missing. `Totals.<currency>.unresolved` carries the count beside\nthe money, because a week that looks cheap because eleven deliveries never resolved is a\ndifferent problem from a quiet week.\n\n`city_uuid` on a city means **the city and every district inside it**. A filter naming a\ncaptain or an area that does not exist answers with an empty page, never with everything.\n\nNothing here is recomputed: every figure was written at the moment of delivery, and a report\nthat recalculated would be free to disagree with the balance it exists to explain.\n\nRequires `cities.view`.",
                "operationId": "deliveryEarningsIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 15
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "captain_uuid",
                        "in": "query",
                        "description": "Captain ULID.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "city_uuid",
                        "in": "query",
                        "description": "A city (with its districts) or one district.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "credited",
                                "unresolved"
                            ]
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "description": "Inclusive: the whole day it names.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of earnings, its totals, and the same set by area.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DeliveryEarning"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Pages.",
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Page": {
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Records": {
                                            "type": "integer",
                                            "example": 3
                                        },
                                        "Totals": {
                                            "description": "currency => {earned, deliveries, unresolved}",
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "object"
                                            }
                                        },
                                        "ByCity": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "city": {
                                                        "description": "Null names the unresolved bucket.",
                                                        "type": "string",
                                                        "nullable": true
                                                    },
                                                    "parent": {
                                                        "type": "string",
                                                        "nullable": true
                                                    },
                                                    "currency": {
                                                        "type": "string"
                                                    },
                                                    "earned": {
                                                        "type": "number",
                                                        "format": "float"
                                                    },
                                                    "deliveries": {
                                                        "type": "integer"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing cities.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A window that ends before it starts, or an unknown status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/delivery-fee-tiers": {
            "get": {
                "tags": [
                    "Dashboard — Delivery pricing"
                ],
                "summary": "Every pricing ladder",
                "description": "The company ladder first, then each store's, cheapest band first inside either.\n\nUnpaginated on purpose: a ladder is read whole or not at all, and a page of one is a page of\nsomething nobody thinks of in pages.\n\nRequires `delivery_fees.view`.",
                "operationId": "deliveryFeeTiersIndex",
                "responses": {
                    "200": {
                        "description": "Every band there is.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DeliveryFeeTier"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing delivery_fees.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Delivery pricing"
                ],
                "summary": "Add a band to a ladder",
                "description": "With `store_uuid` the band joins that store's own ladder, which then prices **all** of its\norders — a store with one negotiated band does not fall back to the company ladder for the\nbaskets that band does not cover, because a price assembled from two documents is one nobody\nagreed to. Without it, the band joins the company ladder.\n\n`max_goods_value` is optional: leaving it out means \"and above\", which is where free delivery\nusually sits. The floor is inclusive and the ceiling exclusive, so `0–100,000` and\n`100,000–300,000` meet without both covering 100,000.\n\n**Overlapping bands answer `409`**, naming the band they clash with. Two bands covering one\norder value would make the fee a coin toss, and the alternative — a priority column — is where\na pricing table stops being readable and starts being something you have to simulate.\n\nRequires `delivery_fees.manage`.",
                "operationId": "deliveryFeeTiersStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "min_goods_value",
                                    "fee"
                                ],
                                "properties": {
                                    "store_uuid": {
                                        "description": "Omit for the company ladder.",
                                        "type": "string",
                                        "format": "uuid",
                                        "example": null,
                                        "nullable": true
                                    },
                                    "min_goods_value": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 3000
                                    },
                                    "max_goods_value": {
                                        "description": "Omit for \"and above\".",
                                        "type": "number",
                                        "format": "float",
                                        "example": null,
                                        "nullable": true
                                    },
                                    "fee": {
                                        "description": "Zero is free delivery.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 0
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "example": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Added.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/DeliveryFeeTier"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing delivery_fees.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The range overlaps an existing band on the same ladder.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A ceiling at or below the floor, or an unknown store.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/delivery-fee-tiers/{uuid}": {
            "delete": {
                "tags": [
                    "Dashboard — Delivery pricing"
                ],
                "summary": "Retire a band",
                "description": "Allowed even where orders were priced by it. They keep the fee they were charged as a number of\ntheir own and only their pointer to the rule goes null, so retiring last season's offer never\nrewrites what a store was billed.\n\nRequires `delivery_fees.manage`.",
                "operationId": "deliveryFeeTiersDestroy",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Retired.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "string",
                                            "example": null,
                                            "nullable": true
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing delivery_fees.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such band.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Dashboard — Delivery pricing"
                ],
                "summary": "Change a band",
                "description": "Everything is optional; what is absent is left alone. The ladder a band sits on is **not**\neditable — moving one between a store and the company would be two different negotiations in a\nsingle request.\n\n`clear_max: true` opens the band up to \"and above\". It exists because a null in JSON cannot be\ntold apart from a field nobody sent, so removing a ceiling needs a word of its own. Sending it\ntogether with `max_goods_value` is refused rather than resolved by precedence.\n\nThe overlap check runs again on the new range, ignoring this band itself.\n\nRequires `delivery_fees.manage`.",
                "operationId": "deliveryFeeTiersUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "min_goods_value": {
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "max_goods_value": {
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "clear_max": {
                                        "description": "Remove the ceiling: this band runs to infinity.",
                                        "type": "boolean",
                                        "example": false
                                    },
                                    "fee": {
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "is_active": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Changed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/DeliveryFeeTier"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing delivery_fees.manage.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such band.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The new range overlaps another band.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A ceiling at or below the floor, or both a ceiling and `clear_max`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/dispatch/settings": {
            "get": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "Dispatch settings",
                "description": "The business values the captain dispatch algorithm runs on.\n\n- `editable`: the values the operations team may change — the handoff buffers and the\n  batch detour limit — each with the value that applies now, its config default, the\n  range it may be set to, and whether it was overridden (by whom, when).\n- `effective`: every value the algorithm currently uses, overrides applied.\n\nOverrides are cached for 60 seconds; a change made through the PUT applies at once.\nRequires `dispatch.view`.",
                "operationId": "dispatchSettingsShow",
                "responses": {
                    "200": {
                        "description": "The settings.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "editable": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "key": {
                                                                "type": "string",
                                                                "example": "offer_timeout_s",
                                                                "enum": [
                                                                    "handoff_buffer_prepaid_min",
                                                                    "handoff_buffer_cod_min",
                                                                    "max_batch_detour_min",
                                                                    "offer_timeout_s"
                                                                ]
                                                            },
                                                            "label": {
                                                                "type": "string",
                                                                "example": "Maximum batch detour (minutes)"
                                                            },
                                                            "value": {
                                                                "type": "number",
                                                                "example": 6
                                                            },
                                                            "default": {
                                                                "type": "number",
                                                                "example": 6
                                                            },
                                                            "min": {
                                                                "type": "number",
                                                                "example": 0
                                                            },
                                                            "max": {
                                                                "type": "number",
                                                                "example": 20
                                                            },
                                                            "overridden": {
                                                                "type": "boolean",
                                                                "example": false
                                                            },
                                                            "updated_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true
                                                            },
                                                            "updated_by": {
                                                                "type": "string",
                                                                "example": null,
                                                                "nullable": true
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                },
                                                "effective": {
                                                    "properties": {
                                                        "max_active_orders": {
                                                            "type": "integer",
                                                            "example": 2
                                                        },
                                                        "radius_steps_km": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "number"
                                                            },
                                                            "example": [
                                                                5,
                                                                8,
                                                                12
                                                            ]
                                                        },
                                                        "top_n": {
                                                            "type": "integer",
                                                            "example": 7
                                                        },
                                                        "detour_index": {
                                                            "type": "number",
                                                            "example": 1.3000000000000000444089209850062616169452667236328125
                                                        },
                                                        "handoff_buffer_prepaid_min": {
                                                            "type": "number",
                                                            "example": 3
                                                        },
                                                        "handoff_buffer_cod_min": {
                                                            "type": "number",
                                                            "example": 5
                                                        },
                                                        "gps_aging_min": {
                                                            "type": "number",
                                                            "example": 1.5
                                                        },
                                                        "gps_stale_min": {
                                                            "type": "number",
                                                            "example": 3
                                                        },
                                                        "routing_timeout_ms": {
                                                            "type": "integer",
                                                            "example": 1000
                                                        },
                                                        "suggestion_cache_ttl_s": {
                                                            "type": "integer",
                                                            "example": 75
                                                        },
                                                        "max_batch_detour_min": {
                                                            "type": "number",
                                                            "example": 6
                                                        },
                                                        "offer_timeout_s": {
                                                            "description": "How long an offered order waits for the captain to answer.",
                                                            "type": "integer",
                                                            "example": 60
                                                        },
                                                        "tie_break_band_min": {
                                                            "type": "number",
                                                            "example": 2
                                                        },
                                                        "reroute_deviation_m": {
                                                            "type": "integer",
                                                            "example": 250
                                                        },
                                                        "reroute_deviation_s": {
                                                            "type": "integer",
                                                            "example": 30
                                                        },
                                                        "assign_lock_ttl_s": {
                                                            "type": "integer",
                                                            "example": 30
                                                        },
                                                        "ping_moving_s": {
                                                            "type": "integer",
                                                            "example": 8
                                                        },
                                                        "ping_stationary_s": {
                                                            "type": "integer",
                                                            "example": 45
                                                        },
                                                        "moving_speed_mps": {
                                                            "type": "number",
                                                            "example": 2
                                                        },
                                                        "gps_history_flush_batch": {
                                                            "type": "integer",
                                                            "example": 1000
                                                        },
                                                        "gps_history_retention_days": {
                                                            "type": "integer",
                                                            "example": 30
                                                        },
                                                        "routing_engine": {
                                                            "type": "string",
                                                            "example": "fake",
                                                            "enum": [
                                                                "fake",
                                                                "google",
                                                                "osrm"
                                                            ]
                                                        },
                                                        "batch_rejected_policy": {
                                                            "type": "string",
                                                            "example": "rank_lower",
                                                            "enum": [
                                                                "rank_lower",
                                                                "exclude"
                                                            ]
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing dispatch.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "Change dispatch settings",
                "description": "Overrides the editable values sent (JSON); a key left out is not touched, a key sent as\n`null` is reset to its config default. At least one editable key must be sent, each\nwithin its range. The answer is the same body as the GET, with the new values applied.\nRequires `dispatch.settings`.",
                "operationId": "dispatchSettingsUpdate",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "handoff_buffer_prepaid_min": {
                                        "type": "number",
                                        "example": 3,
                                        "nullable": true,
                                        "maximum": 15,
                                        "minimum": 0
                                    },
                                    "handoff_buffer_cod_min": {
                                        "type": "number",
                                        "example": 5,
                                        "nullable": true,
                                        "maximum": 15,
                                        "minimum": 0
                                    },
                                    "max_batch_detour_min": {
                                        "type": "number",
                                        "example": 7,
                                        "nullable": true,
                                        "maximum": 20,
                                        "minimum": 0
                                    },
                                    "offer_timeout_s": {
                                        "description": "Seconds a captain has to accept. Bounded at both ends: under the floor an offer is taken back from a captain still reaching for their phone — and that counts as a refusal against them — while over the ceiling a customer waits a quarter of an hour on somebody who will never answer.",
                                        "type": "integer",
                                        "example": 120,
                                        "nullable": true,
                                        "maximum": 900,
                                        "minimum": 30
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Settings updated; the body is the GET body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "object"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "Dispatch settings updated."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing dispatch.settings permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No editable key sent, or a value out of its range.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/dispatch/live": {
            "get": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "Where the fleet is, right now",
                "description": "Every approved captain who is on duty, with their last known position, what they are\ncarrying, and — the field that matters most — **how old that position is**.\n\n**Not paginated, deliberately.** A map showing page one of the captains is worse than no\nmap: a dispatcher cannot tell whether an empty quarter of the city is really empty or\nsimply on page two.\n\n### Read `gps_state` before you trust the coordinates\n\nA dot looks equally confident whether the fix is four seconds or forty minutes old, and a\ndispatcher who cannot tell the difference will route around a captain who left an hour\nago — or route *to* one. The thresholds are the dispatch algorithm's own\n(`gps_aging_min`, `gps_stale_min`), so this screen and the ranking agree about what\n\"stale\" means.\n\n| State | Means |\n|---|---|\n| `fresh` | reporting normally |\n| `aging` | past the algorithm's aging threshold; still usable |\n| `stale` | the algorithm is already discounting them |\n| `never` | on duty and **has never reported at all** — their app is not sending |\n\n`never` is separate from `stale` because the two need different actions: a stale captain\nwas working and something happened; one who never reported is a support call.\n\nCaptains with no position **are included**. Hiding them would conceal the most\ninteresting row on the screen.\n\n### Two details\n\n`age_seconds` is measured on the **server's** clock. Do not subtract `captured_at` from\nthe browser's time — a laptop that has been asleep is routinely minutes out.\n\n`active_orders` is what the captain is actually carrying, counted from the orders. It is\nnot `drivers.active_orders`, which is a reservation counter that legitimately runs ahead\nof reality for a moment during assignment.\n\nPoll it; roughly every ten seconds matches how often a moving captain reports. Positions\nare frequent and worth pulling. The `dispatch.dashboard` websocket channel carries *route*\nchanges, which are rare and worth pushing.\n\nRequires `dispatch.view`.",
                "operationId": "dispatchLiveFleet",
                "responses": {
                    "200": {
                        "description": "The fleet.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "as_of": {
                                                    "description": "The server's clock when the snapshot was taken.",
                                                    "type": "string",
                                                    "format": "date-time"
                                                },
                                                "captains": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "uuid": {
                                                                "description": "The captain ULID.",
                                                                "type": "string"
                                                            },
                                                            "name": {
                                                                "type": "string"
                                                            },
                                                            "phone": {
                                                                "type": "string",
                                                                "nullable": true
                                                            },
                                                            "lat": {
                                                                "description": "Null when they have never reported.",
                                                                "type": "number",
                                                                "nullable": true
                                                            },
                                                            "lng": {
                                                                "type": "number",
                                                                "nullable": true
                                                            },
                                                            "accuracy": {
                                                                "description": "Metres, as the phone reported it.",
                                                                "type": "number",
                                                                "nullable": true
                                                            },
                                                            "captured_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true
                                                            },
                                                            "age_seconds": {
                                                                "description": "How old the fix is, on the server's clock.",
                                                                "type": "integer",
                                                                "nullable": true
                                                            },
                                                            "gps_state": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "fresh",
                                                                    "aging",
                                                                    "stale",
                                                                    "never"
                                                                ]
                                                            },
                                                            "on_break": {
                                                                "description": "Online, but not taking new orders.",
                                                                "type": "boolean"
                                                            },
                                                            "last_seen_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true
                                                            },
                                                            "active_orders": {
                                                                "description": "What they are carrying, not what is reserved.",
                                                                "type": "integer"
                                                            },
                                                            "vehicle": {
                                                                "properties": {
                                                                    "plate_number": {
                                                                        "type": "string"
                                                                    },
                                                                    "type": {
                                                                        "type": "string",
                                                                        "nullable": true
                                                                    }
                                                                },
                                                                "type": "object",
                                                                "nullable": true
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                },
                                                "summary": {
                                                    "description": "Every key present even at zero — a tile that vanishes reads as \"nothing to check\".",
                                                    "properties": {
                                                        "on_duty": {
                                                            "type": "integer"
                                                        },
                                                        "fresh": {
                                                            "type": "integer"
                                                        },
                                                        "aging": {
                                                            "type": "integer"
                                                        },
                                                        "stale": {
                                                            "type": "integer"
                                                        },
                                                        "never_reported": {
                                                            "type": "integer"
                                                        },
                                                        "on_break": {
                                                            "type": "integer"
                                                        },
                                                        "carrying": {
                                                            "type": "integer"
                                                        },
                                                        "idle": {
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing `dispatch.view`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/dispatch/kpis": {
            "get": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "What the dispatch algorithm did over a window",
                "description": "**Every rate is nullable, and that is the most important thing on this endpoint.** A rate\nwith nothing in its denominator is *unknown*, not zero: a day with no assignments has no\nbatch rate, and drawing `0%` would report a fleet that never batches instead of a fleet\nthat did nothing. Render `null` as \"—\". A screen cannot un-see a number it was given.\n\nRates are **fractions between 0 and 1**, not percentages. One place decides how to phrase\na number for a human, and it is not this one.\n\nThe figures come from two sources on purpose: counters answer \"how many\", which is what\nevery rate needs and what a table of millions of rows cannot answer cheaply; the\nsuggestion log answers \"how long\", because a latency percentile needs the individual\nmeasurements and a counter has thrown them away.\n\nThe window is capped. A `from` reaching past the counters' retention is **refused rather\nthan truncated** — a partial answer that looked complete would be worse than an error.\n\nRequires `dispatch.view`.",
                "operationId": "dispatchKpis",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "description": "Defaults to the start of the retained window.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "description": "Defaults to today. Cannot be in the future.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The KPIs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "from": {
                                                    "type": "string",
                                                    "format": "date"
                                                },
                                                "to": {
                                                    "type": "string",
                                                    "format": "date"
                                                },
                                                "suggestion_to_display": {
                                                    "description": "How long the system took to build a list — p50/p95 and a count.",
                                                    "type": "object"
                                                },
                                                "display_to_assign": {
                                                    "description": "How long the dispatcher then took to choose. Measures the human, not the machine.",
                                                    "type": "object"
                                                },
                                                "first_suggestion_acceptance_rate": {
                                                    "description": "Of assignments made from a list, the share that took its first pick.",
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "batch_rate": {
                                                    "description": "Of all assignments, the share that joined a route rather than starting one.",
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "assignment_failure_rate": {
                                                    "description": "Of all attempts, the share refused — no capacity, or a captain no longer eligible.",
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "routing_fallback_rate": {
                                                    "description": "Of all routing calls, the share the engine did not answer.",
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "routing_elements_per_assignment": {
                                                    "description": "Billable map units per order assigned.",
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "maps_cost_per_delivery": {
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "recomputes_per_delivery": {
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "totals": {
                                                    "description": "The raw counters the rates were derived from.",
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The window reaches past what the counters retain.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/dispatch/drivers/{driver}/route-plan": {
            "get": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "A captain's live route",
                "description": "The stops in the order the captain is told to do them, with the line to draw on a map.\n\n**Read `degraded` before trusting the times.** True means the routing engine could not\nanswer: the stops and their order are still right, the times are straight-line estimates,\nand `polyline` is empty. Drawing estimates as though they were road times is how a\ndispatcher promises a customer something nobody can keep.\n\n`version` matters — pass it back when reordering, or a stale screen will overwrite a\nnewer plan.\n\nThe identifier is a **ULID**, not a uuid: `Driver` uses `HasUlids`.\n\nRequires `dispatch.view`.",
                "operationId": "dispatchRoutePlanShow",
                "parameters": [
                    {
                        "name": "driver",
                        "in": "path",
                        "description": "The captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The plan.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RoutePlan"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No captain, or no current plan.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/dispatch/drivers/{driver}/route-plan/reorder": {
            "patch": {
                "tags": [
                    "Dashboard — Dispatch"
                ],
                "summary": "Change the order of a captain's stops",
                "description": "Send **every** stop key, in the new order — `pickup:{id}` and `dropoff:{id}`, exactly as\nthe `key` field of each stop gives them. A partial list is refused, because it would be\nambiguous about whether the missing stops were dropped or merely not mentioned.\n\n`version` is the plan version you were looking at. If the plan has moved on since — a new\norder was assigned, or the captain advanced — this answers **409** rather than\noverwriting it. That is the whole point: two dispatchers on the same captain must not be\nable to silently undo each other.\n\nA dropoff cannot be ordered before its own pickup.\n\nRequires **`orders.assign`**, not `dispatch.settings`: changing what a captain is told to\ndo next is the same authority as handing them an order in the first place.",
                "operationId": "dispatchRoutePlanReorder",
                "parameters": [
                    {
                        "name": "driver",
                        "in": "path",
                        "description": "The captain ULID.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "version",
                                    "stops"
                                ],
                                "properties": {
                                    "version": {
                                        "description": "The version you were shown.",
                                        "type": "integer",
                                        "example": 4,
                                        "minimum": 1
                                    },
                                    "stops": {
                                        "description": "Every stop key, in the new order.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "pattern": "^(pickup|dropoff):\\d+$"
                                        },
                                        "example": [
                                            "pickup:12",
                                            "pickup:13",
                                            "dropoff:44",
                                            "dropoff:45"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Reordered, and pushed to the captain.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RoutePlan"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The plan moved on since that version.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Stops missing, duplicated, or a dropoff before its pickup.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/integration/webhooks": {
            "get": {
                "tags": [
                    "Dashboard — Store integration"
                ],
                "summary": "Every callback we have tried to send",
                "description": "The answer to *\"did you tell them?\"*, with the raw payload we sent and whatever their\nendpoint answered.\n\n`Summary` counts deliveries by status, and **every status is present even at zero** — a\ndashboard tile reading \"—\" when the true answer is \"none\" tells somebody checking for\nbreakage exactly the wrong thing. Read it like this:\n\n| Piling up | Means |\n|---|---|\n| `pending` | no queue worker is running. `php artisan queue:work` |\n| `failed` | retrying; `next_attempt_at` says when |\n| `dropped` | six attempts exhausted. Nothing more is coming, and a human has to replay it |\n\nRequires `integration.view`.",
                "operationId": "integrationWebhookIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "sent",
                                "failed",
                                "dropped"
                            ]
                        }
                    },
                    {
                        "name": "event",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "example": "order.delivered"
                    },
                    {
                        "name": "order_uuid",
                        "in": "query",
                        "description": "Everything sent about one order.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of deliveries, plus the status summary.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/WebhookDelivery"
                                            }
                                        },
                                        "Summary": {
                                            "properties": {
                                                "pending": {
                                                    "type": "integer",
                                                    "example": 0
                                                },
                                                "sent": {
                                                    "type": "integer",
                                                    "example": 128
                                                },
                                                "failed": {
                                                    "type": "integer",
                                                    "example": 1
                                                },
                                                "dropped": {
                                                    "type": "integer",
                                                    "example": 0
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing `integration.view`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/integration/webhooks/{delivery}": {
            "get": {
                "tags": [
                    "Dashboard — Store integration"
                ],
                "summary": "One delivery, with the bytes we sent",
                "description": "The `payload` is kept in full because the first disagreement with an external partner is\nalways \"we sent it\" — and without the bytes there is nothing to settle it with.\n\nRequires `integration.view`.",
                "operationId": "integrationWebhookShow",
                "parameters": [
                    {
                        "name": "delivery",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The delivery.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookDelivery"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such delivery.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/integration/webhooks/{delivery}/replay": {
            "post": {
                "tags": [
                    "Dashboard — Store integration"
                ],
                "summary": "Send it again",
                "description": "The case this exists for is a store that was down past our six attempts: the event is\n`dropped`, nothing more is coming, and somebody has to say \"try now\".\n\nIt **resets** the attempt count rather than continuing it — the previous run is over, and\nwhat was asked for is a fresh set of retries starting at ten seconds.\n\nThe store's handler will see the event a second time. That is what `event_id` is for, and\ntheir contract requires them to deduplicate on it.\n\nRequires `integration.replay`, which `integration.view` does not grant: reading the log\nand changing what another company believes are different acts.",
                "operationId": "integrationWebhookReplay",
                "parameters": [
                    {
                        "name": "delivery",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Queued again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookDelivery"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing `integration.replay`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/notifications": {
            "get": {
                "tags": [
                    "Dashboard — Notifications"
                ],
                "summary": "The notifications for the signed-in admin",
                "description": "Newest first, and only this admin's own.\n\n`title` and `message` arrive **already translated** into whatever `Accept-Language` asked\nfor, so a screen renders them directly. Branch on `type` and `group`, never on the text.\n\nRequires `notifications.view`.",
                "operationId": "notificationIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "group",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "order",
                                "vehicle",
                                "application",
                                "system"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of notifications.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AdminNotification"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/notifications/unread-count": {
            "get": {
                "tags": [
                    "Dashboard — Notifications"
                ],
                "summary": "How many are unread",
                "description": "The number for the badge. Cheap enough to poll. Requires `notifications.view`.",
                "operationId": "notificationUnreadCount",
                "responses": {
                    "200": {
                        "description": "The count.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "count": {
                                                    "type": "integer",
                                                    "example": 3
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/notifications/{uuid}/read": {
            "post": {
                "tags": [
                    "Dashboard — Notifications"
                ],
                "summary": "Mark one as read",
                "description": "Only the caller's own. Another admin's notification answers 404 — read state belongs to\nthe person, not to the event.\n\nRequires `notifications.read`.",
                "operationId": "notificationMarkRead",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Marked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AdminNotification"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not one of yours.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/notifications/read-all": {
            "post": {
                "tags": [
                    "Dashboard — Notifications"
                ],
                "summary": "Mark every one of mine as read",
                "description": "Affects only the caller. Requires `notifications.read`.",
                "operationId": "notificationReadAll",
                "responses": {
                    "200": {
                        "description": "All marked."
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders": {
            "get": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Delivery orders, a page at a time",
                "description": "Filters: search (order number), status. Requires `orders.view`. Orders use UUIDs. The list can be read open or pre-filtered to one status.",
                "operationId": "orderIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Order number.",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "maxLength": 255
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "pending",
                                "assigned",
                                "picked_up",
                                "on_the_way",
                                "delivered",
                                "delivery_failed"
                            ]
                        }
                    },
                    {
                        "name": "items_mismatch",
                        "in": "query",
                        "description": "1 = only orders whose pickup item count did not match the order.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of orders.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Order"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing/invalid page or rows.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Open an order for delivery",
                "description": "A fake order the back office creates until the live third party integration starts\nfeeding the system (Feature 04 MVP). It writes the same fields the integration will.\nThe pickup/dropoff coordinates are optional but each pair stays intact: a latitude\nwithout its longitude is refused rather than half-recorded. Requires `orders.create`.",
                "operationId": "orderStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "customer_name",
                                    "pickup_address",
                                    "dropoff_address"
                                ],
                                "properties": {
                                    "customer_name": {
                                        "type": "string",
                                        "example": "Khalid Al Ghamdi",
                                        "maxLength": 255
                                    },
                                    "customer_phone": {
                                        "type": "string",
                                        "example": "+966500000101",
                                        "nullable": true,
                                        "maxLength": 30
                                    },
                                    "pickup_address": {
                                        "type": "string",
                                        "example": "Store 12, Granada Mall, Riyadh",
                                        "maxLength": 255
                                    },
                                    "dropoff_address": {
                                        "type": "string",
                                        "example": "Olaya Street, Riyadh",
                                        "maxLength": 255
                                    },
                                    "pickup_lat": {
                                        "type": "number",
                                        "example": 24.803625499999998993416738812811672687530517578125,
                                        "nullable": true,
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "pickup_lng": {
                                        "type": "number",
                                        "example": 46.69935459999999949332050164230167865753173828125,
                                        "nullable": true,
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "dropoff_lat": {
                                        "type": "number",
                                        "example": 24.6887535999999983005182002671062946319580078125,
                                        "nullable": true,
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "dropoff_lng": {
                                        "type": "number",
                                        "example": 46.680810600000000931686372496187686920166015625,
                                        "nullable": true,
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "customer_note": {
                                        "description": "What the customer asked for; shown to the captain.",
                                        "type": "string",
                                        "example": "Call on arrival.",
                                        "nullable": true,
                                        "maxLength": 1000
                                    },
                                    "note": {
                                        "description": "Internal note for the operations team; never shown to the captain.",
                                        "type": "string",
                                        "example": "Repeat customer.",
                                        "nullable": true,
                                        "maxLength": 1000
                                    },
                                    "fee": {
                                        "type": "number",
                                        "example": 18.5,
                                        "nullable": true,
                                        "minimum": 0
                                    },
                                    "currency": {
                                        "type": "string",
                                        "example": "SYP",
                                        "maxLength": 10
                                    },
                                    "payment_method": {
                                        "type": "string",
                                        "example": "cash_on_delivery",
                                        "enum": [
                                            "cash_on_delivery",
                                            "prepaid"
                                        ]
                                    },
                                    "amount_to_collect": {
                                        "description": "Required for cash_on_delivery; ignored for prepaid.",
                                        "type": "number",
                                        "example": 92.5,
                                        "nullable": true,
                                        "minimum": 0
                                    },
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "required": [
                                                "name",
                                                "quantity"
                                            ],
                                            "properties": {
                                                "name": {
                                                    "type": "string",
                                                    "maxLength": 255
                                                },
                                                "quantity": {
                                                    "type": "integer",
                                                    "maximum": 999,
                                                    "minimum": 1
                                                },
                                                "unit_price": {
                                                    "type": "number",
                                                    "nullable": true,
                                                    "minimum": 0
                                                },
                                                "note": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "maxLength": 255
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "maxItems": 50
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "customer_name": "Khalid Al Ghamdi",
                                "customer_phone": "+966500000101",
                                "pickup_address": "Store 12, Granada Mall, Riyadh",
                                "dropoff_address": "Olaya Street, Riyadh",
                                "pickup_lat": 24.803625499999998993416738812811672687530517578125,
                                "pickup_lng": 46.69935459999999949332050164230167865753173828125,
                                "dropoff_lat": 24.6887535999999983005182002671062946319580078125,
                                "dropoff_lng": 46.680810600000000931686372496187686920166015625,
                                "note": "Call on arrival.",
                                "fee": 18.5,
                                "currency": "SYP"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Order opened.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Order"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.create permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "One order with items, captain and timeline",
                "description": "Requires `orders.view`. Orders use UUIDs.",
                "operationId": "orderShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a089d1-9dc5-7207-b8ec-928fa322e342"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The order.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Order"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/{uuid}/captains": {
            "get": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Ranked captain suggestions for an order",
                "description": "The captains worth putting this order in front of, best first, with every number that\ndecided the order they are in. It is a suggestion only — the dispatcher picks who\ncarries it — so it sits on the same `orders.assign` permission as the assignment that\nfollows it.\n\n**Busy captains are included.** A captain finishing a delivery two streets from the\npickup often beats an idle one across town, so each row is priced on an *adjusted ETA*:\nthe time left on their current delivery, plus a handoff buffer, plus the road time from\nthere to this pickup. An idle captain simply has the first two at zero. `state` says\nwhich kind of captain a row is, and `reasons` says it in words, already translated.\n\nNote that the assignment endpoint is stricter than this list: until stacking ships it\nstill refuses a busy captain, so a name shown here can come back `422`.\n\n**The list survives a maps outage.** When the routing engine times out or refuses, the\nlist is still returned, ranked on straight-line estimates, with `ranking_degraded: true`,\na `degraded_reason`, and `eta_estimated: true` on every row whose time was guessed. This\nendpoint does not fail because maps did.\n\n**An empty list is an answer.** Nobody eligible, nobody within the widest search radius,\nor everybody set aside for a GPS point too old to trust all return `200` with\n`candidates: []` and a `no_candidates_reason` to show the dispatcher.\n\nEvery response is written to the Suggestion Log; `suggestion_uuid` is that entry, so any\nlist a dispatcher saw can be explained afterwards.",
                "operationId": "orderCaptainSuggestions",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a089d1-9dc5-7207-b8ec-928fa322e342"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The ranked suggestions, possibly empty.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/SuggestionList"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.assign permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The order has no pickup that can be placed on a map.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/{uuid}/assign": {
            "patch": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Hand the order to a captain",
                "description": "Hands the order to the captain the dispatcher picked, identified by ULID. Requires\n`orders.assign`.\n\n**A captain carrying an order can be given another.** Up to `max_active_orders` (2 by\ndefault), which is what makes the batching the suggestion list proposes actually possible.\n\n**Expect `409`, and handle it.** The dispatcher confirms from a list that was true when it\nwas drawn, so between the two the captain may have been taken by somebody else, filled up,\nor gone off duty. The capacity is taken by a single conditional statement, so two\ndispatchers cannot both succeed — the one who loses gets `409` with a `MessageDebug.reason`\nsaying which happened:\n\n- `locked` — another dispatcher is confirming this captain right now; retry in a moment.\n- `at_capacity` — the captain filled up; ask for a fresh list and choose again.\n- `not_eligible` — the captain went offline, started a break, or was suspended; ask for a\n  fresh list.\n\n`locked` is worth a retry; the other two are not, and the screen should refresh the\nsuggestions instead.\n\nSending `suggestion_uuid` and `rank` records which list the captain was chosen from and\nwhere they sat on it. Both are optional — an order assigned from a phone call has neither\n— but sending them is what lets anyone ask afterwards whether dispatchers take the\nranking's first pick. An unknown `suggestion_uuid` is recorded as no list rather than\nrefused: a missing statistic must never stop a captain getting their order.",
                "operationId": "orderAssign",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a089d1-9dc5-7207-b8ec-928fa322e342"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "driver_uuid"
                                ],
                                "properties": {
                                    "driver_uuid": {
                                        "description": "The captain's ULID.",
                                        "type": "string",
                                        "example": "01m24x34bzfbh7resdmkm55mmq"
                                    },
                                    "suggestion_uuid": {
                                        "description": "The suggestion list the captain was chosen from, when there was one.",
                                        "type": "string",
                                        "format": "uuid",
                                        "example": "01a0b389-019d-7a5c-9f7e-3d1b0c2a4e77",
                                        "nullable": true
                                    },
                                    "rank": {
                                        "description": "The captain's place on that list. 1 is the top suggestion.",
                                        "type": "integer",
                                        "example": 1,
                                        "nullable": true,
                                        "minimum": 1
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "driver_uuid": "01m24x34bzfbh7resdmkm55mmq",
                                "suggestion_uuid": "01a0b389-019d-7a5c-9f7e-3d1b0c2a4e77",
                                "rank": 1
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Order handed over.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Order"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.assign permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order or captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The captain could not take the order after all — held by another dispatcher, full, or off duty. MessageDebug.reason says which.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Status": {
                                            "type": "boolean",
                                            "example": false
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "This captain filled up while the list was open. Refresh the suggestions and choose again."
                                        },
                                        "MessageDebug": {
                                            "properties": {
                                                "reason": {
                                                    "type": "string",
                                                    "example": "at_capacity",
                                                    "enum": [
                                                        "locked",
                                                        "at_capacity",
                                                        "not_eligible"
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing or malformed driver_uuid, or the order cannot leave its current status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/{uuid}/assign-enforced": {
            "patch": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Direct an employee captain: assigned and accepted in one move",
                "description": "The same hand-over as `assign`, without the captain's answer. The order is assigned and\naccepted together, no offer deadline is written, and nothing is queued to take it back.\n\n**Employee captains only** — `422` for a freelance one. A freelancer's arrangement is that\nthey may refuse, and a company that can force work on them is not using freelancers. The\nsuggestion list says which arrangement each captain is on (`captain.employment_type`), so a\nscreen can offer this only where it will work.\n\nThe order still passes through `assigned` internally, because that is the transition that\nrecomputes the captain's route and puts the order on their phone. The timeline therefore shows\nboth steps, and **the accepted step carries the manager as its actor** rather than pretending\nthe captain answered.\n\nRequires `orders.assign_enforced`, which is separate from `orders.assign`: offering work and\ndirecting it are different authorities.",
                "operationId": "ordersAssignEnforced",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "driver_uuid"
                                ],
                                "properties": {
                                    "driver_uuid": {
                                        "description": "The captain ULID.",
                                        "type": "string",
                                        "example": "01m24x34bzfbh7resdmkm55mmq"
                                    },
                                    "suggestion_uuid": {
                                        "description": "The list this captain was chosen from, for the KPIs.",
                                        "type": "string",
                                        "format": "uuid",
                                        "nullable": true
                                    },
                                    "rank": {
                                        "description": "Their row on that list.",
                                        "type": "integer",
                                        "nullable": true,
                                        "minimum": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order, already accepted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Order"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "The order was assigned to the captain, who does not need to accept it."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.assign_enforced.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order or captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The captain is full, or no longer eligible.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A freelance captain, or an order that cannot be assigned from its current status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/{uuid}/cancel": {
            "post": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Call the order off",
                "description": "Ends the order, for the reason given. **Terminal** — a cancelled order cannot be revived,\nreassigned or delivered.\n\nA named POST rather than a status field on an update, because cancelling is not an edit.\nIt writes a timeline entry naming the admin who did it, and **hands back the carrying\ncaptain's capacity** in the same transaction that moves the status, so the captain becomes\nassignable again at once. An order with no captain simply releases nothing.\n\n**Its own permission.** `orders.cancel`, not `orders.assign` — somebody who may hand work\nout is not by that fact somebody who may call it off.\n\n`reason` is required. A cancelled order with no reason is unanswerable later: to the store\nthat placed it, to the captain who lost the job, and to whoever asks why the numbers moved.\n\nAnswers **422** if the order has already ended — a delivered order cannot be un-delivered\nby cancelling it.\n\nCaptains cannot reach this. A captain who cannot take an order **declines** it\n(`POST /api/driver/orders/{uuid}/decline`), which returns it to the pool for somebody else\nrather than ending it; after the pickup they use `failed`.",
                "operationId": "dashboardOrderCancel",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "01a089d1-9dc5-7207-b8ec-928fa322e342"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "type": "string",
                                        "example": "Customer changed their mind.",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "reason": "Customer changed their mind."
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Order cancelled; any carrying captain is free again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Order"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "The order has been cancelled.",
                                            "nullable": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.cancel permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No reason given, or the order has already ended.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/orders/awaiting-collection": {
            "get": {
                "tags": [
                    "Dashboard — Orders"
                ],
                "summary": "Deliveries that cannot be assigned yet, longest block first",
                "description": "Wrapped orders whose goods have not reached the wrapping shop yet.\n\nSome stores have their goods wrapped before delivery. Such an order is **two rows**: a\ncollection leg that gathers the goods from the suppliers and leaves them with the\nwrapper, and a delivery leg — the store's own order — that collects the finished parcel\nand takes it to the customer. The first captain is released as soon as they hand the\ngoods over, which is why these are two orders rather than one.\n\nThe delivery leg sits in ordinary `pending` the whole time. It is **not** given a status\nof its own, because whether its parcel is ready is already recorded completely by the\ncollection leg: a second copy on this row would be free to drift, and would need\nsomebody to press a button to restate what the system already knows. Instead, assignment\nis refused with **409** until every collection leg has reached `delivered`, and this\nendpoint lists the orders in that state so nobody has to find out by clicking.\n\n**Oldest first**, the opposite of every other list here: the order blocked longest is the\none that needs looking at.\n\nEach row carries `can_be_assigned`, `assignment_blocked_reason` and `collection_legs`\nwith their status and any failure reason. A collection leg in `delivery_failed` blocks\npermanently — the goods never arrived — and the back office is notified separately so\nsomebody can send another captain for them or call the order off.\n\nNeeds `orders.view`, the same grant as the order list.",
                "operationId": "dashboardOrdersAwaitingCollection",
                "parameters": [
                    {
                        "name": "rows",
                        "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
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The blocked deliveries, longest block first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Order"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Total pages.",
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Page": {
                                            "type": "integer",
                                            "example": 1
                                        },
                                        "Records": {
                                            "description": "Total orders blocked.",
                                            "type": "integer",
                                            "example": 3
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing orders.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/profile": {
            "get": {
                "tags": [
                    "Dashboard — Profile"
                ],
                "summary": "Signed in admin's own record",
                "operationId": "adminProfileShow",
                "responses": {
                    "200": {
                        "description": "The admin record, roles included.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Profile"
                ],
                "summary": "Update the signed in admin's own record",
                "operationId": "adminProfileUpdate",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "محمد الجاعور",
                                        "maxLength": 255
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "super-admin@kapitano-logiistic.com",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^\\+[0-9]{8,15}$",
                                        "example": "+963932174371"
                                    },
                                    "date_of_birth": {
                                        "type": "string",
                                        "format": "date",
                                        "example": "1990-01-01",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "محمد الجاعور",
                                "email": "super-admin@kapitano-logiistic.com",
                                "phone": "+963932174371",
                                "date_of_birth": "1990-01-01"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Record updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/profile/photo": {
            "post": {
                "tags": [
                    "Dashboard — Profile"
                ],
                "summary": "Replace the profile photo",
                "operationId": "adminProfilePhoto",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "photo": {
                                        "description": "jpg/jpeg/png, max 5120KB",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Photo replaced.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Admin"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/profile/password": {
            "post": {
                "tags": [
                    "Dashboard — Profile"
                ],
                "summary": "Replace the password",
                "description": "Requires the current password first. A wrong current password answers 422 on the `current_password` field.",
                "operationId": "adminChangePassword",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "current_password": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "123456"
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "current_password": "123456",
                                "password": "123456",
                                "password_confirmation": "123456"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password changed."
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Current password wrong or validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/deliveries": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Push delivery log",
                "description": "Every push the application sent, one row per device, newest first — the answer to\n\"did the captain get it?\".\n\n- `status`: `sent` (Firebase accepted it for that device), `failed` (Firebase refused\n  it, or sending crashed; `error` says why), `no_device` (the recipient had no\n  registered handset, so nothing was sent). Broadcasts skip captains without a device\n  instead of logging `no_device` for each.\n- `device` is the last 12 characters of the token: enough to tell handsets apart, not\n  enough to push to one.\n- `driver_uuid` narrows to one captain (unknown → 404); `broadcast_uuid` to one broadcast.\n\nRows older than `PUSH_RETENTION_DAYS` (30) are deleted nightly. Requires `push.view`.",
                "operationId": "pushDeliveriesIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 10,
                            "maximum": 25,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "sent",
                                "failed",
                                "no_device"
                            ]
                        }
                    },
                    {
                        "name": "driver_uuid",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "01m2fantc1662x43w8aajdfnq0"
                        }
                    },
                    {
                        "name": "broadcast_uuid",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "notification",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "NewOrderAssignedNotification"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-09-01"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-09-17"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of deliveries.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "uuid": {
                                                        "type": "string",
                                                        "format": "uuid"
                                                    },
                                                    "recipient": {
                                                        "properties": {
                                                            "uuid": {
                                                                "type": "string"
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "example": "Captain C1"
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "example": "Driver"
                                                            }
                                                        },
                                                        "type": "object",
                                                        "nullable": true
                                                    },
                                                    "broadcast_uuid": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "nullable": true
                                                    },
                                                    "notification": {
                                                        "type": "string",
                                                        "example": "NewOrderAssignedNotification"
                                                    },
                                                    "title": {
                                                        "type": "string",
                                                        "example": "New order assigned",
                                                        "nullable": true
                                                    },
                                                    "body": {
                                                        "type": "string",
                                                        "nullable": true
                                                    },
                                                    "data": {
                                                        "description": "The silent payload the app reads to decide what to open. **Every value is a string** — FCM carries no other type, so a count arrives as `\"4\"` and a flag as `\"1\"`. `type` says which message it is; the remaining keys depend on it.",
                                                        "type": "object",
                                                        "example": {
                                                            "type": "route_plan.updated",
                                                            "route_plan_uuid": "01a0e992-5c6a-7057-ba53-de235553a5bb",
                                                            "version": "20",
                                                            "stops": "4"
                                                        },
                                                        "nullable": true,
                                                        "additionalProperties": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "device": {
                                                        "type": "string",
                                                        "example": "…0123456789ab",
                                                        "nullable": true
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "sent",
                                                            "failed",
                                                            "no_device"
                                                        ]
                                                    },
                                                    "status_label": {
                                                        "type": "string",
                                                        "example": "Failed"
                                                    },
                                                    "message_id": {
                                                        "type": "string",
                                                        "example": "projects/captain-app-43cfa/messages/0:1726512345",
                                                        "nullable": true
                                                    },
                                                    "error": {
                                                        "type": "string",
                                                        "example": "The registration token is not a valid FCM registration token",
                                                        "nullable": true
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Total": {
                                            "description": "Pages",
                                            "type": "integer"
                                        },
                                        "Page": {
                                            "type": "integer"
                                        },
                                        "Records": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown driver_uuid.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid filter or missing rows/page.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/deliveries/{uuid}/resend": {
            "post": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Resend a logged push",
                "description": "Sends a logged push again — same title, body and data, plus `data.resent_from` — to the\nrecipient's **current** devices. The original device is often gone (a failed push usually\nmeans the app was reinstalled), so the resend follows the recipient, not the token.\n\nThe answer is Firebase's, read back from the log; see \"Send a test push\" for the fields.\n404 when the delivery or its recipient no longer exists. Requires `push.send`; limited to\n30 per minute.",
                "operationId": "pushDeliveryResend",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Firebase's answer.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PushSendOutcome"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.send permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown delivery, or its recipient was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "More than 30 sends a minute."
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/stats": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Push health",
                "description": "How push has been doing over the last `PUSH_HEALTH_WINDOW_HOURS` (24): the count per\noutcome, the share that failed, and the thresholds it is judged against.\n\n`healthy` turns false only when at least `thresholds.minimum_failures` pushes failed\n*and* they are at least `thresholds.failure_percent` of the total — a couple of\nuninstalled apps is not an outage. The hourly `push:health` command uses the same rule\nand, when unhealthy, notifies the admins' inbox once per `PUSH_HEALTH_ALERT_COOLDOWN_DAYS`.\nThe thresholds are deploy configuration, not dashboard settings. Requires `push.view`.",
                "operationId": "pushStats",
                "responses": {
                    "200": {
                        "description": "The window's health.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "window_hours": {
                                                    "type": "integer",
                                                    "example": 24
                                                },
                                                "counts": {
                                                    "properties": {
                                                        "sent": {
                                                            "type": "integer",
                                                            "example": 120
                                                        },
                                                        "failed": {
                                                            "type": "integer",
                                                            "example": 3
                                                        },
                                                        "no_device": {
                                                            "type": "integer",
                                                            "example": 7
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "example": 130
                                                },
                                                "failure_percent": {
                                                    "type": "integer",
                                                    "example": 2
                                                },
                                                "healthy": {
                                                    "type": "boolean",
                                                    "example": true
                                                },
                                                "thresholds": {
                                                    "properties": {
                                                        "failure_percent": {
                                                            "type": "integer",
                                                            "example": 25
                                                        },
                                                        "minimum_failures": {
                                                            "type": "integer",
                                                            "example": 5
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/test": {
            "post": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Send a test push to a captain",
                "description": "Pushes a test notification (`data.type = test`) to every registered device of one\ncaptain, **for real** — the phone shows it. Title and body default to a translated text.\n\nThe answer is what Firebase said, read back from the delivery log, not how many devices\nthe captain has:\n\n- `sent`: at least one device was accepted by Firebase.\n- `delivered` / `failed`: per-device outcome. `null` when the delivery log is switched\n  off, because then there is nothing to read the answer from.\n- `devices: 0`: nothing was sent; the captain has no registered handset.\n\nRequires `push.send`; limited to 30 per minute.",
                "operationId": "pushTest",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "driver_uuid"
                                ],
                                "properties": {
                                    "driver_uuid": {
                                        "type": "string",
                                        "example": "01m2fantc1662x43w8aajdfnq0"
                                    },
                                    "title": {
                                        "type": "string",
                                        "example": "Kapitano test",
                                        "nullable": true,
                                        "maxLength": 100
                                    },
                                    "body": {
                                        "type": "string",
                                        "example": "Can you see this?",
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Firebase's answer.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PushSendOutcome"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.send permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown captain.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "driver_uuid missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "More than 30 sends a minute."
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/devices": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Registered devices",
                "description": "Every handset push can reach, most recently seen first, or one captain's with\n`driver_uuid`. A captain missing from this list will get nothing.\n\n`locale` is the language the app registered in; the captain's notifications are built in\nit. `token` is shortened the same way as in the delivery log. Requires `push.view`.",
                "operationId": "pushDevicesIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 10,
                            "maximum": 25,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "driver_uuid",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of devices.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "uuid": {
                                                        "type": "string",
                                                        "format": "uuid"
                                                    },
                                                    "owner": {
                                                        "properties": {
                                                            "uuid": {
                                                                "type": "string"
                                                            },
                                                            "name": {
                                                                "type": "string"
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "example": "Driver"
                                                            }
                                                        },
                                                        "type": "object",
                                                        "nullable": true
                                                    },
                                                    "device_id": {
                                                        "type": "string",
                                                        "nullable": true
                                                    },
                                                    "locale": {
                                                        "type": "string",
                                                        "example": "ar",
                                                        "nullable": true
                                                    },
                                                    "token": {
                                                        "type": "string",
                                                        "example": "…0123456789ab"
                                                    },
                                                    "registered_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    },
                                                    "last_seen_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Records": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown driver_uuid.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/devices/{uuid}": {
            "delete": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Remove a device",
                "description": "Removes a handset from push — a lost or handed-over phone that must stop receiving a\ncaptain's orders. If the captain's app registers again from it, it comes back. Requires\n`push.manage`.",
                "operationId": "pushDeviceDestroy",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "The device was removed and will receive no more notifications."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.manage permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown device.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/broadcasts": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Broadcast history",
                "description": "Broadcasts newest first, with who sent them and how far each got. Requires `push.view`.",
                "operationId": "pushBroadcastsIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 10,
                            "maximum": 25,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of broadcasts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/PushBroadcast"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Records": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Broadcast to captains",
                "description": "Sends one message to many captains, **for real**, in the background. Only approved,\nactive captains are ever included:\n\n- `all`: every approved, active captain.\n- `online`: only those on duty right now.\n- `captains`: the ones named in `driver_uuids` (at most `PUSH_BROADCAST_MAX_NAMED_CAPTAINS`, 500).\n\nThe broadcast is queued as a batch of small jobs (`PUSH_BROADCAST_CHUNK_SIZE`, 50 captains\neach) so no job outlives the queue's retry window and nobody is pushed twice. Captains\nwithout a registered device are skipped. Answers 201 at once; follow progress with\n\"One broadcast and its progress\".\n\n- **409** — the same admin sent the same title, body and audience within\n  `PUSH_BROADCAST_DUPLICATE_WINDOW_S` (120 s): a double click is not sent twice.\n- **422** — nobody matches the audience.\n\nRequires `push.broadcast`; limited to 5 per minute.",
                "operationId": "pushBroadcastStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "title",
                                    "body",
                                    "audience"
                                ],
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "example": "Eid holiday",
                                        "maxLength": 100
                                    },
                                    "body": {
                                        "type": "string",
                                        "example": "The depot is closed on Friday.",
                                        "maxLength": 500
                                    },
                                    "audience": {
                                        "type": "string",
                                        "enum": [
                                            "all",
                                            "online",
                                            "captains"
                                        ]
                                    },
                                    "driver_uuids": {
                                        "description": "Required for, and only allowed with, audience=captains.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/PushBroadcast"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Message": {
                                            "type": "string",
                                            "example": "The broadcast was queued and is being sent in the background."
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.broadcast permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The same broadcast was just sent.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid input, or nobody matches the audience.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "More than 5 broadcasts a minute."
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/broadcasts/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "One broadcast and its progress",
                "description": "Poll this after sending: `status` moves queued → sending → completed and the counts grow as chunks run. Requires `push.view`.",
                "operationId": "pushBroadcastShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The broadcast.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/PushBroadcast"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown broadcast.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/failed-jobs": {
            "get": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Failed push jobs",
                "description": "The queued push work that ran out of attempts — order-assigned and application-decision\nnotifications and broadcast chunks — newest first, with the first line of the error.\nOther failed jobs are not listed here. Requires `push.manage`.",
                "operationId": "pushFailedJobsIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 10,
                            "maximum": 25,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of failed push jobs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "uuid": {
                                                        "type": "string",
                                                        "format": "uuid"
                                                    },
                                                    "job": {
                                                        "type": "string",
                                                        "example": "NotifyCaptainOfAssignment"
                                                    },
                                                    "queue": {
                                                        "type": "string",
                                                        "example": "default"
                                                    },
                                                    "error": {
                                                        "type": "string",
                                                        "example": "ModelNotFoundException: No query results for model [App\\Models\\Order]."
                                                    },
                                                    "failed_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "Records": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.manage permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/failed-jobs/{uuid}/retry": {
            "post": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Retry a failed push job",
                "description": "Puts the job back on its queue. A job that fails again returns to the list. Only push jobs are in reach; any other uuid answers 404. Requires `push.manage`.",
                "operationId": "pushFailedJobRetry",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Re-queued."
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.manage permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown job, or not a push job.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/push/failed-jobs/{uuid}": {
            "delete": {
                "tags": [
                    "Dashboard — Push Notifications"
                ],
                "summary": "Forget a failed push job",
                "description": "Removes the failed job for good. Only push jobs are in reach; any other uuid answers 404. Requires `push.manage`.",
                "operationId": "pushFailedJobDestroy",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed."
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing push.manage permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown job, or not a push job.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/roles": {
            "get": {
                "tags": [
                    "Dashboard — Roles & Permissions"
                ],
                "summary": "List the roles",
                "description": "Paginated, each role with the permissions it grants. Requires `roles.view`. Roles use UUIDs.",
                "operationId": "roleIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of roles.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Role"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing roles.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing/invalid page or rows.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Roles & Permissions"
                ],
                "summary": "Create a role",
                "description": "Creates a role on the `admin` guard and grants the permissions sent with it. Requires `roles.create`.",
                "operationId": "roleStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "operations-manager",
                                        "maxLength": 255
                                    },
                                    "permissions": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "example": "orders.view"
                                        },
                                        "minItems": 1
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "operations-manager",
                                "permissions": [
                                    "drivers.view",
                                    "drivers.update",
                                    "drivers.review",
                                    "vehicles.view",
                                    "vehicles.create",
                                    "vehicles.update",
                                    "orders.view",
                                    "orders.create",
                                    "orders.assign"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Role created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Role"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing roles.create permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/roles/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Roles & Permissions"
                ],
                "summary": "One role with its permissions",
                "operationId": "roleShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a08576-829e-71a7-8823-8bac31159cd1"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The role.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Role"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing roles.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Role not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Roles & Permissions"
                ],
                "summary": "Rename a role and sync its permissions",
                "operationId": "roleUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid",
                            "example": "01a08576-829e-71a7-8823-8bac31159cd1"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "example": "support",
                                        "maxLength": 255
                                    },
                                    "permissions": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "name": "support",
                                "permissions": [
                                    "drivers.view",
                                    "vehicles.view",
                                    "orders.view"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Role updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Role"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing roles.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Role not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/permissions": {
            "get": {
                "tags": [
                    "Dashboard — Roles & Permissions"
                ],
                "summary": "Permission catalogue",
                "description": "Every permission a role may be granted, not paginated (a fixed list used by the role form). Requires any of roles.view / roles.create / roles.update.",
                "operationId": "permissionIndex",
                "responses": {
                    "200": {
                        "description": "The permission catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Permission"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing any role permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/settlements/preview": {
            "get": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "Total a period up, without writing anything",
                "description": "**Run this before drawing a payment up.** It writes nothing; the point is that the\nfigures reach a human before they become a payment, rather than being retyped off another\nscreen — which is where a transposed digit gets into a bank transfer.\n\nBoth dates are required, unlike the store's own statement. A payout covers a stated\nperiod, and silently defaulting one would put \"the last thirty days from whenever you\nclicked\" into a financial record.\n\nOne row per currency, never summed across them.\n\nRequires `settlements.manage`.",
                "operationId": "settlementPreview",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "What the period came to.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "totals": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "currency": {
                                                                "type": "string",
                                                                "example": "SYP"
                                                            },
                                                            "delivered_count": {
                                                                "type": "integer"
                                                            },
                                                            "cash_collected": {
                                                                "type": "number"
                                                            },
                                                            "prepaid_value": {
                                                                "type": "number"
                                                            },
                                                            "fees_charged": {
                                                                "type": "number"
                                                            },
                                                            "net_due_to_store": {
                                                                "type": "number"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Dates missing, or the range is backwards.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/settlements": {
            "get": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "One store's payouts",
                "description": "Drafts included, unlike the store's own view of the same ledger. Requires `settlements.view`.",
                "operationId": "settlementIndex",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "settled",
                                "cancelled"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of settlements.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Settlement"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "Draw a payout up, as a draft",
                "description": "**A draft is invisible to the store.** They see it once somebody has stood behind it — a\nfigure still being checked is not one worth having an argument about.\n\nThe amounts you send are recorded **as sent**, and are allowed to differ from the\npreview: an adjustment, a rounding, a dispute settled halfway. What is recorded is what a\nhuman agreed to pay, not what the orders imply. That is also why they are copied in\nrather than joined to — if an order is corrected next month, a payment already made must\nnot change underneath the people holding it.\n\n`net_amount` may be **negative**. A mostly-prepaid month where our fees exceed the cash\ncollected leaves the shop owing us, and a ledger that could only express one direction\nwould force somebody to fudge it.\n\nRequires `settlements.manage`.",
                "operationId": "settlementStore",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "period_start",
                                    "period_end",
                                    "currency",
                                    "cash_collected",
                                    "fees_charged",
                                    "net_amount"
                                ],
                                "properties": {
                                    "period_start": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "period_end": {
                                        "description": "On or after period_start.",
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "currency": {
                                        "type": "string",
                                        "example": "SYP",
                                        "maxLength": 3
                                    },
                                    "cash_collected": {
                                        "type": "number"
                                    },
                                    "fees_charged": {
                                        "type": "number"
                                    },
                                    "net_amount": {
                                        "description": "What is actually paid. Sent rather than derived, because it is allowed to differ from cash − fees.",
                                        "type": "number"
                                    },
                                    "orders_count": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "reference": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 1000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Drafted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Settlement"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/settlements/{settlement}": {
            "put": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "Correct a draft",
                "description": "Only while it is a draft. A settled one answers **409 `settlement_not_editable`**: the way\nto correct a payment both sides are holding is another payment, not a rewrite of the one\nthey agreed.\n\nRequires `settlements.manage`.",
                "operationId": "settlementUpdate",
                "parameters": [
                    {
                        "name": "settlement",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "period_start",
                                    "period_end",
                                    "currency",
                                    "cash_collected",
                                    "fees_charged",
                                    "net_amount"
                                ],
                                "properties": {
                                    "period_start": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "period_end": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "currency": {
                                        "type": "string",
                                        "maxLength": 3
                                    },
                                    "cash_collected": {
                                        "type": "number"
                                    },
                                    "fees_charged": {
                                        "type": "number"
                                    },
                                    "net_amount": {
                                        "type": "number"
                                    },
                                    "orders_count": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "reference": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Settlement"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already settled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/settlements/{settlement}/settle": {
            "post": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "Mark it paid",
                "description": "From here the store can see it, and **neither side may edit it**. The figures are frozen\nrather than recomputed, so a later correction to an order cannot change a payment that\nhas already been made.\n\nRequires `settlements.manage`.",
                "operationId": "settlementSettle",
                "parameters": [
                    {
                        "name": "settlement",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Settled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Settlement"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not a draft. Nothing leads out of settled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/settlements/{settlement}/cancel": {
            "post": {
                "tags": [
                    "Dashboard — Settlements"
                ],
                "summary": "Abandon a draft",
                "description": "Only from draft. Requires `settlements.manage`.",
                "operationId": "settlementCancel",
                "parameters": [
                    {
                        "name": "settlement",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Cancelled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Settlement"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not a draft.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/stats": {
            "get": {
                "tags": [
                    "Dashboard — Stats"
                ],
                "summary": "Everything the overview screen draws",
                "description": "One call for the whole landing page, rather than a dozen — the screen draws all of it at\nonce, so splitting it would only buy a slower first paint.\n\n**Cached for a short period and shared by every admin**, which is why `generated_at` is\nreturned: a figure a minute old is fine on this screen, and a figure whose age is unknown\nis not. Show it.\n\nCounts are **zero-filled across every status**, so a tile never disappears because its\nnumber happens to be nought — \"no failed deliveries\" and \"we forgot to ask\" must not look\nalike.\n\nRequires `dispatch.view`.",
                "operationId": "dashboardStats",
                "responses": {
                    "200": {
                        "description": "The overview.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "generated_at": {
                                                    "description": "When the cached snapshot was built. Show it.",
                                                    "type": "string",
                                                    "format": "date-time"
                                                },
                                                "orders": {
                                                    "properties": {
                                                        "total": {
                                                            "type": "integer"
                                                        },
                                                        "today": {
                                                            "type": "integer"
                                                        },
                                                        "yesterday": {
                                                            "type": "integer"
                                                        },
                                                        "active": {
                                                            "description": "Everything not yet in a terminal state.",
                                                            "type": "integer"
                                                        },
                                                        "by_status": {
                                                            "description": "Every OrderStatus, zero-filled.",
                                                            "type": "object"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "revenue": {
                                                    "properties": {
                                                        "today": {
                                                            "type": "number"
                                                        },
                                                        "yesterday": {
                                                            "type": "number"
                                                        },
                                                        "total": {
                                                            "type": "number"
                                                        },
                                                        "by_payment_method": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "deliveries": {
                                                    "properties": {
                                                        "today": {
                                                            "type": "integer"
                                                        },
                                                        "yesterday": {
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "drivers": {
                                                    "properties": {
                                                        "by_status": {
                                                            "description": "Every DriverStatus, zero-filled.",
                                                            "type": "object"
                                                        },
                                                        "online": {
                                                            "type": "integer"
                                                        },
                                                        "ready_to_assign": {
                                                            "description": "Approved, on duty, not on a break, and carrying fewer than the maximum — the same rule the assignment screen applies.",
                                                            "type": "integer"
                                                        },
                                                        "idle": {
                                                            "description": "Of those, the ones carrying nothing at all.",
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "vehicles": {
                                                    "properties": {
                                                        "total": {
                                                            "type": "integer"
                                                        },
                                                        "active": {
                                                            "type": "integer"
                                                        },
                                                        "awaiting_assignment": {
                                                            "description": "Company vehicles with no plate yet.",
                                                            "type": "integer"
                                                        },
                                                        "by_ownership": {
                                                            "type": "object"
                                                        },
                                                        "by_type": {
                                                            "type": "object"
                                                        },
                                                        "documents": {
                                                            "properties": {
                                                                "registration": {
                                                                    "type": "object"
                                                                },
                                                                "insurance": {
                                                                    "type": "object"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "trends": {
                                                    "properties": {
                                                        "days": {
                                                            "description": "How many days the series covers.",
                                                            "type": "integer"
                                                        },
                                                        "series": {
                                                            "description": "One entry per day: created, delivered, revenue.",
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients": {
            "get": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "The stores, and the applications waiting for a decision",
                "description": "Newest first. Filter by `status=pending` for the review queue.\n\nNote that this list deliberately **includes inactive rows**, unlike most listings here.\nAn application awaiting review is inactive by definition, so a queue that hid them would\nalways look empty.\n\nRequires `store_clients.view`.",
                "operationId": "storeClientIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "approved",
                                "rejected",
                                "suspended"
                            ]
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Name or handle.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of stores.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}": {
            "get": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "One store",
                "description": "No secret is returned here. Support can read a store's whole configuration without being able to read its signing key. Requires `store_clients.view`.",
                "operationId": "storeClientShow",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The store.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such store.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Correct a store's configuration on its behalf",
                "description": "For when a shop cannot fix it itself — the owner is the person who left, or the callback\nURL is wrong in a way that only shows up in our delivery log.\n\nThe URL goes through the **same SSRF check** the store's own screen uses. Being an admin\nis not a reason to skip it: the outbound request is still made by our server, to whatever\nwas typed, so the check protects us rather than the person typing.\n\n`slug`, `status` and `is_active` are refused with 422. The handle is in our rate-limit\nkeys and our logs; the other two move through the review decisions, where they collect a\nreason and a name.\n\nRequires `store_clients.manage`.",
                "operationId": "storeClientUpdate",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "webhook_url": {
                                        "description": "https, public host, standard port, no credentials.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "allowed_ips": {
                                        "description": "Empty switches the check off.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "ipv4"
                                        },
                                        "maxItems": 20
                                    },
                                    "default_currency": {
                                        "type": "string",
                                        "maxLength": 3
                                    },
                                    "timezone": {
                                        "type": "string"
                                    },
                                    "wrapping_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "wrapping_address": {
                                        "description": "Sent together with both coordinates, or all three cleared to switch wrapping off. A wrapping shop with no point on the map is not a place a captain can be sent.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "wrapping_lat": {
                                        "type": "number",
                                        "format": "float",
                                        "nullable": true,
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "wrapping_lng": {
                                        "type": "number",
                                        "format": "float",
                                        "nullable": true,
                                        "maximum": 180,
                                        "minimum": -180
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A private callback URL, or a field that is never editable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/users": {
            "get": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "The people who can sign in to this store",
                "description": "Worth checking after an approval: *\"approved store, nobody can sign in\"* is the\nonboarding failure that looks like nothing at all from our side.\n\nRequires `store_clients.view`.",
                "operationId": "storeClientUsers",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of people.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreUser"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/approve": {
            "post": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Approve a store — and how a suspended one comes back",
                "description": "Switches the store on and moves every `pending` person at it to `active`.\n\n**This is also the unpause.** `Suspended → Approved` is an allowed move, so a pause that\nhas run its course ends by approving again — there is no separate endpoint, because it\nwould mean exactly the same thing.\n\n**It does not mint the API token.** A plaintext token exists only at the moment it is\ncreated, so it is issued deliberately through `POST {client}/tokens` rather than printed\ninto the answer to a question nobody asked.\n\nThe note is optional here — an approval usually explains itself.\n\nRequires `store_clients.review`.",
                "operationId": "storeClientApprove",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "note": {
                                        "type": "string",
                                        "example": "Contract signed",
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Approved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The application cannot move that way from its current status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/reject": {
            "post": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Turn an application down",
                "description": "**The note is required**, unlike on an approval. This is one of the two decisions a shop\nrings up about, and \"no reason recorded\" makes that call unanswerable by whoever picks it\nup rather than by whoever made the decision.\n\nRevokes every portal session at the store immediately.\n\nRequires `store_clients.review`.",
                "operationId": "storeClientReject",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "note"
                                ],
                                "properties": {
                                    "note": {
                                        "type": "string",
                                        "example": "Could not verify the business",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Rejected.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not allowed from the current status — an approved store is suspended, not rejected.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The note is missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/suspend": {
            "post": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Stop a store trading, without unpicking its approval",
                "description": "A pause is meant to end, and a suspended store is not a rejected one — so this leaves the\nreview decision intact and approving again brings it back.\n\nTakes effect on the **very next request**: portal tokens are revoked immediately rather\nthan left to expire, because a Sanctum token does not expire on its own.\n\nRequires `store_clients.manage` — pausing a shop that is already trading stops another\ncompany's orders, which is operations' call rather than a reviewer's.",
                "operationId": "storeClientSuspend",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "note"
                                ],
                                "properties": {
                                    "note": {
                                        "type": "string",
                                        "example": "Unpaid invoices",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Suspended.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreClient"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not allowed from the current status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/tokens": {
            "post": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Mint a machine credential — shown once",
                "description": "The token a store's **servers** authenticate with, as opposed to the password its staff\nsign in with.\n\n**The plaintext is returned once and cannot be recovered.** The response carries\n`Cache-Control: no-store`; hand it over on a secure channel and do not log it.\n\nDeliberately separate from approving a store: asking for a token is asking for a secret,\nand that should be an act somebody chose rather than a side effect of a decision.\n\nExisting tokens are **left alone** — replacing them silently would cut a store off\nmid-trade. Use the DELETE below when that is what you mean.\n\nOmit `abilities` for both. Send a narrower set for a reporting or staging integration\nthat has no business creating orders.\n\nRequires `store_clients.manage`.",
                "operationId": "storeClientIssueToken",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "abilities": {
                                        "description": "Defaults to both.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "orders:read",
                                                "orders:write"
                                            ]
                                        },
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The token, once.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "token": {
                                                    "type": "string",
                                                    "example": "12|xxxxxxxxxxxxxxxxxxxx"
                                                },
                                                "abilities": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Kill every machine credential this store holds",
                "description": "**The emergency path for a leaked token.** Until this existed the only way to do it was a\nshell on the server, which is the wrong requirement for something that has to happen in\nthe next minute and be recorded against a name.\n\nTheir **portal access is untouched**. A leaked *server* credential is not a reason to\nlock the shop's staff out of the screen where they can read what happened and set up a\nnew one.\n\nRequires `store_clients.manage`.",
                "operationId": "storeClientRevokeTokens",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "properties": {
                                                "revoked": {
                                                    "description": "How many were killed.",
                                                    "type": "integer",
                                                    "example": 2
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/store-clients/{client}/users/{user}/activation": {
            "patch": {
                "tags": [
                    "Dashboard — Stores"
                ],
                "summary": "Turn one of a store's people on or off",
                "description": "Normally the store's own owner does this from their portal. Two cases need us to: the\nowner **is** the person who left, so nobody at the shop can remove their access; or the\nshop has been asked to and has not.\n\nTurning somebody off revokes their sessions at once.\n\nA person belonging to a different store answers **404** — an endpoint nested under one\nstore that quietly acted on another's would be a surprise nobody needs.\n\nRequires `store_clients.manage`.",
                "operationId": "storeClientUserActivation",
                "parameters": [
                    {
                        "name": "client",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "user",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "is_active"
                                ],
                                "properties": {
                                    "is_active": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StoreUser"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not somebody at this store.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/vehicles": {
            "get": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "Vehicle list",
                "description": "Paginated, newest first, switched off vehicles included. Filters: search (plate, brand,\nmodel, registration / insurance number, captain name or phone), ownership_type,\nvehicle_type, document_status, driver_uuid, is_active, awaiting_assignment.\n\n`document_status` narrows to vehicles with **at least one** document in that state\n(`missing`, `expired`, `expiring_soon` = within 30 days); `valid` narrows to vehicles\nwhose registration **and** insurance are both valid for more than 30 days.\nRequires `vehicles.view`.",
                "operationId": "vehicleIndex",
                "parameters": [
                    {
                        "name": "rows",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "maximum": 25,
                            "minimum": 1
                        },
                        "example": 10
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "maxLength": 255
                        }
                    },
                    {
                        "name": "ownership_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "company_owned",
                                "personal"
                            ]
                        }
                    },
                    {
                        "name": "vehicle_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "motorcycle",
                                "car",
                                "van",
                                "pickup_truck",
                                "truck"
                            ]
                        }
                    },
                    {
                        "name": "document_status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                                "missing",
                                "expired",
                                "expiring_soon",
                                "valid"
                            ]
                        }
                    },
                    {
                        "name": "driver_uuid",
                        "in": "query",
                        "description": "Captain ULID.",
                        "schema": {
                            "type": "string",
                            "nullable": true
                        }
                    },
                    {
                        "name": "is_active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "awaiting_assignment",
                        "in": "query",
                        "description": "Company-owned rows with no plate yet — captains waiting for a fleet car.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of vehicles.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Vehicle"
                                            }
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Missing/invalid page, rows or filter.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "Add a vehicle for a captain",
                "description": "Puts a vehicle on record for a captain who has none (a captain has exactly one vehicle — one who already has one answers 409). Plate numbers are unique. Photos are optional. Requires `vehicles.create`.",
                "operationId": "vehicleStore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "driver_uuid",
                                    "ownership_type",
                                    "vehicle_type",
                                    "plate_number",
                                    "brand",
                                    "model",
                                    "manufacture_year",
                                    "color"
                                ],
                                "properties": {
                                    "driver_uuid": {
                                        "description": "Captain ULID.",
                                        "type": "string",
                                        "example": "01m24x34bzfbh7resdmkm55mmq"
                                    },
                                    "ownership_type": {
                                        "type": "string",
                                        "example": "company_owned",
                                        "enum": [
                                            "company_owned",
                                            "personal"
                                        ]
                                    },
                                    "vehicle_type": {
                                        "type": "string",
                                        "example": "van",
                                        "enum": [
                                            "motorcycle",
                                            "car",
                                            "van",
                                            "pickup_truck",
                                            "truck"
                                        ]
                                    },
                                    "plate_number": {
                                        "type": "string",
                                        "example": "KAP-5050",
                                        "maxLength": 20
                                    },
                                    "brand": {
                                        "type": "string",
                                        "example": "Toyota",
                                        "maxLength": 100
                                    },
                                    "model": {
                                        "type": "string",
                                        "example": "Hiace",
                                        "maxLength": 100
                                    },
                                    "manufacture_year": {
                                        "type": "integer",
                                        "example": 2024,
                                        "maximum": 2027,
                                        "minimum": 1950
                                    },
                                    "color": {
                                        "type": "string",
                                        "example": "white",
                                        "maxLength": 50
                                    },
                                    "registration_number": {
                                        "type": "string",
                                        "example": "REG-7788",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "registration_expires_at": {
                                        "type": "string",
                                        "format": "date",
                                        "example": "2027-09-30",
                                        "nullable": true
                                    },
                                    "insurance_policy_number": {
                                        "type": "string",
                                        "example": "INS-4411",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "insurance_expires_at": {
                                        "type": "string",
                                        "format": "date",
                                        "example": "2027-03-31",
                                        "nullable": true
                                    },
                                    "vehicle_image": {
                                        "description": "jpg/jpeg/png, max 5 MB.",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "mechanics_image": {
                                        "description": "jpg/jpeg/png, max 5 MB.",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Vehicle added.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Vehicle"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.create permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Captain not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The captain already has a vehicle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorConflict"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed (e.g. plate number already on record).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/vehicles/{uuid}": {
            "get": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "One vehicle",
                "description": "The vehicle with the captain driving it, its photos and the state of its documents. Requires `vehicles.view`.",
                "operationId": "vehicleShow",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "01a089d1-97c8-7108-bcde-a4ede59fd004"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The vehicle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Vehicle"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.view permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Vehicle not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "Correct a vehicle's record",
                "description": "Updates only the fields sent (JSON). Identifying fields may be changed but not blanked;\nregistration and insurance fields may be sent as `null` to clear them. The plate number\nmust stay unique. Filling in a company car still awaiting assignment lets its captain\nbe approved without a `vehicle` block. Requires `vehicles.update`.",
                "operationId": "vehicleUpdate",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "01a089d1-97c8-7108-bcde-a4ede59fd004"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "ownership_type": {
                                        "type": "string",
                                        "enum": [
                                            "company_owned",
                                            "personal"
                                        ]
                                    },
                                    "vehicle_type": {
                                        "type": "string",
                                        "enum": [
                                            "motorcycle",
                                            "car",
                                            "van",
                                            "pickup_truck",
                                            "truck"
                                        ]
                                    },
                                    "plate_number": {
                                        "type": "string",
                                        "maxLength": 20
                                    },
                                    "brand": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "model": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "manufacture_year": {
                                        "type": "integer",
                                        "maximum": 2027,
                                        "minimum": 1950
                                    },
                                    "color": {
                                        "type": "string",
                                        "maxLength": 50
                                    },
                                    "registration_number": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "registration_expires_at": {
                                        "type": "string",
                                        "format": "date",
                                        "nullable": true
                                    },
                                    "insurance_policy_number": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "insurance_expires_at": {
                                        "type": "string",
                                        "format": "date",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            },
                            "example": {
                                "vehicle_type": "van",
                                "color": "black",
                                "insurance_policy_number": "INS-9900",
                                "insurance_expires_at": "2027-12-31"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Record updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Vehicle"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Vehicle not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/vehicles/{uuid}/images": {
            "post": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "Replace vehicle photos",
                "description": "Multipart. Send `vehicle_image`, `mechanics_image`, or both — the one not sent stays as it is; at least one is required. Requires `vehicles.update`.",
                "operationId": "vehicleUpdateImages",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "01a089d1-97c8-7108-bcde-a4ede59fd004"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "vehicle_image": {
                                        "description": "jpg/jpeg/png, max 5 MB.",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "mechanics_image": {
                                        "description": "jpg/jpeg/png, max 5 MB.",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Photos replaced.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Vehicle"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Vehicle not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No photo sent, or not a jpg/png under 5 MB.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorValidation"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        },
        "/api/dashboard/vehicles/{uuid}/activation": {
            "patch": {
                "tags": [
                    "Dashboard — Vehicles"
                ],
                "summary": "Activate or deactivate a vehicle",
                "description": "Flips the vehicle on or off. Vehicles are never deleted. Requires `vehicles.update`.",
                "operationId": "vehicleToggleActivation",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "01a089d1-97c8-7108-bcde-a4ede59fd004"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "State changed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "Model": {
                                            "$ref": "#/components/schemas/Vehicle"
                                        },
                                        "Status": {
                                            "type": "boolean",
                                            "example": true
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token missing, revoked, or headers missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorUnauthorized"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Missing vehicles.update permission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorForbidden"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Vehicle not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorNotFound"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "adminAuth": []
                    }
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "Admin": {
                "description": "A back office account as exposed by the admin resources.",
                "properties": {
                    "uuid": {
                        "description": "A back office account as exposed by AdminResource. Roles and the permissions they\ngrant are present only when the roles relation is loaded.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a08576-8432-72a4-908c-c75a11a98bad"
                    },
                    "name": {
                        "description": "The administrator full name, as shown in audit trails and on an order timeline.",
                        "type": "string",
                        "example": "محمد الجاعور"
                    },
                    "email": {
                        "description": "Their sign-in identity, unique across administrators.",
                        "type": "string",
                        "format": "email",
                        "example": "super-admin@kapitano-logiistic.com"
                    },
                    "phone": {
                        "description": "A contact number. Not used to sign in.",
                        "type": "string",
                        "example": "+963932174371"
                    },
                    "date_of_birth": {
                        "description": "Held for the personnel record. Null when nobody filled it in.",
                        "type": "string",
                        "format": "date",
                        "example": "1990-01-01",
                        "nullable": true
                    },
                    "photo": {
                        "description": "Their avatar. Null when none was uploaded.",
                        "type": "string",
                        "format": "url",
                        "nullable": true
                    },
                    "is_active": {
                        "description": "Whether they may sign in. Deactivating keeps the account and everything it did, which is why accounts are switched off rather than deleted.",
                        "type": "boolean",
                        "example": true
                    },
                    "roles": {
                        "description": "The role names granted to them. Permissions come with these rather than being listed one by one.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "super-admin"
                        ]
                    },
                    "permissions": {
                        "description": "The effective permission names, flattened from every role. Empty on a super admin, who bypasses the check entirely — read `is_super_admin` before concluding they can do nothing.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": []
                    },
                    "is_super_admin": {
                        "description": "**Passes every permission check regardless of what `permissions` lists.** A screen that hides actions by searching that array will hide everything from exactly the person allowed to do it all.",
                        "type": "boolean",
                        "example": true
                    },
                    "created_at": {
                        "description": "When the account was created.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-09 12:18:51"
                    }
                },
                "type": "object"
            },
            "AdminAuthResult": {
                "description": "The result of a successful dashboard login: bearer token and the admin record.",
                "properties": {
                    "token": {
                        "description": "The login response: token and the admin's own record.",
                        "type": "string",
                        "example": "27|XBzYv3uBanTHHldOHWvrngVIwcRvP1Ts2Yrk6fOL3688db7e"
                    },
                    "admin": {
                        "$ref": "#/components/schemas/Admin"
                    }
                },
                "type": "object"
            },
            "Role": {
                "description": "A role on the admin guard with the permissions it grants.",
                "properties": {
                    "uuid": {
                        "description": "A role with the permissions it grants.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a08576-829e-71a7-8823-8bac31159cd1"
                    },
                    "name": {
                        "description": "The role identifier, in kebab case. This is what `Admin.roles` lists.",
                        "type": "string",
                        "example": "operations-manager"
                    },
                    "guard_name": {
                        "description": "Which authentication guard the role belongs to. Always `admin` here — captains and store users are not governed by roles.",
                        "type": "string",
                        "example": "admin"
                    },
                    "is_super_admin": {
                        "description": "Whether holding this role bypasses every permission check. Granting it hands over the whole dashboard, so it is worth confirming before saving.",
                        "type": "boolean",
                        "example": false
                    },
                    "permissions": {
                        "description": "What the role allows, in full. Editing a role changes what every administrator holding it can do, immediately.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Permission"
                        }
                    },
                    "created_at": {
                        "description": "When the role was created.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-09 12:18:51"
                    }
                },
                "type": "object"
            },
            "Permission": {
                "description": "A permission in the catalogue.",
                "properties": {
                    "uuid": {
                        "description": "A single permission from the fixed catalogue.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a089d1-853a-7129-a071-d5079ff01060"
                    },
                    "name": {
                        "description": "The permission identifier the API checks against, as `area.action`. This is the string to test for, not the label.",
                        "type": "string",
                        "example": "orders.view"
                    },
                    "label": {
                        "description": "The permission translated for the screen.",
                        "type": "string",
                        "example": "View orders"
                    },
                    "group": {
                        "description": "Which area it belongs to, so a permissions screen can section the list rather than showing a hundred checkboxes.",
                        "type": "string",
                        "example": "orders"
                    },
                    "group_label": {
                        "description": "The group translated for the screen.",
                        "type": "string",
                        "example": "Orders"
                    }
                },
                "type": "object"
            },
            "AdminNotification": {
                "properties": {
                    "uuid": {
                        "description": "One item in the back office's bell.\n\n`title` and `message` arrive already translated into whatever `Accept-Language` asked for, so\na screen renders them directly. Branch on `type` and `group`, never on the text.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "title": {
                        "description": "Already translated.",
                        "type": "string"
                    },
                    "message": {
                        "description": "Already translated.",
                        "type": "string"
                    },
                    "type": {
                        "description": "How loudly to draw it. `danger` means somebody has to act.",
                        "type": "string",
                        "enum": [
                            "info",
                            "warning",
                            "success",
                            "danger"
                        ]
                    },
                    "group": {
                        "description": "What it is about, for filtering.",
                        "type": "string",
                        "enum": [
                            "order",
                            "vehicle",
                            "application",
                            "system"
                        ]
                    },
                    "action_url": {
                        "description": "Where clicking it should go.",
                        "type": "string",
                        "nullable": true
                    },
                    "is_read": {
                        "description": "Whether this administrator has opened it. Read state is per administrator, so the same event is unread for everyone else.",
                        "type": "boolean"
                    },
                    "created_at": {
                        "description": "When the event happened. The list reads newest first.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "ErrorValidation": {
                "description": "422 — validation failed; the offending fields sit under MessageDebug.validation.",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": "Validation Error",
                    "MessageDebug": {
                        "validation": {
                            "phone": [
                                "The phone field is required."
                            ]
                        }
                    },
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                },
                "allOf": [
                    {
                        "properties": {
                            "Status": {
                                "description": "422 — validation failed. The offending fields sit under `MessageDebug.validation`.",
                                "type": "boolean",
                                "example": false
                            },
                            "Message": {
                                "type": "string",
                                "example": "Validation Error"
                            },
                            "MessageDebug": {
                                "properties": {
                                    "validation": {
                                        "type": "object",
                                        "example": {
                                            "phone": [
                                                "The phone field is required."
                                            ]
                                        },
                                        "additionalProperties": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            }
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "ErrorUnauthorized": {
                "description": "401 — missing/invalid token, or a required header was not sent.",
                "properties": {
                    "Status": {
                        "description": "401 — no usable token, or the required headers are missing.",
                        "type": "boolean",
                        "example": false
                    },
                    "Message": {
                        "description": "Already translated and safe to show. On this status it rarely helps the user, though — a missing header and a dead token read the same to them, so prefer sending them back to sign in.",
                        "type": "string",
                        "example": "Unauthorized",
                        "nullable": true
                    },
                    "MessageDebug": {
                        "description": "Diagnostic detail (unauthorized / accept_header / language) — this is what tells the two apart while developing. Never shown to a user."
                    }
                },
                "type": "object",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": "Unauthorized",
                    "MessageDebug": {
                        "Unauthorized": [
                            "Unauthorized !"
                        ]
                    },
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                }
            },
            "ErrorForbidden": {
                "description": "403 — the account is disabled/rejected, or the admin lacks the required permission.",
                "properties": {
                    "Status": {
                        "description": "403 — the account is turned away for good, or the token lacks the permission.",
                        "type": "boolean",
                        "example": false
                    },
                    "Message": {
                        "description": "Why it was refused, already translated. Worth showing: a suspended captain needs to know that is what happened rather than that something broke.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "MessageDebug": {
                        "description": "Diagnostic detail (reason / permission message). Never shown to a user."
                    }
                },
                "type": "object",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": null,
                    "MessageDebug": "You do not have permission to access this link.",
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                }
            },
            "ErrorNotFound": {
                "description": "404 — the requested record was not found.",
                "properties": {
                    "Status": {
                        "description": "404 — the record (or account) does not exist.",
                        "type": "boolean",
                        "example": false
                    },
                    "Message": {
                        "description": "Already translated and safe to show.",
                        "type": "string",
                        "example": "The item not found"
                    },
                    "MessageDebug": {
                        "description": "The machine-readable key behind the message. Never shown to a user.",
                        "type": "object",
                        "example": {
                            "item_not_found": []
                        }
                    }
                },
                "type": "object",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": "The item not found",
                    "MessageDebug": {
                        "item_not_found": []
                    },
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                }
            },
            "ErrorConflict": {
                "description": "409 — the requested change conflicts with the current state (e.g. re-deciding an application).",
                "properties": {
                    "Status": {
                        "description": "409 — the state machine refuses a repeated decision.",
                        "type": "boolean",
                        "example": false
                    },
                    "Message": {
                        "description": "Already translated and safe to show. A conflict usually means the screen is out of date, so re-reading the record is the right next move.",
                        "type": "string",
                        "example": "The item already exists."
                    },
                    "MessageDebug": {
                        "description": "The machine-readable key behind the message. Never shown to a user.",
                        "type": "object",
                        "example": {
                            "item_already_exists": []
                        }
                    }
                },
                "type": "object",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": "The item already exists.",
                    "MessageDebug": {
                        "item_already_exists": []
                    },
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                }
            },
            "ErrorTooManyRequests": {
                "description": "429 — too many requests; slow down and retry shortly.",
                "properties": {
                    "Status": {
                        "description": "429 — the request was throttled.",
                        "type": "boolean",
                        "example": false
                    },
                    "Message": {
                        "description": "Already translated and safe to show. Back off rather than retrying straight away — the OTP endpoints allow four attempts a minute.",
                        "type": "string",
                        "example": "Too many requests, please slow down and try again shortly"
                    },
                    "MessageDebug": {
                        "description": "The machine-readable key behind the message. Never shown to a user.",
                        "type": "object",
                        "example": {
                            "too_many_requests": []
                        }
                    }
                },
                "type": "object",
                "example": {
                    "Model": null,
                    "Status": false,
                    "Message": "Too many requests, please slow down and try again shortly",
                    "MessageDebug": {
                        "too_many_requests": []
                    },
                    "Total": 0,
                    "Page": 0,
                    "Records": 0
                }
            },
            "CaptainLedgerEntry": {
                "description": "One movement of money between a captain and the company. Written once and never edited — a\ncorrection is a new `adjustment` line.\n\n**`amount` is signed: positive means the company owes the captain.** A supplier payment and\ncash handed in are positive; cash collected from a customer and cash paid out by the desk are\nnegative. `balance_after` is the captain's running balance in this currency once the line\nlanded.",
                "properties": {
                    "uuid": {
                        "description": "One line of a captain's statement.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a0c6d2-4f1e-7c3a-9b2d-5e8f1a2b3c4d"
                    },
                    "type": {
                        "description": "What kind of movement this is. `supplier_payment` and `delivery_earning` raise the balance (the company owes the captain more), `cash_collected` and `cash_handed_in` and `cash_paid_out` lower it, and `adjustment` is a correction that may go either way.",
                        "type": "string",
                        "example": "supplier_payment",
                        "enum": [
                            "supplier_payment",
                            "cash_collected",
                            "delivery_earning",
                            "cash_paid_out",
                            "cash_handed_in",
                            "adjustment"
                        ]
                    },
                    "type_label": {
                        "description": "The movement type translated for the screen.",
                        "type": "string",
                        "example": "Paid supplier"
                    },
                    "amount": {
                        "description": "Signed. Positive = the company owes the captain.",
                        "type": "number",
                        "format": "float",
                        "example": 300
                    },
                    "balance_after": {
                        "description": "The running balance in this currency once this line landed — so a statement reconciles down the page without the reader adding anything up.",
                        "type": "number",
                        "format": "float",
                        "example": 300
                    },
                    "currency": {
                        "description": "Always `SYP`. Balances are grouped by it, which is why every line still carries it.",
                        "type": "string",
                        "example": "SYP"
                    },
                    "expected_amount": {
                        "description": "What the system expected: the goods cost for a supplier payment, `amount_to_collect` for a collection. Null for a desk movement.",
                        "type": "number",
                        "format": "float",
                        "example": 300,
                        "nullable": true
                    },
                    "variance": {
                        "description": "Actual minus expected. Null when nothing was expected.",
                        "type": "number",
                        "format": "float",
                        "example": 0,
                        "nullable": true
                    },
                    "has_variance": {
                        "description": "Whether the actual and the expected disagree — the flag to colour a row by, so a captain is not left comparing two numbers themselves.",
                        "type": "boolean",
                        "example": false
                    },
                    "order": {
                        "description": "Which order the movement belongs to. Null on a desk movement, which settles a balance rather than a delivery.",
                        "properties": {
                            "uuid": {
                                "description": "Opens the order this movement came from.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "order_number": {
                                "description": "The reference to show beside the amount, so a captain can match a line to a job.",
                                "type": "string",
                                "example": "ORD-100002"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "pickup": {
                        "description": "Which counter the money changed hands at, on a payment made to one supplier of a multi-supplier order. This is what turns \"the order was 4,000 short\" into \"the second shop was\", and it is the difference between an office ringing the captain and an office ringing the right shop. Null on an order collected in one tap, and on every desk movement.",
                        "properties": {
                            "uuid": {
                                "description": "The stop the payment was made at.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "store_name": {
                                "description": "The counter to name when a payment is queried. Null when the store sent no name.",
                                "type": "string",
                                "example": "بيت العود",
                                "nullable": true
                            },
                            "address": {
                                "description": "Where that counter is — enough for an office to ring the right shop.",
                                "type": "string",
                                "example": "شارع الثورة، دمشق"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "captain": {
                        "description": "Whose line it is. Present on the money feed, where every row is a different person; absent from a statement that already names one captain beside the page.",
                        "properties": {
                            "uuid": {
                                "description": "A ULID — whose line this is.",
                                "type": "string",
                                "example": "01m24x34bzfbh7resdmkm55mmq"
                            },
                            "name": {
                                "description": "The captain name, for a feed where every row is a different person.",
                                "type": "string",
                                "example": "Ahmed"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "recorded_by": {
                        "description": "Who wrote the line: the captain on their phone, or the back office.",
                        "properties": {
                            "kind": {
                                "description": "Which side entered it. A captain-entered figure is a claim from the road; a back-office one has already been through somebody at a desk.",
                                "type": "string",
                                "example": "captain",
                                "enum": [
                                    "captain",
                                    "back_office",
                                    "other"
                                ]
                            },
                            "name": {
                                "description": "Who exactly. Null when the actor is no longer on record.",
                                "type": "string",
                                "example": "Ahmed",
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "reference": {
                        "description": "Voucher or receipt number from the desk.",
                        "type": "string",
                        "example": "VCH-2001",
                        "nullable": true
                    },
                    "note": {
                        "description": "Whatever was written alongside the movement, by the captain or the desk.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the movement was recorded. A statement reads newest first.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-21 10:15:00"
                    }
                },
                "type": "object"
            },
            "CaptainLedgerFeedTotals": {
                "description": "What a filtered window of the money feed moved, in one currency.\n\n**In and out are reported apart, never netted.** A day that paid out 5,000 and took 5,000 back\nnets to zero, which tells a cashier nothing about the 10,000 that changed hands.\n\nFollowing the ledger's sign convention, `in` is what grew the company's debt to captains —\nsupplier runs and cash handed in — and `out` is what shrank it.",
                "properties": {
                    "in": {
                        "description": "What grew the debt to captains over this window - supplier runs and cash handed in. Positive.",
                        "type": "number",
                        "format": "float",
                        "example": 5000
                    },
                    "out": {
                        "description": "What shrank it - cash collected from customers and cash paid out at the desk. Negative.",
                        "type": "number",
                        "format": "float",
                        "example": -5000
                    },
                    "net": {
                        "description": "The two added together. Never show this alone: a day that paid out 5,000 and took 5,000 back nets to zero and tells a cashier nothing about the 10,000 that changed hands.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "entries": {
                        "description": "How many lines made it.",
                        "type": "integer",
                        "example": 2
                    }
                },
                "type": "object"
            },
            "CaptainBalance": {
                "properties": {
                    "captain": {
                        "description": "Whose balance this row is.",
                        "properties": {
                            "uuid": {
                                "description": "A ULID — what a settle call is addressed to.",
                                "type": "string",
                                "example": "01m24x34bzfbh7resdmkm55mmq"
                            },
                            "name": {
                                "description": "The captain name, for the desk queue.",
                                "type": "string",
                                "example": "Ahmed"
                            },
                            "phone": {
                                "description": "So the desk can call them in to settle.",
                                "type": "string",
                                "example": "+966500000001"
                            }
                        },
                        "type": "object"
                    },
                    "currency": {
                        "description": "Always `SYP`. A captain has one balance row per currency, never a combined one.",
                        "type": "string",
                        "example": "SYP"
                    },
                    "balance": {
                        "description": "Signed. Positive = the company owes the captain.",
                        "type": "number",
                        "format": "float",
                        "example": 300
                    },
                    "outstanding": {
                        "description": "The absolute amount, for the desk to count out.",
                        "type": "number",
                        "format": "float",
                        "example": 300
                    },
                    "state": {
                        "description": "Which way the balance points, so a desk does not have to read a sign. `owed` means the company owes the captain, `owes` means they are holding company cash, `clear` means square.",
                        "type": "string",
                        "example": "owed",
                        "enum": [
                            "owed",
                            "owes",
                            "clear"
                        ]
                    },
                    "state_label": {
                        "description": "The state translated for the screen.",
                        "type": "string",
                        "example": "Owed to the captain"
                    },
                    "settle_with": {
                        "description": "The movement that brings this captain back to zero. Null when square.",
                        "properties": {
                            "direction": {
                                "description": "Which way the cash has to move: `cash_paid_out` means the desk pays the captain, `cash_handed_in` means the captain brings money in. Answered here so a cashier never has to work it out from the sign of the balance.",
                                "type": "string",
                                "example": "cash_paid_out",
                                "enum": [
                                    "cash_paid_out",
                                    "cash_handed_in"
                                ]
                            },
                            "label": {
                                "description": "That direction translated for the screen — the wording to put on the button.",
                                "type": "string",
                                "example": "Reimbursed by cashier"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "entries_count": {
                        "description": "How many movements make up this balance - a hint at how much statement there is to read behind it.",
                        "type": "integer",
                        "example": 4
                    },
                    "last_movement_at": {
                        "description": "When this captain money last moved. A stale date beside a large balance is what a cash desk sorts by.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-21 10:15:00",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "CaptainLedgerTotals": {
                "description": "Per captain first, then split by sign. A captain who paid 300 and collected 380 counts once, as owing 80 — never as both owed 300 and owing 380.",
                "properties": {
                    "owed_to_captains": {
                        "description": "What the company owes captains in total.",
                        "type": "number",
                        "format": "float",
                        "example": 300
                    },
                    "owed_by_captains": {
                        "description": "What captains owe the company in total.",
                        "type": "number",
                        "format": "float",
                        "example": 380
                    },
                    "captains_owed": {
                        "description": "How many captains the company owes. Counted per person, so somebody who both paid and collected counts once, on their net position.",
                        "type": "integer",
                        "example": 1
                    },
                    "captains_owing": {
                        "description": "How many captains are holding company cash, counted the same way.",
                        "type": "integer",
                        "example": 1
                    }
                },
                "type": "object"
            },
            "CaptainBalanceBreakdown": {
                "description": "What a balance is actually made of, keyed by currency. The balance on its own is one number standing in for four different things, and two of them ask opposite actions: money the company owes a captain is theirs to claim, cash they are holding belongs to somebody else. Reported as plain positive totals with names that say the direction, so nothing has to be inferred from a sign.",
                "properties": {
                    "paid_to_suppliers": {
                        "description": "What the captain paid out of pocket at suppliers.",
                        "type": "number",
                        "format": "float",
                        "example": 140
                    },
                    "collected_from_customers": {
                        "description": "What they took from customers on delivery.",
                        "type": "number",
                        "format": "float",
                        "example": 200
                    },
                    "earned_from_deliveries": {
                        "description": "What the deliveries themselves earned them — their own pay, not money passing through their hands.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "reimbursed_by_desk": {
                        "description": "What the cashier has already paid back to them.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "handed_in_at_desk": {
                        "description": "What they have already handed in.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "adjustments": {
                        "description": "Signed, because a correction is the one entry whose meaning is \"this much, this way\" - flattening it to a magnitude would hide which way it went.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "balance": {
                        "description": "The signed net, unchanged: positive still means the company owes the captain. Every movement is inside exactly one of the parts above, so none of this balance is unaccounted for — reading them back to it means applying the direction each name states, since the parts themselves are magnitudes.",
                        "type": "number",
                        "format": "float",
                        "example": -60
                    }
                },
                "type": "object"
            },
            "CashHandIn": {
                "description": "A captain saying they are bringing the company's cash in, and what the desk did about it.\n\n**`declared_amount` is a claim, not money.** While the status is `pending` nothing in the ledger\nhas moved and the captain still owes every riyal of it: a screen drawing the declared figure as\nsettled would be telling an operator the company holds cash that is still in somebody's pocket.\n\n`confirmed_amount` is the money — it exists once somebody has counted it — and it is allowed to\ndiffer from the declaration. `shortfall` is the gap, positive when the desk received **less** than\nwas promised, which is the number worth looking at.",
                "properties": {
                    "uuid": {
                        "description": "How the declaration is addressed — what a captain sends to call their own one off.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "status": {
                        "description": "Where the declaration stands. **Only `confirmed` has moved any money**: `pending` is a claim waiting at the desk, `cancelled` is the captain calling it off, `declined` is the desk refusing it. A captain may cancel only while it is `pending`.",
                        "type": "string",
                        "example": "pending",
                        "enum": [
                            "pending",
                            "confirmed",
                            "declined",
                            "cancelled"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string",
                        "example": "Waiting for the desk"
                    },
                    "currency": {
                        "description": "Always `SYP`. A hand-in settles one currency, which is why it is named on the declaration.",
                        "type": "string",
                        "example": "SYP"
                    },
                    "declared_amount": {
                        "description": "What the captain says they are bringing. Moves nothing.",
                        "type": "number",
                        "format": "float",
                        "example": 380
                    },
                    "confirmed_amount": {
                        "description": "What the desk counted. Null until it is counted.",
                        "type": "number",
                        "format": "float",
                        "example": null,
                        "nullable": true
                    },
                    "shortfall": {
                        "description": "Declared minus confirmed. Positive means less arrived than was promised.",
                        "type": "number",
                        "format": "float",
                        "example": null,
                        "nullable": true
                    },
                    "captain": {
                        "description": "Who is bringing the cash. Present on the desk queue, where every row is a different person; absent from a captain reading their own hand-ins.",
                        "properties": {
                            "uuid": {
                                "description": "A ULID — which captain is settling.",
                                "type": "string"
                            },
                            "name": {
                                "description": "Their name, for the desk queue.",
                                "type": "string"
                            },
                            "phone": {
                                "description": "So the desk can ring them about a declaration that never arrived.",
                                "type": "string",
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "ledger_entry_uuid": {
                        "description": "The movement the confirmation wrote — the claim and the money, linked.",
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                    },
                    "decided_by": {
                        "description": "The name of whoever at the desk confirmed or declined it. Null while it waits.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "decided_at": {
                        "description": "When the desk decided. Null while it waits.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "captain_note": {
                        "description": "What the captain wrote when declaring.",
                        "type": "string",
                        "nullable": true
                    },
                    "desk_note": {
                        "description": "What the desk wrote when deciding — usually why a count fell short, or why it was declined.",
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the captain declared. How long a hand-in has been waiting is read from this.",
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "City": {
                "description": "A city, or a district inside one, with the flat amount a captain earns for delivering there.\n\n**The tree is two deep.** A city holds districts; a district holds nothing. The depth is capped\nbecause what a captain is paid has to be explainable to that captain in one sentence.\n\n`delivery_earning` is always the figure **in force on this row**, whether it was typed here or\ncopied down from the city. `earning_source` is what says which, and it is the field an editing\nscreen turns on: a district marked `inherited` follows its city, and one marked `own` is a\ndecision somebody took that a later cascade must not silently destroy.\n\nThe geofence is a centre and a radius rather than a polygon: a hand-drawn boundary is a\nmaintenance job nobody does twice, and a radius is a figure an operations manager can correct\nfrom a map in seconds.",
                "properties": {
                    "uuid": {
                        "description": "How the area is addressed.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "name": {
                        "description": "What the area is called — a city, or a district inside one.",
                        "type": "string",
                        "example": "Mezzeh"
                    },
                    "is_district": {
                        "description": "Whether this sits inside a city rather than being one. A district may set its own delivery rate or inherit its city's.",
                        "type": "boolean",
                        "example": true
                    },
                    "parent_uuid": {
                        "description": "The city this district belongs to. Null on a city.",
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                    },
                    "parent_name": {
                        "description": "The parent city's name, so a district can be shown in full without a second lookup.",
                        "type": "string",
                        "example": "Damascus",
                        "nullable": true
                    },
                    "lat": {
                        "description": "Centre of the area. A drop-off falls inside it when it lands within `radius_m` of this point.",
                        "type": "number",
                        "format": "float",
                        "example": 33.50750000000000028421709430404007434844970703125
                    },
                    "lng": {
                        "description": "Longitude of the area centre, paired with `lat`.",
                        "type": "number",
                        "format": "float",
                        "example": 36.24000000000000198951966012828052043914794921875
                    },
                    "radius_m": {
                        "description": "How far the area reaches from its centre, in metres.",
                        "type": "integer",
                        "example": 1000
                    },
                    "delivery_earning": {
                        "description": "What one delivery here earns a captain.",
                        "type": "number",
                        "format": "float",
                        "example": 80
                    },
                    "earning_source": {
                        "description": "Whether `delivery_earning` was set on this area or taken from its parent city. It matters when editing: changing a city's rate moves every district still inheriting it.",
                        "type": "string",
                        "example": "own",
                        "enum": [
                            "own",
                            "inherited"
                        ]
                    },
                    "earning_source_label": {
                        "description": "The source translated for the screen.",
                        "type": "string",
                        "example": "Its own rate"
                    },
                    "is_active": {
                        "description": "An inactive area is skipped when a drop-off is placed, and keeps its history.",
                        "type": "boolean",
                        "example": true
                    },
                    "districts": {
                        "description": "Present on a city read as part of the tree; null on a district.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/City"
                        },
                        "nullable": true
                    },
                    "districts_with_own_earning": {
                        "description": "How many districts would be overwritten by a rate change here. The dashboard warns with this rather than asking a second time.",
                        "type": "integer",
                        "example": 1,
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the area was added.",
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "DeliveryEarning": {
                "description": "One delivery's earning, and the record of where the figure came from.\n\nThe money itself is a `delivery_earning` entry in the captain's ledger — this row is the\nexplanation that outlives every later edit of the rate. The amount is **copied at the moment of\ndelivery**, so raising a district's rate tomorrow does not restate what captains were paid last\nweek.\n\n**`status: unresolved` means the delivery earned nothing**, because the drop-off fell inside no\narea on record or the order carried no coordinates. Such a row has a zero amount, no area and no\nledger entry, and it is written rather than skipped: a delivery nobody was paid for has to be\nvisible before payday, and `lat`/`lng` are the evidence for where an area is missing from the map.",
                "properties": {
                    "uuid": {
                        "description": "What one delivery earned a captain.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "status": {
                        "description": "credited - money moved. unresolved - the drop-off matched no area on record, so there was no rate to pay; this is the queue somebody works through. salaried - the area WAS found and the arrangement pays nothing per delivery, which is a policy rather than a gap. Keeping the last two apart is what stops a missing district being buried under a hundred employee trips.",
                        "type": "string",
                        "example": "credited",
                        "enum": [
                            "credited",
                            "unresolved",
                            "salaried"
                        ]
                    },
                    "status_label": {
                        "type": "string",
                        "example": "Paid"
                    },
                    "currency": {
                        "type": "string",
                        "example": "SYP"
                    },
                    "amount": {
                        "description": "Zero on an unresolved row.",
                        "type": "number",
                        "format": "float",
                        "example": 80
                    },
                    "earning_source": {
                        "description": "Whether the rate was the district's own or its city's, at the time.",
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "own",
                            "inherited"
                        ]
                    },
                    "earning_source_label": {
                        "type": "string",
                        "nullable": true
                    },
                    "employment_type": {
                        "description": "The captain's arrangement at the moment of the delivery. A freelancer earns the whole area rate, because per-delivery pay is their income; an employee is on a wage and earns a share of it as an incentive. Null on rows written before the arrangement was recorded - backfilling from a captain's CURRENT type would be a guess dressed as a record.",
                        "type": "string",
                        "example": "freelance",
                        "nullable": true,
                        "enum": [
                            "employee",
                            "freelance"
                        ]
                    },
                    "employment_type_label": {
                        "type": "string",
                        "nullable": true
                    },
                    "applied_share": {
                        "description": "The share of the area rate this delivery paid: 1 for a freelancer, the employee share for an employee. Recorded per delivery because the share is a setting somebody retunes, and a retune must not restate what was already paid.",
                        "type": "number",
                        "format": "float",
                        "example": 1,
                        "nullable": true
                    },
                    "city": {
                        "properties": {
                            "uuid": {
                                "type": "string",
                                "format": "uuid"
                            },
                            "name": {
                                "type": "string",
                                "example": "Mezzeh"
                            },
                            "parent_name": {
                                "type": "string",
                                "example": "Damascus",
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "captain": {
                        "properties": {
                            "uuid": {
                                "description": "ULID",
                                "type": "string"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "order": {
                        "properties": {
                            "uuid": {
                                "type": "string",
                                "format": "uuid"
                            },
                            "order_number": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "lat": {
                        "description": "The point the resolution ran against.",
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "lng": {
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "DeliveryFeeTier": {
                "description": "A range of merchandise value, and what the delivery costs **the store** inside it. A band whose\n`fee` is zero is the free-delivery offer.\n\n**This prices our invoice, not the customer's receipt.** `orders.fee` is the company's revenue;\n`orders.amount_to_collect` is what the shop told its customer to pay, and a ladder that lowered it\nwould be rewriting a figure somebody has already been given. A shop passing free delivery on to its\ncustomer lowers the amount to collect itself, when it sends the order.\n\n**`min_goods_value` is inclusive and `max_goods_value` is exclusive**, so adjacent bands meet\nwithout overlapping and a basket worth exactly 100,000 belongs to one of them. A null ceiling means\n\"and above\", which is where free delivery usually lives. Overlapping bands are refused outright\nrather than resolved by priority.\n\n**A ladder belongs either to one store or to everybody.** `store` null is the company default; a\nstore with bands of its own is priced by **those alone**, never by a mixture of the two.",
                "properties": {
                    "uuid": {
                        "description": "One band of a delivery pricing ladder.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "store": {
                        "description": "Null names the company ladder, which every store without its own falls back to.",
                        "properties": {
                            "uuid": {
                                "type": "string",
                                "format": "uuid"
                            },
                            "name": {
                                "type": "string",
                                "example": "Al Nour Sweets"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "min_goods_value": {
                        "description": "Inclusive floor.",
                        "type": "number",
                        "format": "float",
                        "example": 3000
                    },
                    "max_goods_value": {
                        "description": "Exclusive ceiling; null means \"and above\".",
                        "type": "number",
                        "format": "float",
                        "example": null,
                        "nullable": true
                    },
                    "fee": {
                        "description": "What the delivery costs the store in this band.",
                        "type": "number",
                        "format": "float",
                        "example": 0
                    },
                    "is_free": {
                        "description": "Carried rather than left for a screen to infer from `fee === 0`: free delivery is what these ladders exist for.",
                        "type": "boolean",
                        "example": true
                    },
                    "is_active": {
                        "type": "boolean",
                        "example": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Driver": {
                "description": "A captain application as exposed by the driver resources.",
                "properties": {
                    "uuid": {
                        "description": "A ULID, not a UUID, despite the format hint — how a captain is named everywhere, including in a handover request.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01m24x34bzfbh7resdmkm55mmq"
                    },
                    "name": {
                        "description": "The captain's full name. Set at registration and changed only by the back office, never from the app.",
                        "type": "string",
                        "example": "Abdulaziz Al Ajlan"
                    },
                    "phone": {
                        "description": "Their sign-in identity: the number the OTP goes to. Unique across the fleet and not editable from the app.",
                        "type": "string",
                        "example": "+966500000008"
                    },
                    "email": {
                        "description": "Optional, and the one contact detail the captain may change themselves.",
                        "type": "string",
                        "example": "aziz.free@example.com",
                        "nullable": true
                    },
                    "national_id": {
                        "description": "Identity document number, unique across the fleet.",
                        "type": "string",
                        "example": "1000000008"
                    },
                    "date_of_birth": {
                        "description": "Back office only, like the name — the app cannot change it.",
                        "type": "string",
                        "format": "date",
                        "example": "1991-11-28"
                    },
                    "employment_type": {
                        "description": "The arrangement, and it decides whether an order can be **directed** rather than offered. An employee may be told what to carry, so their orders can arrive already `accepted`; a freelancer is always offered and always free to refuse.",
                        "type": "string",
                        "example": "freelance",
                        "enum": [
                            "employee",
                            "freelance"
                        ]
                    },
                    "employment_type_label": {
                        "description": "The arrangement translated for the screen.",
                        "type": "string",
                        "example": "Freelance captain"
                    },
                    "status": {
                        "description": "Where the application stands. Only `approved` can work; `documents_required` is the one state the app acts on, by sending fresh files to `POST /documents`.",
                        "type": "string",
                        "example": "approved",
                        "enum": [
                            "pending",
                            "documents_required",
                            "approved",
                            "rejected",
                            "suspended"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string",
                        "example": "Approved"
                    },
                    "review_note": {
                        "description": "What the reviewer said — why documents were asked for again, or why the application was refused. Show it whenever it is present.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "reviewed_at": {
                        "description": "When the back office last decided on this application. Null while it has never been reviewed.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-12 10:21:59",
                        "nullable": true
                    },
                    "can_receive_orders": {
                        "description": "Whether this captain may be given work at all — approved, active and not suspended. **It is not a live availability flag**: a captain can be true here and still be offline. Availability lives on `GET /availability`.",
                        "type": "boolean",
                        "example": true
                    },
                    "driving_license_number": {
                        "description": "As printed on the licence.",
                        "type": "string",
                        "example": "DL-10008"
                    },
                    "driving_license_expires_at": {
                        "description": "When the licence runs out. The back office watches this and can put the captain back into `documents_required`.",
                        "type": "string",
                        "format": "date",
                        "example": "2029-09-12"
                    },
                    "is_active": {
                        "description": "Whether the account is switched on. A deactivated captain cannot sign in, which is separate from being suspended and separate again from being offline.",
                        "type": "boolean",
                        "example": true
                    },
                    "documents": {
                        "description": "Only present when the media collection is loaded.",
                        "properties": {
                            "driving_license": {
                                "description": "The licence on file. Null when none has been uploaded yet — which is what `documents_required` usually means.",
                                "type": "string",
                                "format": "url",
                                "example": "http://localhost/kapitano_logistic/storage/images/10-09-2026/04/3/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%85%D9%84%D8%A7%D8%A8%D8%B3.png",
                                "nullable": true
                            },
                            "profile_photo": {
                                "description": "The captain photo on file, shown on their own profile screen.",
                                "type": "string",
                                "format": "url",
                                "example": "http://localhost/kapitano_logistic/storage/images/10-09-2026/04/4/Mask.png",
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "vehicle": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/Vehicle"
                            }
                        ],
                        "nullable": true,
                        "description": "The car assigned to this captain, when the relation was loaded. Null when they have none on record."
                    },
                    "created_at": {
                        "description": "When the application was submitted — not when it was approved, which is `reviewed_at`.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-10 08:36:47"
                    }
                },
                "type": "object"
            },
            "Vehicle": {
                "description": "A vehicle belonging to a captain.",
                "properties": {
                    "uuid": {
                        "description": "How the vehicle is addressed.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a089d1-97c8-7108-bcde-a4ede59fd004"
                    },
                    "ownership_type": {
                        "description": "Whose car it is, and **whether the captain may edit it at all**: `POST /vehicle` answers 403 on a company car, which the back office maintains.",
                        "type": "string",
                        "example": "personal",
                        "enum": [
                            "company_owned",
                            "personal"
                        ]
                    },
                    "ownership_type_label": {
                        "description": "The ownership translated for the screen.",
                        "type": "string",
                        "example": "Personal vehicle owned by the applicant"
                    },
                    "vehicle_type": {
                        "description": "What the captain drives. Dispatch reads it when an order needs a particular kind of vehicle.",
                        "type": "string",
                        "example": "car",
                        "nullable": true,
                        "enum": [
                            "motorcycle",
                            "car",
                            "van",
                            "pickup_truck",
                            "truck"
                        ]
                    },
                    "vehicle_type_label": {
                        "description": "The vehicle type translated for the screen.",
                        "type": "string",
                        "example": "Car",
                        "nullable": true
                    },
                    "plate_number": {
                        "description": "The registration plate, unique across the fleet. Null on a company car the office has not filled in.",
                        "type": "string",
                        "example": "AZZ-8008",
                        "nullable": true
                    },
                    "brand": {
                        "description": "Manufacturer, as the captain entered it.",
                        "type": "string",
                        "example": "GMC",
                        "nullable": true
                    },
                    "model": {
                        "description": "Model name, as the captain entered it.",
                        "type": "string",
                        "example": "Terrain",
                        "nullable": true
                    },
                    "manufacture_year": {
                        "description": "Year of manufacture.",
                        "type": "integer",
                        "example": 2021,
                        "nullable": true
                    },
                    "color": {
                        "description": "Body colour — what a shop looks for when the captain pulls up.",
                        "type": "string",
                        "example": "red",
                        "nullable": true
                    },
                    "registration_number": {
                        "description": "The registration document number.",
                        "type": "string",
                        "example": "REG-8008",
                        "nullable": true
                    },
                    "registration_expires_at": {
                        "description": "When the registration runs out. `registration_status` is worked out from this.",
                        "type": "string",
                        "format": "date",
                        "example": "2027-09-30",
                        "nullable": true
                    },
                    "registration_status": {
                        "description": "Worked out on the day of the request; expiring_soon = within 30 days.",
                        "type": "string",
                        "example": "valid",
                        "enum": [
                            "missing",
                            "expired",
                            "expiring_soon",
                            "valid"
                        ]
                    },
                    "registration_status_label": {
                        "description": "The registration status translated for the screen.",
                        "type": "string",
                        "example": "Valid"
                    },
                    "insurance_policy_number": {
                        "description": "The insurance policy number.",
                        "type": "string",
                        "example": "INS-8008",
                        "nullable": true
                    },
                    "insurance_expires_at": {
                        "description": "When cover ends. `insurance_status` is worked out from this.",
                        "type": "string",
                        "format": "date",
                        "example": "2027-02-28",
                        "nullable": true
                    },
                    "insurance_status": {
                        "description": "Worked out on the day of the request, like the registration one; `expiring_soon` means within 30 days. Worth surfacing in the app — it is the kind of thing a captain finds out about at the roadside.",
                        "type": "string",
                        "example": "valid",
                        "enum": [
                            "missing",
                            "expired",
                            "expiring_soon",
                            "valid"
                        ]
                    },
                    "insurance_status_label": {
                        "description": "The insurance status translated for the screen.",
                        "type": "string",
                        "example": "Valid"
                    },
                    "driver": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/Driver"
                            }
                        ],
                        "nullable": true,
                        "description": "Present on the vehicle endpoints (dashboard and captain app), where the captain is loaded; absent inside a captain record."
                    },
                    "created_at": {
                        "description": "When the vehicle record was created.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-10 08:36:47"
                    },
                    "updated_at": {
                        "description": "When it was last changed, by the captain or the office.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-12 10:21:59"
                    },
                    "images": {
                        "description": "Only present when the media collection is loaded.",
                        "properties": {
                            "vehicle_image": {
                                "description": "A photo of the car itself. Null when none was uploaded.",
                                "type": "string",
                                "format": "url",
                                "example": "http://localhost/kapitano_logistic/storage/images/10-09-2026/04/1/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%85%D9%84%D8%A7%D8%A8%D8%B3.png",
                                "nullable": true
                            },
                            "mechanics_image": {
                                "description": "A photo of the mechanical inspection paperwork. Null when none was uploaded.",
                                "type": "string",
                                "format": "url",
                                "example": "http://localhost/kapitano_logistic/storage/images/10-09-2026/04/2/logo-N.png",
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "is_active": {
                        "description": "Whether the vehicle is in service. An inactive one stops its captain being offered work.",
                        "type": "boolean",
                        "example": true
                    }
                },
                "type": "object"
            },
            "Order": {
                "description": "A delivery order as the back office sees it (internal note included).",
                "properties": {
                    "uuid": {
                        "description": "How every other endpoint addresses this order. The numeric id is never exposed.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a089d1-9dc5-7207-b8ec-928fa322e342"
                    },
                    "order_number": {
                        "description": "Our human reference, quoted on the phone by the office and the captain. A wrapped order collection leg carries its parent number with a `-C` suffix.",
                        "type": "string",
                        "example": "ORD-100002"
                    },
                    "customer_name": {
                        "description": "Who receives the parcel. **On a collection leg this holds the wrapping shop, not a person** — see `leg`.",
                        "type": "string",
                        "example": "Khalid Al Ghamdi"
                    },
                    "customer_phone": {
                        "description": "How to reach the recipient. Null on a collection leg, and on a customer who left no number.",
                        "type": "string",
                        "example": "+966500000101",
                        "nullable": true
                    },
                    "pickup_address": {
                        "description": "The first stop, mirrored from `pickups[0]`. With several suppliers, read `pickups` for the rest.",
                        "type": "string",
                        "example": "Store 12, Granada Mall, Riyadh"
                    },
                    "dropoff_address": {
                        "description": "The delivery address.",
                        "type": "string",
                        "example": "Olaya Street, Riyadh"
                    },
                    "pickup_lat": {
                        "description": "The first stop as a coordinate. Null when the address could not be placed on the map, which also keeps the order out of distance-based dispatch.",
                        "type": "number",
                        "format": "float",
                        "example": 24.803625499999998993416738812811672687530517578125,
                        "nullable": true
                    },
                    "pickup_lng": {
                        "description": "Longitude of the first stop, paired with `pickup_lat`.",
                        "type": "number",
                        "format": "float",
                        "example": 46.69935459999999949332050164230167865753173828125,
                        "nullable": true
                    },
                    "dropoff_lat": {
                        "description": "Where the order ends: the customer, or the wrapping shop on a collection leg.",
                        "type": "number",
                        "format": "float",
                        "example": 24.6887535999999983005182002671062946319580078125,
                        "nullable": true
                    },
                    "dropoff_lng": {
                        "description": "Longitude of the drop-off, paired with `dropoff_lat`.",
                        "type": "number",
                        "format": "float",
                        "example": 46.680810600000000931686372496187686920166015625,
                        "nullable": true
                    },
                    "customer_note": {
                        "description": "What the customer asked for; shown to the captain.",
                        "type": "string",
                        "example": "Call on arrival.",
                        "nullable": true
                    },
                    "note": {
                        "description": "Internal note for the operations team; never shown to the captain.",
                        "type": "string",
                        "example": "Repeat customer.",
                        "nullable": true
                    },
                    "fee": {
                        "description": "What we charge for the delivery. Zero on a waived one — see `fee_waived` — and zero on a collection leg, which earns no delivery rate of its own.",
                        "type": "number",
                        "format": "float",
                        "example": 18.5,
                        "nullable": true
                    },
                    "currency": {
                        "description": "Always `SYP`. Kept on the row because ledger balances are grouped by it.",
                        "type": "string",
                        "example": "SYP",
                        "nullable": true
                    },
                    "payment_method": {
                        "description": "How the customer pays. It says nothing about whether the money arrived — that is `payment_status`.",
                        "type": "string",
                        "example": "cash_on_delivery",
                        "enum": [
                            "cash_on_delivery",
                            "prepaid"
                        ]
                    },
                    "payment_method_label": {
                        "description": "The payment method translated for the screen.",
                        "type": "string",
                        "example": "Cash on delivery"
                    },
                    "quoted_fee": {
                        "description": "The delivery fee the caller asked for, when the pricing ladder overruled it. Null when nobody stated one, or when no rule had an opinion. The ladder DOES overrule a stated fee - a store integration that always sends the same number would otherwise never give anybody free delivery - so this is what keeps the override a record rather than a silent edit.",
                        "type": "number",
                        "format": "float",
                        "example": 18000,
                        "nullable": true
                    },
                    "fee_priced_by_rule": {
                        "description": "Whether a pricing band decided the fee on this order.",
                        "type": "boolean",
                        "example": true
                    },
                    "fee_waived": {
                        "description": "Free delivery: a band priced this order at nothing. Carried on every read INCLUDING the list, because a waived delivery would otherwise look identical to a shop that never charged for one.",
                        "type": "boolean",
                        "example": true
                    },
                    "fee_rule": {
                        "description": "The band that decided it, on the reads that load it. Null on an order priced by whoever sent it, and on one whose band has since been retired - the fee itself is a column, so retiring a band never rewrites what was charged.",
                        "properties": {
                            "uuid": {
                                "description": "Identifies the band, so a fee can be traced to the rule that set it.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "min_goods_value": {
                                "description": "The lowest basket this band applies to, inclusive.",
                                "type": "number",
                                "format": "float",
                                "example": 300000
                            },
                            "max_goods_value": {
                                "description": "Null means \"and above\".",
                                "type": "number",
                                "format": "float",
                                "example": null,
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "amount_to_collect": {
                        "description": "Cash the captain collects; always null for prepaid. NOT touched by the pricing ladder: it is what the shop told its customer to pay.",
                        "type": "number",
                        "format": "float",
                        "example": 92.5,
                        "nullable": true
                    },
                    "status": {
                        "description": "Where the order stands. The last three are final. Note that `pending` alone does not mean assignable — a wrapped delivery leg waits in `pending` too, which is what `can_be_assigned` is for.",
                        "type": "string",
                        "example": "on_the_way",
                        "enum": [
                            "pending",
                            "assigned",
                            "accepted",
                            "picked_up",
                            "on_the_way",
                            "delivered",
                            "delivery_failed",
                            "cancelled"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string",
                        "example": "On the way"
                    },
                    "payment_status": {
                        "description": "Whether the money actually moved, which the payment *method* cannot say. Null on orders written before this existed - guessing would be worse than admitting we do not know, so a missing value must never be drawn as unpaid.",
                        "type": "string",
                        "example": "unpaid",
                        "nullable": true,
                        "enum": [
                            "paid",
                            "unpaid",
                            "refunded"
                        ]
                    },
                    "payment_status_label": {
                        "description": "The payment status translated for the screen. Null wherever the status itself is.",
                        "type": "string",
                        "example": "Unpaid",
                        "nullable": true
                    },
                    "payment_reference": {
                        "description": "The reference the store gave for the payment, when they sent one.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "payment_verified_at": {
                        "description": "When a prepaid order was confirmed as paid.",
                        "type": "string",
                        "format": "date-time",
                        "example": null,
                        "nullable": true
                    },
                    "source": {
                        "description": "Where the order came from. Branch on this and never on `store`: the shop name is absent from the create and assign responses, and keying off it there labels a shop own order as back-office.",
                        "type": "string",
                        "example": "store_api",
                        "nullable": true,
                        "enum": [
                            "dashboard",
                            "store_api"
                        ]
                    },
                    "external_order_id": {
                        "description": "The reference the shop knows it by, and the one they will quote at us.",
                        "type": "string",
                        "example": "SO-77120",
                        "nullable": true
                    },
                    "external_order_number": {
                        "description": "The shop reference with any prefix stripped, for showing in a narrow column. `external_order_id` is the value to match on.",
                        "type": "string",
                        "example": "77120",
                        "nullable": true
                    },
                    "store": {
                        "description": "The shop that sent it, on the reads that load it.",
                        "properties": {
                            "uuid": {
                                "description": "Opens the store record.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "name": {
                                "description": "The shop trading name, for a column heading or a filter chip.",
                                "type": "string",
                                "example": "متجر دمشق"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "leg": {
                        "description": "Which half of a wrapped delivery this row is, and null for the ordinary order - nearly all of them. Some stores have their goods wrapped before delivery: such an order is TWO rows, a collection leg that gathers the goods from the suppliers and leaves them with the wrapper, and a delivery leg - the store's own order - that takes the finished parcel to the customer. Two rows because the first captain is released the moment they hand the goods over.",
                        "type": "string",
                        "example": null,
                        "nullable": true,
                        "enum": [
                            "collection",
                            "delivery"
                        ]
                    },
                    "leg_label": {
                        "description": "The leg translated for the screen. Null on an ordinary order, exactly as `leg` is.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "parent_order": {
                        "description": "The customer order a collection leg is fetching goods for. Only ever set on a collection leg, whose own customer_name is the wrapping shop.",
                        "properties": {
                            "uuid": {
                                "description": "Opens the customer order this leg is buying for.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "order_number": {
                                "description": "The parent reference — this leg carries the same number with a `-C` suffix.",
                                "type": "string",
                                "example": "ORD-100002"
                            },
                            "status": {
                                "description": "Where the customer order stands while this leg fetches its goods.",
                                "type": "string",
                                "example": "pending"
                            },
                            "status_label": {
                                "description": "That status translated for the screen.",
                                "type": "string",
                                "example": "Pending"
                            },
                            "customer_name": {
                                "description": "The real recipient — the one name a collection leg does not carry on its own row.",
                                "type": "string",
                                "example": "Khalid Al Ghamdi"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "collection_legs": {
                        "description": "The internal orders fetching the goods for this delivery. Present on the reads that load them - the order detail and GET /orders/awaiting-collection.",
                        "type": "array",
                        "items": {
                            "properties": {
                                "uuid": {
                                    "description": "Opens the collection leg.",
                                    "type": "string",
                                    "format": "uuid"
                                },
                                "order_number": {
                                    "description": "This delivery number with a `-C` suffix.",
                                    "type": "string",
                                    "example": "ORD-100002-C"
                                },
                                "status": {
                                    "description": "Where the collection stands. Until it reads `delivered` the goods have not reached the wrapper, and this delivery cannot be assigned.",
                                    "type": "string",
                                    "example": "delivered"
                                },
                                "status_label": {
                                    "description": "That status translated for the screen.",
                                    "type": "string",
                                    "example": "Delivered"
                                },
                                "failed_reason": {
                                    "description": "A collection leg that failed blocks its delivery for good - the goods never arrived.",
                                    "type": "string",
                                    "example": null,
                                    "nullable": true
                                }
                            },
                            "type": "object"
                        }
                    },
                    "can_be_assigned": {
                        "description": "Whether a captain may be sent for this order yet. A wrapped order's delivery leg sits in plain pending while its goods are still being collected, so its status alone cannot be told apart from an order that could be handed out now. ABSENT is not false: it is derived from collection_legs and is only sent where they are loaded. Treat it as blocking only when it is explicitly false.",
                        "type": "boolean",
                        "example": false
                    },
                    "assignment_blocked_reason": {
                        "description": "Why not, in the language the reader asked for. Null when nothing is in the way. Assignment answers 409 with the same sentence.",
                        "type": "string",
                        "example": "The goods for this order have not arrived at the wrapping location yet - collection ORD-100002-C is Pending. A captain cannot be sent until they do.",
                        "nullable": true
                    },
                    "offer_expires_at": {
                        "description": "When an unanswered offer is taken back and the order returns to the pool.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-26T14:20:30+03:00",
                        "nullable": true
                    },
                    "accepted_at": {
                        "description": "When the captain accepted. Null while the offer is still open.",
                        "type": "string",
                        "format": "date-time",
                        "example": null,
                        "nullable": true
                    },
                    "driver": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/Driver"
                            }
                        ],
                        "nullable": true,
                        "description": "The captain holding the order, on the reads that load them. Stays set on a cancelled order, so the record shows who was carrying it when it ended."
                    },
                    "items": {
                        "description": "The lines on the order. Where the store said which supplier each comes from, the same lines appear again split across `pickups[].items`.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        },
                        "example": []
                    },
                    "items_expected": {
                        "description": "Sum of the product quantities.",
                        "type": "integer",
                        "example": 3
                    },
                    "items_collected": {
                        "description": "Count the captain confirmed at pickup; null if not confirmed.",
                        "type": "integer",
                        "example": 2,
                        "nullable": true
                    },
                    "items_mismatch": {
                        "description": "True when the confirmed count differs from items_expected.",
                        "type": "boolean",
                        "example": true
                    },
                    "pickups": {
                        "description": "Every store the order is collected from, each with what was confirmed there. items_mismatch says an order was short; this says which counter was.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderPickup"
                        }
                    },
                    "history": {
                        "description": "Every status the order has been through, with who moved it and when. On the detail read only, oldest first.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderHistory"
                        },
                        "example": []
                    },
                    "cancelled_at": {
                        "description": "Only ever set on an order that ended that way.",
                        "type": "string",
                        "format": "date-time",
                        "example": null,
                        "nullable": true
                    },
                    "cancel_reason": {
                        "description": "Why the order was called off. Always present on a cancelled order - the endpoint requires it.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "failed_reason": {
                        "description": "Why the delivery was given up on. A reason is required to fail an order, so it is never null on a failed one.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "proof_of_delivery": {
                        "description": "The photo the captain sent with the delivery, and the only evidence behind a disputed one. Null until an order is delivered with a photo.",
                        "type": "string",
                        "format": "uri",
                        "example": "https://api.kapitano.shop/storage/42/doorstep.jpg",
                        "nullable": true
                    },
                    "amount_paid": {
                        "description": "What a captain paid the supplier for this order.",
                        "type": "number",
                        "format": "float",
                        "example": 300,
                        "nullable": true
                    },
                    "amount_variance": {
                        "description": "What the whole order came to against what it should have, signed: negative means less was paid than the goods came to. The figure a captain wants at the end of a multi-supplier collection, when the per-stop numbers are three screens back.",
                        "type": "number",
                        "format": "float",
                        "example": -4,
                        "nullable": true
                    },
                    "amount_collected": {
                        "description": "What a captain took from the customer for this order.",
                        "type": "number",
                        "format": "float",
                        "example": 380,
                        "nullable": true
                    },
                    "settlement": {
                        "description": "On the detail read only. Every movement of money on the order and the captain behind each - the captain who paid and the captain who collected need not be the same person.",
                        "properties": {
                            "expected_goods_cost": {
                                "description": "What the CAPTAIN is expected to pay suppliers. Null on a wrapped delivery leg, which buys nothing because its collection leg already did.",
                                "type": "number",
                                "format": "float",
                                "example": 300,
                                "nullable": true
                            },
                            "goods_value": {
                                "description": "What the items are worth to the CUSTOMER: quantity x unit_price on this row, whoever paid for them. Present on a wrapped delivery leg where `expected_goods_cost` is null, because the parcel is still what the customer is charged for. Null when no line carries a price.",
                                "type": "number",
                                "format": "float",
                                "example": 75000,
                                "nullable": true
                            },
                            "delivery_fee": {
                                "description": "The delivery fee. A PART of `customer_total`, not an extra on top of it.",
                                "type": "number",
                                "format": "float",
                                "example": 18000,
                                "nullable": true
                            },
                            "customer_total": {
                                "description": "What the customer owes for this order, delivery included. `amount_to_collect` when the order states one - a store that sent a total has stated the total - otherwise `goods_value` + `delivery_fee` added up, which is the prepaid case. Null when neither is known: a delivery fee alone is not an order total.",
                                "type": "number",
                                "format": "float",
                                "example": 93000,
                                "nullable": true
                            },
                            "customer_total_is_computed": {
                                "description": "True when the total above was added up here rather than stated by the order, which happens on a prepaid order that collects nothing. A figure the system worked out and a figure a store stated are not equally trustworthy, and a screen should be able to say which it shows.",
                                "type": "boolean",
                                "example": false
                            },
                            "total_mismatch": {
                                "description": "The stated total minus its own parts, or null when a part is unknown. Positive means the customer is asked for more than the goods and the delivery come to. NOT an error: a discount, a deposit already paid, or a rounding all live here - but nothing in the system enforces the relationship between the two columns, so a non-zero figure is how an order entered wrongly becomes visible instead of being averaged into a report.",
                                "type": "number",
                                "format": "float",
                                "example": 0,
                                "nullable": true
                            },
                            "amount_to_collect": {
                                "description": "What the customer was due to hand over, repeated here so the settlement block reads on its own.",
                                "type": "number",
                                "format": "float",
                                "example": 380,
                                "nullable": true
                            },
                            "amount_paid": {
                                "description": "What the captain reported paying suppliers on this order.",
                                "type": "number",
                                "format": "float",
                                "example": 300,
                                "nullable": true
                            },
                            "amount_collected": {
                                "description": "What the captain reported taking from the customer.",
                                "type": "number",
                                "format": "float",
                                "example": 380,
                                "nullable": true
                            },
                            "amount_variance": {
                                "description": "Paid minus expected, signed: negative means less was paid than the goods came to. Null when either half is unknown.",
                                "type": "number",
                                "format": "float",
                                "example": -4,
                                "nullable": true
                            },
                            "cash_flow": {
                                "description": "The same money read as the ORDER's cash flow: negative for what went out on goods, positive for what came in from the customer. Each entry's own `amount` below is signed the other way because it answers a different question - what the company owes the captain. A captain who spends their own money at a supplier is owed it, so the same event is +90 there and -90 here. Both are on the page on purpose.",
                                "properties": {
                                    "goods_paid": {
                                        "description": "What left the company for goods on this order. Negative, or zero when nothing was paid.",
                                        "type": "number",
                                        "format": "float",
                                        "example": -140
                                    },
                                    "cash_collected": {
                                        "description": "What came in from the customer. Positive, or zero.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 200
                                    },
                                    "net": {
                                        "description": "The two above added together: what this row made or cost.",
                                        "type": "number",
                                        "format": "float",
                                        "example": 60
                                    },
                                    "across_legs": {
                                        "description": "Only on the delivery leg of a wrapped order. Such an order buys its goods on one row and takes the customer cash on the other, so this row alone reads \"money in, nothing out\" for an order that cost something to fulfil - true of the row, and a lie about the order. This adds the collection legs in. Absent on an ordinary order, where the figures above already are the whole story.",
                                        "properties": {
                                            "goods_paid": {
                                                "description": "What left the company for goods across every leg of this order. Negative.",
                                                "type": "number",
                                                "format": "float",
                                                "example": -140
                                            },
                                            "cash_collected": {
                                                "description": "What came in from the customer across every leg. Positive.",
                                                "type": "number",
                                                "format": "float",
                                                "example": 200
                                            },
                                            "net": {
                                                "description": "The whole order, both legs together — the figure to judge a wrapped order by.",
                                                "type": "number",
                                                "format": "float",
                                                "example": 60
                                            }
                                        },
                                        "type": "object"
                                    }
                                },
                                "type": "object"
                            },
                            "entries": {
                                "description": "Every movement of money recorded against this order, newest first. The captain who paid the supplier and the captain who collected from the customer need not be the same person, which is why each entry names its own.",
                                "type": "array",
                                "items": {
                                    "properties": {
                                        "uuid": {
                                            "description": "Identifies the movement in the captain ledger.",
                                            "type": "string",
                                            "format": "uuid"
                                        },
                                        "type": {
                                            "description": "What kind of movement it was. Only the first two normally appear against an order; desk movements settle a balance rather than a delivery.",
                                            "type": "string",
                                            "enum": [
                                                "supplier_payment",
                                                "cash_collected",
                                                "delivery_earning",
                                                "cash_paid_out",
                                                "cash_handed_in",
                                                "adjustment"
                                            ]
                                        },
                                        "type_label": {
                                            "description": "The movement type translated for the screen.",
                                            "type": "string"
                                        },
                                        "amount": {
                                            "description": "Signed for the CAPTAIN: positive = the company owes them. A supplier payment is positive here.",
                                            "type": "number",
                                            "format": "float"
                                        },
                                        "order_amount": {
                                            "description": "The same figure signed for the ORDER: negative for money out. Null for a desk movement or an adjustment, which have no direction of their own here - reimbursing a captain moves money that was already counted when the goods were bought.",
                                            "type": "number",
                                            "format": "float",
                                            "example": -90,
                                            "nullable": true
                                        },
                                        "currency": {
                                            "description": "Always `SYP`. Ledger balances are grouped by it.",
                                            "type": "string"
                                        },
                                        "expected_amount": {
                                            "description": "What the system expected here: the goods cost on a supplier payment, the amount due on a collection. Null on a desk movement, which nothing was expected of.",
                                            "type": "number",
                                            "format": "float",
                                            "nullable": true
                                        },
                                        "variance": {
                                            "description": "Actual minus expected. Null when nothing was expected — a difference from a missing number is not a difference.",
                                            "type": "number",
                                            "format": "float",
                                            "nullable": true
                                        },
                                        "captain": {
                                            "description": "Who made this movement. Worth reading per entry rather than off the order: on a wrapped order the buying and collecting captains differ.",
                                            "properties": {
                                                "uuid": {
                                                    "description": "A ULID identifying the captain.",
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "description": "Their name, to show beside the amount.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "nullable": true
                                        },
                                        "created_at": {
                                            "description": "When the movement was recorded.",
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the order was placed. The list is ordered by this, newest first.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-10 08:36:51"
                    }
                },
                "type": "object"
            },
            "OrderPickup": {
                "description": "A store the order is collected from. An order has at least one and at most three; they are visited in `sequence` order, and all of them before the customer.",
                "properties": {
                    "uuid": {
                        "description": "Address this store with PATCH /api/driver/orders/{uuid}/pickups/{pickup}/collected.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a089d1-9dc5-7207-b8ec-928fa322e999"
                    },
                    "sequence": {
                        "description": "The visiting order chosen for the stops.",
                        "type": "integer",
                        "example": 1,
                        "nullable": true
                    },
                    "store_name": {
                        "description": "What to show the captain as the name of this counter. Null when the store sent an address and no name.",
                        "type": "string",
                        "example": "Bait Al Oud",
                        "nullable": true
                    },
                    "address": {
                        "description": "Where this counter is, for the captain to navigate to.",
                        "type": "string",
                        "example": "Baghdad Street, Damascus"
                    },
                    "lat": {
                        "description": "This counter as a coordinate. Null when the address could not be placed, in which case the stop is on the route by address only.",
                        "type": "number",
                        "format": "float",
                        "example": 33.51380000000000336513039655983448028564453125,
                        "nullable": true
                    },
                    "lng": {
                        "description": "Longitude of this counter, paired with `lat`.",
                        "type": "number",
                        "format": "float",
                        "example": 36.27649999999999863575794734060764312744140625,
                        "nullable": true
                    },
                    "ready_at": {
                        "description": "When the store expects the goods to be ready.",
                        "type": "string",
                        "format": "date-time",
                        "example": null,
                        "nullable": true
                    },
                    "collected": {
                        "description": "Whether this store has been confirmed.",
                        "type": "boolean",
                        "example": false
                    },
                    "collected_at": {
                        "description": "When this counter was confirmed. Null while it is still outstanding.",
                        "type": "string",
                        "format": "date-time",
                        "example": null,
                        "nullable": true
                    },
                    "items_collected": {
                        "description": "How many pieces the captain confirmed at this counter. Null when confirmed in one tap.",
                        "type": "integer",
                        "example": 3,
                        "nullable": true
                    },
                    "items_mismatch": {
                        "description": "Set when the confirmed count differs from what this store was expected to hand over. A store owning no lines expects nothing and is never flagged.",
                        "type": "boolean",
                        "example": false
                    },
                    "amount_paid": {
                        "description": "What the captain paid at this supplier.",
                        "type": "number",
                        "format": "float",
                        "example": 120,
                        "nullable": true
                    },
                    "items": {
                        "description": "The lines collected here. Empty on an order whose items were never split by supplier, which is not the same as nothing to collect.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        }
                    },
                    "items_expected": {
                        "description": "The quantities of the lines assigned to this store.",
                        "type": "integer",
                        "example": 3
                    },
                    "expected_goods_cost": {
                        "description": "What the lines assigned to this counter come to. The number the captain checks their own against before handing cash over - asked for a figure with nothing to compare it to, people type what the till said and never notice when the two disagree. Null when this stop owns no priced lines, and null on a delivery leg, which buys nothing.",
                        "type": "number",
                        "format": "float",
                        "example": 90,
                        "nullable": true
                    },
                    "amount_variance": {
                        "description": "amount_paid minus expected_goods_cost, signed: negative means the captain paid less than the goods came to. Null when either half is unknown, because a difference from a missing number is not a difference.",
                        "type": "number",
                        "format": "float",
                        "example": -4,
                        "nullable": true
                    },
                    "order_amount": {
                        "description": "The same payment read as the order's money rather than the captain's: cash left the company here, so it is negative. amount_paid beside it stays the positive number the captain actually typed.",
                        "type": "number",
                        "format": "float",
                        "example": -90,
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "OrderItem": {
                "description": "A product line inside an order.",
                "properties": {
                    "uuid": {
                        "description": "Identifies the line. Nothing in the captain API is addressed by it — confirmation is per stop, not per line.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a089d1-9dc5-7207-b8ec-928fa322e777"
                    },
                    "name": {
                        "description": "What the store called the product. Not unique on an order: two lines can share a name and differ only by `variant`.",
                        "type": "string",
                        "example": "Cotton shirt"
                    },
                    "quantity": {
                        "description": "How many pieces of this line. `items_expected` is the sum of these.",
                        "type": "integer",
                        "example": 2
                    },
                    "unit_price": {
                        "description": "Price of one piece, in the order currency. **Null means the store never said**, not that it is free — which is why an order with unpriced lines reports a null `expected_goods_cost` rather than a zero one.",
                        "type": "number",
                        "format": "float",
                        "example": 45,
                        "nullable": true
                    },
                    "note": {
                        "description": "Anything the store added about this line.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "sku": {
                        "description": "The store product code, as they sent it.",
                        "type": "string",
                        "example": "SHIRT-RED-L",
                        "nullable": true
                    },
                    "image_url": {
                        "description": "The store own picture of this line. A link we keep, never an address we fetch - so it is loaded by the client and may 404 if the store rotates it.",
                        "type": "string",
                        "format": "uri",
                        "example": "https://cdn.example.sy/shirt-red.jpg",
                        "nullable": true
                    },
                    "variant": {
                        "description": "What distinguishes this line from another with the same name. Draw it beside the name - a captain confirming two of a shirt cannot otherwise tell the red large from the blue small, and finds out at the customer door.",
                        "type": "object",
                        "example": {
                            "color": "red",
                            "size": "L"
                        },
                        "nullable": true,
                        "additionalProperties": {
                            "type": "string"
                        }
                    }
                },
                "type": "object"
            },
            "OrderHistory": {
                "description": "One step in an order's status timeline.",
                "properties": {
                    "uuid": {
                        "description": "A status step of an order's timeline.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a08600-878b-726b-8df7-0c1bc4374db6"
                    },
                    "status": {
                        "description": "The status the order moved into at this point.",
                        "type": "string",
                        "example": "assigned",
                        "enum": [
                            "pending",
                            "assigned",
                            "accepted",
                            "picked_up",
                            "on_the_way",
                            "delivered",
                            "delivery_failed",
                            "cancelled"
                        ]
                    },
                    "status_label": {
                        "description": "That status translated for the screen.",
                        "type": "string",
                        "example": "Assigned"
                    },
                    "note": {
                        "description": "What was recorded with the move — a cancellation or failure reason, usually. Null on an ordinary step.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "actor": {
                        "description": "Name of the admin or captain who caused the change.",
                        "type": "string",
                        "example": "Monte Kilback",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the move happened. The timeline reads oldest first.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-09 14:49:36"
                    }
                },
                "type": "object"
            },
            "SuggestionList": {
                "description": "The ranked captains for an order, with how the list was found and what it cost.",
                "properties": {
                    "suggestion_uuid": {
                        "description": "The Suggestion Log entry this list was written to.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a0b389-019d-7a5c-9f7e-3d1b0c2a4e77"
                    },
                    "candidates": {
                        "description": "Best first. Empty when nobody could be offered — see no_candidates_reason.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SuggestionCandidate"
                        }
                    },
                    "radius_km": {
                        "description": "The radius the search settled on.",
                        "type": "number",
                        "format": "float",
                        "example": 5
                    },
                    "search_expanded": {
                        "description": "True when the first radius held too few captains and the search had to widen.",
                        "type": "boolean",
                        "example": false
                    },
                    "excluded_stale": {
                        "description": "Captains set aside because their GPS point was too old to trust. Reported, never hidden.",
                        "type": "array",
                        "items": {
                            "type": "string",
                            "example": "01m24x34bzfbh7resdmkm55mmq"
                        }
                    },
                    "routing_elements": {
                        "description": "How many origin-destination pairs the routing engine was asked for.",
                        "type": "integer",
                        "example": 3
                    },
                    "cache_hit": {
                        "description": "Whether the routing answer came from the suggestion cache.",
                        "type": "boolean",
                        "example": false
                    },
                    "ranking_degraded": {
                        "description": "True when the routing engine could not answer and the list is ranked on straight-line estimates.",
                        "type": "boolean",
                        "example": false
                    },
                    "degraded_reason": {
                        "description": "Why the ranking fell back to straight-line estimates. Null when the routing engine answered normally.",
                        "type": "string",
                        "example": null,
                        "nullable": true,
                        "enum": [
                            "routing_timeout",
                            "routing_error",
                            "routing_partial",
                            "routing_not_configured"
                        ]
                    },
                    "degraded_reason_label": {
                        "description": "The reason translated for the screen.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "no_candidates_reason": {
                        "description": "Why the list is empty, translated. Null whenever there are candidates.",
                        "type": "string",
                        "example": null,
                        "nullable": true
                    },
                    "timings": {
                        "$ref": "#/components/schemas/SuggestionTimings"
                    },
                    "total_ms": {
                        "description": "How long the whole pipeline took.",
                        "type": "integer",
                        "example": 96
                    }
                },
                "type": "object"
            },
            "SuggestionCandidate": {
                "description": "One captain on a suggestion list, with every number that put them in their place. Times are minutes; the Suggestion Log keeps the seconds.",
                "properties": {
                    "rank": {
                        "description": "1 is the best suggestion.",
                        "type": "integer",
                        "example": 1
                    },
                    "captain": {
                        "description": "Who is being suggested, and enough about them to decide how to hand the order over.",
                        "properties": {
                            "uuid": {
                                "description": "A ULID — what the assign call is addressed to.",
                                "type": "string",
                                "example": "01m24x34bzfbh7resdmkm55mmq"
                            },
                            "name": {
                                "description": "The captain name, for the dispatcher reading the list.",
                                "type": "string",
                                "example": "Faisal Al Harbi"
                            },
                            "employment_type": {
                                "description": "Which arrangement the captain is on. Only an employee may be directed with assign-enforced; a freelancer has to be offered the order.",
                                "type": "string",
                                "example": "employee",
                                "enum": [
                                    "employee",
                                    "freelance"
                                ]
                            },
                            "employment_type_label": {
                                "description": "The arrangement translated for the screen.",
                                "type": "string",
                                "example": "Employee captain"
                            }
                        },
                        "type": "object"
                    },
                    "state": {
                        "description": "Whether the captain is free, carrying an order but able to take another, or at their limit. The other states the enum holds (offline, on_break, unapproved) never reach a list: eligibility removes them first.",
                        "type": "string",
                        "example": "idle",
                        "enum": [
                            "idle",
                            "batchable",
                            "full"
                        ]
                    },
                    "state_label": {
                        "description": "The captain state translated for the screen.",
                        "type": "string",
                        "example": "Idle"
                    },
                    "at_store_batch": {
                        "description": "True when the captain is already at this pickup, so the order can be handed over without a trip.",
                        "type": "boolean",
                        "example": false
                    },
                    "gps_freshness": {
                        "description": "How much to trust the position this candidate was ranked from. A stale point makes every distance below an estimate; captains too stale to rank at all are reported separately in `excluded_stale`.",
                        "type": "string",
                        "example": "fresh",
                        "enum": [
                            "fresh",
                            "aging",
                            "stale",
                            "missing"
                        ]
                    },
                    "gps_freshness_label": {
                        "description": "How old the point is, translated for the screen.",
                        "type": "string",
                        "example": "Fresh"
                    },
                    "distance_km": {
                        "description": "Straight-line distance from the point the captain is judged from to the pickup.",
                        "type": "number",
                        "format": "float",
                        "example": 1.520000000000000017763568394002504646778106689453125
                    },
                    "road_eta_min": {
                        "description": "Road time to the pickup.",
                        "type": "number",
                        "format": "float",
                        "example": 4.5,
                        "nullable": true
                    },
                    "remaining_delivery_eta_min": {
                        "description": "Time left on the delivery the captain is already carrying. Zero for an idle captain.",
                        "type": "number",
                        "format": "float",
                        "example": 0,
                        "nullable": true
                    },
                    "handoff_buffer_min": {
                        "description": "Allowance for handing the current order over. Zero for an idle captain.",
                        "type": "number",
                        "format": "float",
                        "example": 0,
                        "nullable": true
                    },
                    "adjusted_eta_min": {
                        "description": "The number the list is ranked by: the three above added together.",
                        "type": "number",
                        "format": "float",
                        "example": 4.5,
                        "nullable": true
                    },
                    "detour_delta_min": {
                        "description": "How much longer the current customer waits if this order is added. Null when nothing would be batched.",
                        "type": "number",
                        "format": "float",
                        "example": null,
                        "nullable": true
                    },
                    "batch_verdict": {
                        "description": "Whether this order may ride along with the one the captain is carrying. `not_applicable` for an idle captain; the two rejections say whether the current customer would wait too long or their promised time would be missed.",
                        "type": "string",
                        "example": "not_applicable",
                        "enum": [
                            "not_applicable",
                            "accepted",
                            "rejected_detour",
                            "rejected_promise"
                        ]
                    },
                    "batch_verdict_label": {
                        "description": "The verdict translated for the screen.",
                        "type": "string",
                        "example": "Not applicable"
                    },
                    "eta_estimated": {
                        "description": "True when the time was estimated from the straight-line distance because the routing engine did not answer.",
                        "type": "boolean",
                        "example": false
                    },
                    "reasons": {
                        "description": "Why this captain is on the list and in this place, translated and ready to show.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "Idle — no orders in progress."
                        ]
                    }
                },
                "type": "object"
            },
            "SuggestionTimings": {
                "description": "What each phase cost, in milliseconds. Measured and logged, never enforced: a slow phase is recorded rather than abandoned, because half a list helps nobody.",
                "properties": {
                    "filter_ms": {
                        "description": "Narrowing every captain down to the shortlist. No routing engine is called here.",
                        "type": "integer",
                        "example": 12
                    },
                    "routing_ms": {
                        "description": "Pricing the shortlist: road times and the batch checks.",
                        "type": "integer",
                        "example": 71
                    },
                    "assembly_ms": {
                        "description": "Ranking and building the answer.",
                        "type": "integer",
                        "example": 13
                    }
                },
                "type": "object"
            },
            "PushSendOutcome": {
                "description": "What Firebase answered for a push to one recipient, read back from the delivery log.",
                "properties": {
                    "Model": {
                        "description": "What Firebase made of the send. A 200 here means we reached Firebase, not that a phone lit up - read `sent` and `failed` before telling anybody the message went out.",
                        "properties": {
                            "sent": {
                                "description": "At least one device was accepted by Firebase.",
                                "type": "boolean",
                                "example": false
                            },
                            "devices": {
                                "description": "How many registered devices the message was addressed to. Zero means the captain has no device registered, which is not an error.",
                                "type": "integer",
                                "example": 1
                            },
                            "delivered": {
                                "description": "Null when the delivery log is switched off.",
                                "type": "integer",
                                "example": 0,
                                "nullable": true
                            },
                            "failed": {
                                "description": "How many devices Firebase rejected - usually a token that belongs to an app that was uninstalled. Null when the delivery log is switched off.",
                                "type": "integer",
                                "example": 1,
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "Status": {
                        "description": "Whether the request itself succeeded. True even when every device was rejected - the rejection is in `Model`, not here.",
                        "type": "boolean",
                        "example": true
                    },
                    "Message": {
                        "description": "A sentence summarising the outcome, already translated.",
                        "type": "string",
                        "example": "Firebase rejected the notification on 1 of 1 device(s). The delivery log shows why."
                    }
                },
                "type": "object"
            },
            "PushBroadcast": {
                "description": "A broadcast, who sent it, and how far it got.",
                "properties": {
                    "uuid": {
                        "description": "Identifies the broadcast.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "title": {
                        "description": "The heading captains see on the notification.",
                        "type": "string",
                        "example": "Eid holiday"
                    },
                    "body": {
                        "description": "The message itself. Sent as written, in one language - broadcasts are not translated per captain.",
                        "type": "string"
                    },
                    "audience": {
                        "description": "Who it went to. Resolved when the broadcast was sent, so a captain who came online afterwards was not included.",
                        "type": "string",
                        "enum": [
                            "all",
                            "online",
                            "captains"
                        ]
                    },
                    "audience_label": {
                        "description": "The audience translated for the screen.",
                        "type": "string",
                        "example": "All approved captains"
                    },
                    "target_count": {
                        "description": "Captains the audience resolved to, with or without a device.",
                        "type": "integer",
                        "example": 240
                    },
                    "status": {
                        "description": "How far the send has got. A broadcast runs in the background, so `queued` right after creating one is normal.",
                        "type": "string",
                        "enum": [
                            "queued",
                            "sending",
                            "completed"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string",
                        "example": "Completed"
                    },
                    "counts": {
                        "description": "Devices, not captains - one captain with a phone and a tablet counts twice.",
                        "properties": {
                            "reached": {
                                "description": "Devices Firebase accepted.",
                                "type": "integer",
                                "example": 212
                            },
                            "failed": {
                                "description": "Devices Firebase rejected. A steady number here usually means stale tokens rather than a fault.",
                                "type": "integer",
                                "example": 4
                            }
                        },
                        "type": "object"
                    },
                    "sent_by": {
                        "description": "The administrator who sent it. A broadcast reaches the whole fleet at once, so it is worth knowing who chose to.",
                        "properties": {
                            "uuid": {
                                "description": "Identifies the administrator.",
                                "type": "string"
                            },
                            "name": {
                                "description": "Their name, for the broadcast history.",
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "started_at": {
                        "description": "When sending began. Null while still queued.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "finished_at": {
                        "description": "When the last device was attempted. Null until the run completes.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the broadcast was composed - earlier than `started_at` when the queue was busy.",
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "RoutePlan": {
                "description": "One version of a captain's route: the stops left, the line to draw and the arrival times. Render only the highest version you have seen.",
                "properties": {
                    "uuid": {
                        "description": "Identifies this plan. The push that announces a new route carries it as `route_plan_uuid`.",
                        "type": "string",
                        "format": "uuid",
                        "example": "01a0b41c-7d2e-73a1-9c44-2f8b5d6e9a10"
                    },
                    "version": {
                        "description": "Climbs by one on every recompute. Keep the highest you have seen and ignore anything lower — a frame or a push can arrive after a newer one.",
                        "type": "integer",
                        "example": 3
                    },
                    "trigger": {
                        "description": "What caused this version.",
                        "type": "string",
                        "example": "assigned",
                        "enum": [
                            "assigned",
                            "stop_completed",
                            "deviation",
                            "manual_reorder"
                        ]
                    },
                    "trigger_label": {
                        "description": "The trigger translated for the screen.",
                        "type": "string",
                        "example": "Order assigned"
                    },
                    "stops": {
                        "description": "In visiting order. Only what is left to do: a collected store and a delivered customer are gone.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/RoutePlanStop"
                        }
                    },
                    "polyline": {
                        "description": "The encoded line to draw. Null when degraded — draw the stop list instead of an invented route.",
                        "type": "string",
                        "example": "yzlkEuvdyE...",
                        "nullable": true
                    },
                    "total_seconds": {
                        "description": "The whole route end to end. An estimate rather than a measurement when `degraded` is true.",
                        "type": "integer",
                        "example": 1420
                    },
                    "total_meters": {
                        "description": "The whole route in metres, on the same terms as `total_seconds`.",
                        "type": "integer",
                        "example": 8600
                    },
                    "routing_engine": {
                        "description": "Which service drew the route. `fake` only appears in development, where the polyline is straight segments rather than roads — useful to know when a test route looks wrong.",
                        "type": "string",
                        "example": "google",
                        "enum": [
                            "fake",
                            "google",
                            "osrm"
                        ]
                    },
                    "degraded": {
                        "description": "True when the map service could not answer: the stops and their order are right, the times are estimates and there is no line.",
                        "type": "boolean",
                        "example": false
                    },
                    "computed_at": {
                        "description": "When this version was worked out. The arrival times are counted from here, so a plan left open on screen grows stale against the clock.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-19T14:05:00+03:00"
                    }
                },
                "type": "object"
            },
            "RoutePlanStop": {
                "description": "One place the captain still has to be. The leg is the hop that leads *to* this stop, so the times add up along the route.",
                "properties": {
                    "key": {
                        "description": "The stop's stable name, used when a dispatcher reorders the route. Positions are not names: the route can be recomputed between a screen being drawn and a reorder arriving.",
                        "type": "string",
                        "example": "pickup:41"
                    },
                    "type": {
                        "description": "Whether the captain is collecting here or handing over. On a collection leg the pickups are the suppliers and the drop-off is the wrapping shop.",
                        "type": "string",
                        "example": "pickup",
                        "enum": [
                            "pickup",
                            "dropoff"
                        ]
                    },
                    "order_id": {
                        "description": "Internal numeric id of the order this stop belongs to. **Not the uuid the captain API uses elsewhere**, so it cannot be matched against an order read from `GET /orders`.",
                        "type": "integer",
                        "example": 812
                    },
                    "pickup_id": {
                        "description": "Internal numeric id of the stop, on the same terms as `order_id`. Null on a drop-off.",
                        "type": "integer",
                        "example": 41,
                        "nullable": true
                    },
                    "lat": {
                        "description": "Where to drive. This and `lng` are what the app pins on the map.",
                        "type": "number",
                        "format": "float",
                        "example": 24.7135999999999995679900166578590869903564453125
                    },
                    "lng": {
                        "description": "Longitude of the stop, paired with `lat`.",
                        "type": "number",
                        "format": "float",
                        "example": 46.67530000000000001136868377216160297393798828125
                    },
                    "leg_seconds": {
                        "description": "Time from the previous stop — from the captain's position for the first one.",
                        "type": "integer",
                        "example": 420
                    },
                    "leg_meters": {
                        "description": "Distance of that same hop, in metres.",
                        "type": "integer",
                        "example": 2300
                    },
                    "eta_at": {
                        "description": "When the captain should arrive here.",
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-09-19T14:12:00+03:00"
                    }
                },
                "type": "object"
            },
            "Settlement": {
                "properties": {
                    "uuid": {
                        "description": "One payment between us and a store.\n\nThe amounts are a snapshot of what both sides agreed on the day, not a live view. They do not\nmove if an order is corrected afterwards — a payment already made must not change underneath\nthe people holding it.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "reference": {
                        "description": "The bank or transfer reference.",
                        "type": "string",
                        "nullable": true
                    },
                    "period": {
                        "description": "The window of delivered orders this settlement covers. Both ends are inclusive.",
                        "properties": {
                            "from": {
                                "description": "First day covered.",
                                "type": "string",
                                "format": "date"
                            },
                            "to": {
                                "description": "Last day covered.",
                                "type": "string",
                                "format": "date"
                            }
                        },
                        "type": "object"
                    },
                    "cash_collected": {
                        "description": "What our captains took from the store customers over the period - the store money that we are holding.",
                        "type": "number"
                    },
                    "fees_charged": {
                        "description": "What we charged for those deliveries. Kept apart from the cash rather than netted, so each side is auditable on its own.",
                        "type": "number"
                    },
                    "net_amount": {
                        "description": "What is actually paid. May be negative when fees exceeded the cash collected.",
                        "type": "number"
                    },
                    "currency": {
                        "description": "Always `SYP`. A settlement covers one currency.",
                        "type": "string"
                    },
                    "orders_count": {
                        "description": "How many delivered orders the figures are built from.",
                        "type": "integer"
                    },
                    "status": {
                        "description": "A draft is ours; the store never sees one.",
                        "type": "string",
                        "enum": [
                            "draft",
                            "settled",
                            "cancelled"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string"
                    },
                    "settled_at": {
                        "description": "When the money actually moved. Null on a draft or a cancelled settlement.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "note": {
                        "description": "Whatever finance recorded alongside the payment.",
                        "type": "string",
                        "nullable": true
                    },
                    "created_by": {
                        "description": "Who drew it up.",
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the settlement was drawn up, which is earlier than `settled_at`.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreClient": {
                "properties": {
                    "uuid": {
                        "description": "A store that feeds us orders, as the back office reads it.\n\nNo secret appears here. Support can read a store's whole configuration without being able to\nread its signing key — those come only from the store's own portal, behind its own password.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "name": {
                        "description": "The shop trading name, as we hold it.",
                        "type": "string",
                        "example": "Fresh Market"
                    },
                    "slug": {
                        "description": "Our handle. Appears in rate-limit keys and logs, so it is never editable.",
                        "type": "string",
                        "example": "fresh-market"
                    },
                    "status": {
                        "description": "Where the integration stands. Only an approved store may send orders, and `is_live` is the flag to act on because it accounts for the pause switch too.",
                        "type": "string",
                        "enum": [
                            "pending",
                            "approved",
                            "rejected",
                            "suspended"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string"
                    },
                    "is_active": {
                        "description": "The operational pause switch, separate from the review status.",
                        "type": "boolean"
                    },
                    "is_live": {
                        "description": "Approved **and** not paused. Only then do orders flow.",
                        "type": "boolean"
                    },
                    "review_note": {
                        "description": "Why a decision went the way it did. The store reads this, so it is written for them rather than as an internal note.",
                        "type": "string",
                        "nullable": true
                    },
                    "reviewed_at": {
                        "description": "When the application was last decided on. Null while it has never been reviewed.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "webhook_url": {
                        "description": "Where we POST the store events. Null means none is set and nothing is being delivered - the events are still recorded, so setting a URL later does not replay them.",
                        "type": "string",
                        "nullable": true
                    },
                    "allowed_ips": {
                        "description": "Empty means the check is off.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "default_currency": {
                        "description": "The currency this store orders are priced in. Always `SYP`.",
                        "type": "string",
                        "example": "SYP"
                    },
                    "timezone": {
                        "description": "The timezone the store statement periods and daily figures are grouped by.",
                        "type": "string",
                        "example": "Asia/Riyadh"
                    },
                    "wrapping": {
                        "description": "Where this store\\x27s parcels are wrapped, when it uses wrapping. Configured once here rather than sent on each order.",
                        "properties": {
                            "configured": {
                                "description": "All of address, lat and lng are set. An order may only ask to be wrapped when this is true.",
                                "type": "boolean",
                                "example": false
                            },
                            "name": {
                                "description": "What the wrapping shop is called. This is the name a collection leg carries as its customer_name.",
                                "type": "string",
                                "example": "Al Nour Wrapping",
                                "nullable": true
                            },
                            "address": {
                                "description": "Where the wrapping shop is. Null until one is configured.",
                                "type": "string",
                                "example": "Baghdad Street, Damascus",
                                "nullable": true
                            },
                            "lat": {
                                "description": "The wrapping shop as a coordinate - what a captain is routed to. Set together with the address and longitude or not at all.",
                                "type": "number",
                                "format": "float",
                                "example": 33.51919540000000097279553301632404327392578125,
                                "nullable": true
                            },
                            "lng": {
                                "description": "Longitude of the wrapping shop, paired with `lat`.",
                                "type": "number",
                                "format": "float",
                                "example": 36.2877103000000005295078153721988201141357421875,
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "secrets": {
                        "description": "Metadata only — never the values.",
                        "properties": {
                            "has_secrets": {
                                "description": "Whether a signing pair has been issued. Without one the store cannot sign a request and the API refuses everything they send.",
                                "type": "boolean"
                            },
                            "rotated_at": {
                                "description": "When the pair was last replaced. Null if it never has been.",
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                            },
                            "previous_valid_until": {
                                "description": "While this is set the previous pair is still accepted, which is what lets a store roll a new secret out without downtime. Null once the old pair has lapsed.",
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "created_at": {
                        "description": "When the store record was created.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreUser": {
                "properties": {
                    "uuid": {
                        "description": "A person at a store who can sign in to the store portal.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "name": {
                        "description": "The person full name, as entered when they were invited.",
                        "type": "string"
                    },
                    "email": {
                        "description": "Their sign-in identifier, unique across every store.",
                        "type": "string",
                        "format": "email"
                    },
                    "phone": {
                        "description": "Where their recovery codes go.",
                        "type": "string"
                    },
                    "role": {
                        "description": "What they may do in the portal. Only an owner can manage the integration, the users and the settlements.",
                        "type": "string",
                        "enum": [
                            "owner",
                            "staff"
                        ]
                    },
                    "role_label": {
                        "description": "The role translated for the screen.",
                        "type": "string"
                    },
                    "status": {
                        "description": "Where the account stands. `pending` means invited but never signed in; a suspended account keeps its history and cannot sign in.",
                        "type": "string",
                        "enum": [
                            "pending",
                            "active",
                            "suspended"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string"
                    },
                    "is_active": {
                        "description": "Whether they may sign in - the switch behind `status`.",
                        "type": "boolean"
                    },
                    "can_manage_integration": {
                        "description": "True for an owner.",
                        "type": "boolean"
                    },
                    "last_login_at": {
                        "description": "When they last signed in. Null while the invitation has never been used.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When they were invited.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "WebhookDelivery": {
                "properties": {
                    "uuid": {
                        "description": "Identifies this delivery record, and what a manual retry is addressed to.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "event": {
                        "description": "Which event was being delivered. Retries of the same event share an `event_id`, so this alone does not identify an attempt.",
                        "type": "string",
                        "example": "order.delivered"
                    },
                    "event_label": {
                        "description": "The event translated for the screen.",
                        "type": "string"
                    },
                    "event_id": {
                        "description": "The store's deduplication key. A retry carries the same one.",
                        "type": "string",
                        "format": "uuid"
                    },
                    "sequence": {
                        "description": "Increases per order. Null on a connection test.",
                        "type": "integer",
                        "nullable": true
                    },
                    "status": {
                        "description": "`dropped` means six attempts were exhausted and a human has to look.",
                        "type": "string",
                        "enum": [
                            "pending",
                            "sent",
                            "failed",
                            "dropped"
                        ]
                    },
                    "status_label": {
                        "description": "The status translated for the screen.",
                        "type": "string"
                    },
                    "attempts": {
                        "description": "How many times we have tried. Six exhausts the schedule and the delivery is dropped.",
                        "type": "integer"
                    },
                    "url": {
                        "description": "Where it was sent - recorded per attempt, so a delivery that failed against an old URL still shows the one it actually used.",
                        "type": "string"
                    },
                    "response_status": {
                        "description": "The HTTP status the store endpoint answered. Null when nothing answered at all, in which case `error` says why.",
                        "type": "integer",
                        "nullable": true
                    },
                    "response_body": {
                        "description": "What the store sent back, truncated. The first place to look when a store insists they never received an event.",
                        "type": "string",
                        "nullable": true
                    },
                    "error": {
                        "description": "Why the attempt never reached an HTTP answer - a timeout, a refused connection, a certificate that did not verify.",
                        "type": "string",
                        "nullable": true
                    },
                    "next_attempt_at": {
                        "description": "When the next retry is due. Null once the delivery succeeded or was dropped.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "delivered_at": {
                        "description": "When the store accepted it. Null until they do.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "created_at": {
                        "description": "When the event was queued - when it happened, not when it was delivered.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "payload": {
                        "description": "The exact body that was POSTed to the store, kept verbatim so a dispute is settled by\nreading it rather than by reconstructing what we think we sent.\n\n`order` is the full order body, identical to what `GET /api/v1/orders/{uuid}` answers\non the store API and documented there.",
                        "properties": {
                            "event": {
                                "description": "The event name as the store received it.",
                                "type": "string",
                                "example": "order.delivered"
                            },
                            "event_id": {
                                "description": "The store's deduplication key.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "occurred_at": {
                                "description": "Advisory. The store orders by `sequence`, not by this.",
                                "type": "string",
                                "format": "date-time"
                            },
                            "sequence": {
                                "description": "Monotonic per order. Null on a connection test.",
                                "type": "integer",
                                "nullable": true
                            },
                            "order": {
                                "description": "The full order body, field for field what `GET /api/v1/orders/{uuid}` answers on the store API — see the **integration** document, which is where the store reads it and where it is kept. It is referenced rather than restated because this specification cannot see that one, and a second copy becomes a second shape the first time either is edited.",
                                "type": "object",
                                "additionalProperties": true
                            }
                        },
                        "type": "object"
                    },
                    "order": {
                        "description": "The order the event was about. Null on a connection test, which belongs to no order.",
                        "properties": {
                            "uuid": {
                                "description": "Opens the order.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "order_number": {
                                "description": "Our reference, for the delivery log listing.",
                                "type": "string"
                            },
                            "external_order_id": {
                                "description": "The store own reference - what they will quote when they ring about a missing event.",
                                "type": "string",
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "store": {
                        "description": "Who the event was being sent to.",
                        "properties": {
                            "uuid": {
                                "description": "Opens the store record.",
                                "type": "string",
                                "format": "uuid"
                            },
                            "name": {
                                "description": "The shop trading name, for the log listing.",
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    }
                },
                "type": "object"
            }
        },
        "securitySchemes": {
            "adminAuth": {
                "type": "http",
                "description": "Bearer token issued by POST /api/dashboard/auth/login. Enter in format (Bearer <token>).",
                "bearerFormat": "Sanctum",
                "scheme": "bearer"
            }
        }
    },
    "tags": [
        {
            "name": "Dashboard — Cash Desk",
            "description": "What captains paid out of their own pockets at suppliers, what they took from customers, and\nthe cash that clears the difference. The company sits in the middle: captains never owe each\nother.\n\n**Positive means the company owes the captain**; negative means the captain owes the company.\nEvery figure is per currency and never summed across them.\n\n**Cash only ever moves towards zero.** Pay out to a captain who is owed, take cash from one\nwho owes, never past their balance. Anything else is a correction and goes through `adjust`,\nwhich requires a reason."
        },
        {
            "name": "Dashboard — Cities and earnings",
            "description": "The delivery areas, the flat amount a captain earns for delivering into each, and what that has\ncost.\n\n**Two levels.** A city holds districts; a district holds nothing. Editing a city's rate carries\nthe districts that follow it; a district given a rate of its own keeps it unless the editor asks\nfor it to be overwritten — and editing a district never touches its city.\n\n**The earning is credited at delivery**, from the area the drop-off point falls in, and only for\norders delivered to a customer: the collection leg of a wrapped order carries goods to a shop and\nearns nothing. The figure is copied onto the earning row, so changing a rate never restates what\nhas already been paid.\n\n`cities.view` reads the areas and the report; `cities.manage` changes a rate. They are separate\nbecause a rate is payroll, and the people who need to see which districts are served are not the\npeople who decide what a trip is worth."
        },
        {
            "name": "Dashboard — Delivery pricing",
            "description": "Value ladders: ranges of merchandise value, each with what the delivery costs **the store** inside\nit. A band priced at zero is free delivery.\n\n**This prices our invoice, not the customer's receipt.** `orders.fee` is the company's revenue —\n`SUM(fee)` in the stats and `fees_charged` on a store statement — while `orders.amount_to_collect`\nis what the shop told its customer to pay. A ladder never touches the second: lowering it would\nrewrite a figure a customer has already been given, and leave the shop short with no record of why.\nA shop passing free delivery on lowers the amount to collect itself, when it sends the order.\n\n**The ladder overrules a fee the caller stated.** A store integration that always sends 18,000\nwould otherwise never give anybody free delivery. What was asked for survives as `quoted_fee` on\nthe order, so the override is a record rather than a silent edit.\n\n**An order is priced when it is opened and again when a store edits its basket** — an order\ncorrected from 320,000 down to 50,000 must not keep the free delivery it no longer qualifies for.\nAn edit that touches neither the lines nor the fee leaves the price alone.\n\nTwo cases where the ladder stays silent and a stated fee stands: an order whose lines carry no\nprices, and a basket that falls outside every band. Neither is an error — the first means the store\nnever said what the goods are worth, the second that the ladder has a hole in it.\n\n`delivery_fees.view` reads; `delivery_fees.manage` changes what the company charges."
        },
        {
            "name": "Dashboard — Authentication",
            "description": "Back office sign in and password recovery."
        },
        {
            "name": "Dashboard — Profile",
            "description": "The signed in admin's own account."
        },
        {
            "name": "Dashboard — Admins",
            "description": "Management of the other back office accounts."
        },
        {
            "name": "Dashboard — Roles & Permissions",
            "description": "The role catalogue and the permissions behind it."
        },
        {
            "name": "Dashboard — Captains",
            "description": "The review queue, decisions and corrections."
        },
        {
            "name": "Dashboard — Vehicles",
            "description": "The vehicles captains drive: list, detail, records, photos, documents and activation."
        },
        {
            "name": "Dashboard — Orders",
            "description": "Order list, detail, creation and manual assignment."
        },
        {
            "name": "Dashboard — Dispatch",
            "description": "Captain dispatch: the business values the algorithm runs on."
        },
        {
            "name": "Dashboard — Push Notifications",
            "description": "The push delivery log, its health, registered devices and a test push."
        },
        {
            "name": "Dashboard — Store integration",
            "description": "Dashboard — Store integration"
        },
        {
            "name": "Dashboard — Notifications",
            "description": "Dashboard — Notifications"
        },
        {
            "name": "Dashboard — Settlements",
            "description": "Dashboard — Settlements"
        },
        {
            "name": "Dashboard — Stats",
            "description": "Dashboard — Stats"
        },
        {
            "name": "Dashboard — Stores",
            "description": "Dashboard — Stores"
        }
    ]
}