{
  "openapi": "3.0.3",
  "info": {
    "title": "Labada Laundry Mobile & Web API",
    "description": "Comprehensive RESTful API documentation for the Labada Laundry System in Bulan, Sorsogon. Features role-based access (Customer, Shop Owner, Rider, Admin), Sanctum authentication, Dijkstra shortest-path route optimization, real-time Reverb websockets, order timeline tracking, transparent billing, and ISO/IEC 25010 System Quality evaluation.",
    "version": "1.0.0",
    "contact": {
      "name": "Labada Support Team",
      "email": "support@labada.app"
    }
  },
  "servers": [
    {
      "url": "http://127.0.0.1:8000/api",
      "description": "Local Development Server"
    },
    {
      "url": "http://localhost:8000/api",
      "description": "Localhost Alternative"
    }
  ],
  "tags": [
    {
      "name": "01. Auth & Profile",
      "description": "Registration, Login, Google OAuth, Profile management, and Expo push tokens."
    },
    {
      "name": "02. Shops & Catalog",
      "description": "Public and customer catalog for laundry shops, service offerings, detergents, and softeners."
    },
    {
      "name": "03. Customer - Addresses",
      "description": "Manage customer pickup & delivery addresses in Bulan."
    },
    {
      "name": "04. Customer - Orders & Payments",
      "description": "Schedule pickups, cancel orders, get itemized receipts, submit GCash/Maya payments, and live GPS rider tracking."
    },
    {
      "name": "05. Shop Owner - Dashboard & Management",
      "description": "Owner analytics, dispatching riders, 1-tap payment verification, and CRUD for services and supplies."
    },
    {
      "name": "06. Rider - Deliveries & Navigation",
      "description": "Rider queue, status updates, live GPS streaming, Dijkstra shortest path route optimization, and earnings."
    },
    {
      "name": "07. Shared - Status & Chat",
      "description": "Order progression timeline and live 3-way in-order chat."
    },
    {
      "name": "08. Notifications",
      "description": "In-app notification history, unread counters, and mark-as-read."
    },
    {
      "name": "09. Feedback & ISO/IEC 25010 Quality",
      "description": "Customer feedback and ISO/IEC 25010 multi-stakeholder system quality evaluation."
    },
    {
      "name": "10. Admin - Landmarks & Dijkstra Graph",
      "description": "Manage Bulan road network landmarks, geographic vertices, and route distances."
    }
  ],
  "paths": {
    "/register": {
      "post": {
        "tags": ["01. Auth & Profile"],
        "summary": "Register a new user",
        "description": "Create an account for customer, rider, owner, or admin. (Owner/Admin require registration_key).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "email", "password", "role"],
                "properties": {
                  "name": { "type": "string", "example": "Juan Dela Cruz" },
                  "email": { "type": "string", "format": "email", "example": "juan@example.com" },
                  "password": { "type": "string", "format": "password", "example": "password123" },
                  "role": { "type": "string", "enum": ["customer", "rider", "owner", "admin"], "example": "customer" },
                  "phone": { "type": "string", "example": "09123456789" },
                  "registration_key": { "type": "string", "description": "Required when registering as owner or admin", "example": "labada-owner-secret-key" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User registered successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": { "type": "string", "example": "User registered successfully." },
                    "access_token": { "type": "string", "example": "1|qWerTyUiOp123456..." },
                    "token_type": { "type": "string", "example": "Bearer" },
                    "user": { "$ref": "#/components/schemas/User" }
                  }
                }
              }
            }
          },
          "422": { "description": "Validation Error" },
          "403": { "description": "Unauthorized registration key" }
        }
      }
    },
    "/login": {
      "post": {
        "tags": ["01. Auth & Profile"],
        "summary": "Login user",
        "description": "Authenticate user with email and password to receive a Sanctum Bearer token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email", "example": "juan@example.com" },
                  "password": { "type": "string", "format": "password", "example": "password123" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logged in successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": { "type": "string", "example": "1|qWerTyUiOp123456..." },
                    "token_type": { "type": "string", "example": "Bearer" },
                    "user": { "$ref": "#/components/schemas/User" }
                  }
                }
              }
            }
          },
          "422": { "description": "Invalid credentials" }
        }
      }
    },
    "/auth/google": {
      "post": {
        "tags": ["01. Auth & Profile"],
        "summary": "Google OAuth Sign-In",
        "description": "Exchange a Google ID Token for an authenticated Sanctum session token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id_token"],
                "properties": {
                  "id_token": { "type": "string", "example": "eyJhbGciOiJSUzI1NiIsImtpZCI6..." },
                  "role": { "type": "string", "enum": ["customer", "rider", "owner", "admin"], "default": "customer" },
                  "phone": { "type": "string", "example": "09123456789" },
                  "registration_key": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Authenticated successfully via Google" },
          "422": { "description": "Invalid Google token" }
        }
      }
    },
    "/profile": {
      "get": {
        "tags": ["01. Auth & Profile"],
        "summary": "Get authenticated user profile",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "User profile retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": { "$ref": "#/components/schemas/User" }
                  }
                }
              }
            }
          },
          "401": { "description": "Unauthenticated" }
        }
      }
    },
    "/profile/push-token": {
      "post": {
        "tags": ["01. Auth & Profile"],
        "summary": "Register Expo Push Token",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expo_push_token": { "type": "string", "example": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Push token updated successfully" }
        }
      }
    },
    "/logout": {
      "post": {
        "tags": ["01. Auth & Profile"],
        "summary": "Logout user",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "description": "Logged out successfully" }
        }
      }
    },
    "/shops": {
      "get": {
        "tags": ["02. Shops & Catalog"],
        "summary": "List all laundry shops",
        "description": "Get all shops with operating hours, status (Open/Closed), ratings, and Bulan coordinates.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "List of shops",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Shop" }
                }
              }
            }
          }
        }
      }
    },
    "/shops/{shop}/services": {
      "get": {
        "tags": ["02. Shops & Catalog"],
        "summary": "Get shop services",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "shop", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 1 }
        ],
        "responses": {
          "200": {
            "description": "List of active services for the shop",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/ShopService" }
                }
              }
            }
          }
        }
      }
    },
    "/shops/{shop}/supplies": {
      "get": {
        "tags": ["02. Shops & Catalog"],
        "summary": "Get shop detergents & conditioners",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "shop", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 1 }
        ],
        "responses": {
          "200": {
            "description": "Categorized available detergent and fabric softener items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detergents": { "type": "array", "items": { "$ref": "#/components/schemas/ShopSupply" } },
                    "conditioners": { "type": "array", "items": { "$ref": "#/components/schemas/ShopSupply" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/addresses": {
      "get": {
        "tags": ["03. Customer - Addresses"],
        "summary": "List user addresses",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "List of saved addresses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Address" }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["03. Customer - Addresses"],
        "summary": "Create address",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["label", "address_line", "city"],
                "properties": {
                  "label": { "type": "string", "example": "Home" },
                  "address_line": { "type": "string", "example": "Zone 4, Pier Site" },
                  "city": { "type": "string", "example": "Bulan" },
                  "landmark": { "type": "string", "example": "Bulan Port (Pier Site)" },
                  "latitude": { "type": "number", "example": 12.6681 },
                  "longitude": { "type": "number", "example": 123.8685 },
                  "is_default": { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Address created successfully" }
        }
      }
    },
    "/addresses/{address}": {
      "get": {
        "tags": ["03. Customer - Addresses"],
        "summary": "Get address details",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "address", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Address details retrieved" }
        }
      },
      "put": {
        "tags": ["03. Customer - Addresses"],
        "summary": "Update address",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "address", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": { "type": "string" },
                  "address_line": { "type": "string" },
                  "city": { "type": "string" },
                  "landmark": { "type": "string" },
                  "latitude": { "type": "number" },
                  "longitude": { "type": "number" },
                  "is_default": { "type": "boolean" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Address updated successfully" },
          "422": { "description": "Cannot edit location while an active order is linked" }
        }
      },
      "delete": {
        "tags": ["03. Customer - Addresses"],
        "summary": "Delete address",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "address", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Address deleted successfully" },
          "422": { "description": "Cannot delete address linked to active orders" }
        }
      }
    },
    "/addresses/{address}/default": {
      "post": {
        "tags": ["03. Customer - Addresses"],
        "summary": "Set address as default",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "address", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Address set as default successfully" }
        }
      }
    },
    "/orders": {
      "get": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "List customer orders",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "List of user orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Order" }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "Schedule a new laundry pickup",
        "description": "Customer schedules a laundry booking with pickup address, service type, and optional detergent add-ons.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["shop_id", "pickup_address_id", "service_type", "pickup_date", "estimated_amount"],
                "properties": {
                  "shop_id": { "type": "integer", "example": 1 },
                  "pickup_address_id": { "type": "integer", "example": 1 },
                  "service_type": { "type": "string", "example": "wash_dry_fold" },
                  "pickup_date": { "type": "string", "format": "date-time", "example": "2026-08-20 14:00:00" },
                  "estimated_amount": { "type": "number", "example": 215.00 },
                  "weight": { "type": "number", "example": 5.0 },
                  "detergent_id": { "type": "integer", "nullable": true, "example": 1 },
                  "conditioner_id": { "type": "integer", "nullable": true, "example": 1 }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Order scheduled successfully" }
        }
      }
    },
    "/orders/{order}/cancel": {
      "post": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "Cancel order",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["reason"],
                "properties": {
                  "reason": { "type": "string", "example": "Customer requested cancellation." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Order cancelled successfully" },
          "422": { "description": "Cannot cancel orders already in progress" }
        }
      }
    },
    "/orders/{order}/receipt": {
      "get": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "Get itemized transparent receipt",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Itemized bill breakdown (Weight x Rate + Supplies + Delivery Fee)" }
        }
      }
    },
    "/orders/{order}/pay": {
      "post": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "Submit payment details or e-Wallet reference",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["method"],
                "properties": {
                  "method": { "type": "string", "enum": ["COD", "GCASH", "MAYA"], "example": "GCASH" },
                  "reference_number": { "type": "string", "example": "GCASH-98234710293" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Payment details submitted" }
        }
      }
    },
    "/orders/{order}/rider-location": {
      "get": {
        "tags": ["04. Customer - Orders & Payments"],
        "summary": "Get live assigned rider GPS location",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Rider coordinates and live status" }
        }
      }
    },
    "/owner/analytics": {
      "get": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Shop analytics summary",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "period", "in": "query", "schema": { "type": "string", "enum": ["all", "today", "week", "month"] }, "example": "all" }
        ],
        "responses": {
          "200": { "description": "Glanceable metrics (revenue, active loads, completed, weights)" }
        }
      }
    },
    "/owner/orders": {
      "get": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "List all shop orders",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "description": "List of orders with customer history metrics" }
        }
      }
    },
    "/owner/riders": {
      "get": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "List riders for assignment",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "description": "List of riders with status and user info" }
        }
      }
    },
    "/owner/orders/{order}/assign": {
      "post": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Assign rider to order",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["rider_id"],
                "properties": {
                  "rider_id": { "type": "integer", "example": 1 }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Rider assigned and notifications sent" }
        }
      }
    },
    "/owner/orders/{order}/verify-payment": {
      "post": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "1-Tap verify e-Wallet reference",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Payment marked completed" }
        }
      }
    },
    "/owner/services": {
      "get": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "List owner services",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "List of shop services" } }
      },
      "post": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Create service offer",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "price"],
                "properties": {
                  "name": { "type": "string", "example": "Wash & Dry Standard" },
                  "description": { "type": "string", "example": "Standard laundry load" },
                  "price": { "type": "number", "example": 160.00 },
                  "price_unit": { "type": "string", "example": "flat_rate" },
                  "min_kg": { "type": "number", "example": 1.0 },
                  "max_kg": { "type": "number", "example": 8.0 },
                  "extra_price_per_kg": { "type": "number", "example": 20.00 },
                  "is_available": { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Service created" } }
      }
    },
    "/owner/services/{service}": {
      "put": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Update service offer",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "service", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Service updated" } }
      },
      "delete": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Delete service offer",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "service", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Service deleted" } }
      }
    },
    "/owner/supplies": {
      "get": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "List owner supplies",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "List of supplies" } }
      },
      "post": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Create supply item",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type", "name"],
                "properties": {
                  "type": { "type": "string", "enum": ["detergent", "conditioner"], "example": "detergent" },
                  "name": { "type": "string", "example": "Ariel Sunrise Fresh" },
                  "brand": { "type": "string", "example": "Ariel" },
                  "price": { "type": "number", "example": 15.00 },
                  "is_available": { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Supply created" } }
      }
    },
    "/owner/supplies/{supply}": {
      "put": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Update supply item",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "supply", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Supply updated" } }
      },
      "delete": {
        "tags": ["05. Shop Owner - Dashboard & Management"],
        "summary": "Delete supply item",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "supply", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Supply deleted" } }
      }
    },
    "/rider/orders": {
      "get": {
        "tags": ["06. Rider - Deliveries & Navigation"],
        "summary": "Get rider assigned orders",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Active delivery assignments" } }
      }
    },
    "/rider/status": {
      "put": {
        "tags": ["06. Rider - Deliveries & Navigation"],
        "summary": "Update rider availability status",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["status"],
                "properties": {
                  "status": { "type": "string", "enum": ["offline", "idle", "delivering"], "example": "idle" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Rider status updated" } }
      }
    },
    "/rider/location": {
      "post": {
        "tags": ["06. Rider - Deliveries & Navigation"],
        "summary": "Update rider GPS location",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["latitude", "longitude"],
                "properties": {
                  "latitude": { "type": "number", "example": 12.6675 },
                  "longitude": { "type": "number", "example": 123.8742 }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Location updated" } }
      }
    },
    "/rider/route-optimization": {
      "get": {
        "tags": ["06. Rider - Deliveries & Navigation"],
        "summary": "Dijkstra Route Optimization",
        "description": "Calculates shortest multi-stop path across Bulan road network for all active pickups/deliveries.",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "start", "in": "query", "schema": { "type": "string" }, "example": "SSU Bulan Campus" }
        ],
        "responses": { "200": { "description": "Optimized route stops and Dijkstra trajectory" } }
      }
    },
    "/rider/earnings": {
      "get": {
        "tags": ["06. Rider - Deliveries & Navigation"],
        "summary": "Get rider delivery earnings & feedback",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Summary of total earnings, completed trips, and customer ratings" } }
      }
    },
    "/orders/{order}/status": {
      "put": {
        "tags": ["07. Shared - Status & Chat"],
        "summary": "Update order status",
        "description": "Transitions: pending -> pickup_assigned -> picking_up -> picked_up -> in_laundry -> processing -> ready_for_delivery -> delivering -> completed.",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["status"],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": ["pending", "pickup_assigned", "picking_up", "picked_up", "in_laundry", "processing", "ready_for_delivery", "delivering", "completed", "cancelled"],
                    "example": "picking_up"
                  },
                  "weight": { "type": "number", "example": 6.2 },
                  "amount": { "type": "number", "example": 246.00 }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Status updated and broadcasted via Reverb" } }
      }
    },
    "/orders/{order}/messages": {
      "get": {
        "tags": ["07. Shared - Status & Chat"],
        "summary": "Get order chat messages",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Chronological chat history" } }
      },
      "post": {
        "tags": ["07. Shared - Status & Chat"],
        "summary": "Send in-order chat message",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "order", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["message"],
                "properties": {
                  "message": { "type": "string", "example": "Hi! I am heading over to pick up the clothes." }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Message sent and broadcasted" } }
      }
    },
    "/notifications": {
      "get": {
        "tags": ["08. Notifications"],
        "summary": "List in-app notifications",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "List of user notifications" } }
      }
    },
    "/notifications/unread-count": {
      "get": {
        "tags": ["08. Notifications"],
        "summary": "Get unread notification count",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Unread count" } }
      }
    },
    "/notifications/{notification}/read": {
      "put": {
        "tags": ["08. Notifications"],
        "summary": "Mark notification as read",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "notification", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Marked as read" } }
      }
    },
    "/notifications/mark-read": {
      "post": {
        "tags": ["08. Notifications"],
        "summary": "Mark all notifications as read",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "All notifications marked read" } }
      }
    },
    "/notifications/{notification}": {
      "delete": {
        "tags": ["08. Notifications"],
        "summary": "Delete a notification",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "notification", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Notification deleted" } }
      }
    },
    "/feedback": {
      "post": {
        "tags": ["09. Feedback & ISO/IEC 25010 Quality"],
        "summary": "Submit order review",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["order_id", "shop_rating", "rider_rating"],
                "properties": {
                  "order_id": { "type": "integer", "example": 1 },
                  "shop_rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "rider_rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "comment": { "type": "string", "example": "Excellent service and prompt delivery!" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Feedback submitted" } }
      }
    },
    "/evaluations/my": {
      "get": {
        "tags": ["09. Feedback & ISO/IEC 25010 Quality"],
        "summary": "Check my system evaluation status",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "User evaluation status and score" } }
      }
    },
    "/evaluations": {
      "post": {
        "tags": ["09. Feedback & ISO/IEC 25010 Quality"],
        "summary": "Submit ISO/IEC 25010 System Quality questionnaire",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "fs_completeness", "fs_correctness", "fs_appropriateness", "fs_accessibility", "fs_integration",
                  "pe_time_behavior", "pe_resource_utilization", "pe_capacity", "pe_scalability", "pe_responsiveness",
                  "ic_usability", "ic_ease_of_navigation", "ic_user_feedback", "ic_compatibility", "ic_communication_support"
                ],
                "properties": {
                  "fs_completeness": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "fs_correctness": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "fs_appropriateness": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "fs_accessibility": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "fs_integration": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "pe_time_behavior": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "pe_resource_utilization": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "pe_capacity": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "pe_scalability": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "pe_responsiveness": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "ic_usability": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "ic_ease_of_navigation": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "ic_user_feedback": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "ic_compatibility": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 },
                  "ic_communication_support": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5 }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Evaluation saved" } }
      }
    },
    "/admin/landmarks": {
      "get": {
        "tags": ["10. Admin - Landmarks & Dijkstra Graph"],
        "summary": "List all landmarks and road connections",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Landmarks graph" } }
      },
      "post": {
        "tags": ["10. Admin - Landmarks & Dijkstra Graph"],
        "summary": "Create landmark vertex",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "latitude", "longitude"],
                "properties": {
                  "name": { "type": "string", "example": "Bulan Freedom Park" },
                  "latitude": { "type": "number", "example": 12.6710 },
                  "longitude": { "type": "number", "example": 123.8780 }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Landmark created" } }
      }
    },
    "/admin/landmarks/{landmark}": {
      "delete": {
        "tags": ["10. Admin - Landmarks & Dijkstra Graph"],
        "summary": "Delete landmark",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "name": "landmark", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "Landmark deleted" } }
      }
    },
    "/admin/landmarks/connections": {
      "post": {
        "tags": ["10. Admin - Landmarks & Dijkstra Graph"],
        "summary": "Create or update bidirectional road connection (Edge)",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["from_landmark_id", "to_landmark_id", "distance"],
                "properties": {
                  "from_landmark_id": { "type": "integer", "example": 1 },
                  "to_landmark_id": { "type": "integer", "example": 2 },
                  "distance": { "type": "number", "example": 0.85 }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Connection updated" } }
      }
    },
    "/admin/landmarks/connections/delete": {
      "post": {
        "tags": ["10. Admin - Landmarks & Dijkstra Graph"],
        "summary": "Delete landmark connection",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["from_landmark_id", "to_landmark_id"],
                "properties": {
                  "from_landmark_id": { "type": "integer", "example": 1 },
                  "to_landmark_id": { "type": "integer", "example": 2 }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Connection deleted" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Sanctum Token",
        "description": "Enter your Laravel Sanctum token generated from /login or /register (e.g. '1|xyz123abc...')"
      }
    },
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Juan Dela Cruz" },
          "email": { "type": "string", "example": "juan@example.com" },
          "role": { "type": "string", "enum": ["customer", "rider", "owner", "admin"], "example": "customer" },
          "phone": { "type": "string", "example": "09123456789" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Shop": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Labada Express Central" },
          "address": { "type": "string", "example": "Zone 4, Pier Site, Bulan" },
          "city": { "type": "string", "example": "Bulan" },
          "landmark": { "type": "string", "example": "Bulan Port (Pier Site)" },
          "latitude": { "type": "number", "example": 12.6681 },
          "longitude": { "type": "number", "example": 123.8685 },
          "rating": { "type": "number", "example": 4.8 },
          "is_open": { "type": "boolean", "example": true },
          "hours_display": { "type": "string", "example": "07:00 AM - 08:00 PM" },
          "status_text": { "type": "string", "example": "Open Now" }
        }
      },
      "ShopService": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "shop_id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Wash & Dry Standard" },
          "description": { "type": "string", "example": "Regular full cycle wash and heated tumble dry" },
          "price": { "type": "number", "example": 160.00 },
          "price_unit": { "type": "string", "example": "flat_rate" },
          "min_kg": { "type": "number", "example": 1.0 },
          "max_kg": { "type": "number", "example": 8.0 },
          "extra_price_per_kg": { "type": "number", "example": 20.00 },
          "is_available": { "type": "boolean", "example": true }
        }
      },
      "ShopSupply": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "shop_id": { "type": "integer", "example": 1 },
          "type": { "type": "string", "enum": ["detergent", "conditioner"], "example": "detergent" },
          "name": { "type": "string", "example": "Ariel Sunrise Fresh" },
          "brand": { "type": "string", "example": "Ariel" },
          "price": { "type": "number", "example": 15.00 },
          "is_available": { "type": "boolean", "example": true }
        }
      },
      "Address": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "label": { "type": "string", "example": "Home" },
          "address_line": { "type": "string", "example": "Zone 4, Pier Site" },
          "city": { "type": "string", "example": "Bulan" },
          "landmark": { "type": "string", "example": "Bulan Port (Pier Site)" },
          "latitude": { "type": "number", "example": 12.6681 },
          "longitude": { "type": "number", "example": 123.8685 },
          "is_default": { "type": "boolean", "example": true }
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "customer_id": { "type": "integer", "example": 1 },
          "shop_id": { "type": "integer", "example": 1 },
          "rider_id": { "type": "integer", "nullable": true, "example": 1 },
          "service_type": { "type": "string", "example": "wash_dry_fold" },
          "pickup_date": { "type": "string", "format": "date-time" },
          "weight": { "type": "number", "example": 5.0 },
          "status": { "type": "string", "example": "pending" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      }
    }
  }
}
