openapi: 3.0.3
info:
  title: ControlOne API
  version: "1.0.0"
  description: |
    Documentazione REST API di **ControlOne** — piattaforma fleet management, telemetria veicoli, geofencing e reportistica.

    ## Autenticazione

    La maggior parte degli endpoint richiede un token **Laravel Sanctum** ottenuto tramite `POST /login`.

    Includere l'header in ogni richiesta protetta:

    ```
    Authorization: Bearer {token}
    Accept: application/json
    Content-Type: application/json
    ```

    Opzionale: `Accept-Language: it` oppure campo `language` nel body per localizzare i messaggi.

    ## Formato risposta standard

    ```json
    {
      "status": true,
      "message": "Messaggio descrittivo",
      "data": {}
    }
    ```

    Gli endpoint **Route Tracking** e **Device** rispondono con JSON semplice (senza wrapper `status`).

  contact:
    name: ControlOne / i4m
    url: https://ctrlone.i4m.it
  license:
    name: Proprietary

servers:
  - url: https://ctrlone.i4m.it/api
    description: Produzione
  - url: http://localhost:8000/api
    description: Sviluppo locale

tags:
  - name: Account
    description: Login, profilo utente, notifiche e impostazioni account
  - name: Dashboard
    description: Statistiche aggregate della flotta
  - name: Vehicles
    description: Anagrafica veicoli e eventi/manutenzioni
  - name: Fleet
    description: Posizione live, dettagli e cronologia GPS
  - name: Reports
    description: Generazione ed export report (carburante, percorsi, allarmi)
  - name: Geofences
    description: Zone geografiche e assegnazione ai veicoli
  - name: RouteTracking
    description: Aggiornamento percorsi assegnati (integrazione parser/device)
  - name: Device
    description: Eventi dispositivo Teltonika e risposte comandi (integrazione parser)

paths:
  /login:
    post:
      tags: [Account]
      summary: Account_Login
      description: Autentica un utente e restituisce il token Sanctum.
      operationId: Account_Login
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                  example: user@example.com
                password:
                  type: string
                  format: password
                fcm_token:
                  type: string
                  nullable: true
                  description: Token Firebase per push notification mobile
                language:
                  type: string
                  example: it
      responses:
        "200":
          description: Login riuscito
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LoginResponse"
        "422":
          $ref: "#/components/responses/ValidationError"

  /forgot-password:
    post:
      tags: [Account]
      summary: Account_ForgotPassword
      operationId: Account_ForgotPassword
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                  format: email
      responses:
        "200":
          description: Email di reset inviata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /validate-token:
    post:
      tags: [Account]
      summary: Account_ValidateToken
      operationId: Account_ValidateToken
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [token]
              properties:
                token:
                  type: string
      responses:
        "200":
          description: Token valido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LoginResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /profile:
    get:
      tags: [Account]
      summary: Account_GetProfile
      operationId: Account_GetProfile
      responses:
        "200":
          description: Profilo utente
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  user:
                    $ref: "#/components/schemas/User"

  /logout:
    get:
      tags: [Account]
      summary: Account_Logout
      operationId: Account_Logout
      description: Invalida il token corrente e azzera il token FCM.
      responses:
        "200":
          description: Logout riuscito
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /update-fcm-token:
    post:
      tags: [Account]
      summary: Account_UpdateFcmToken
      operationId: Account_UpdateFcmToken
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                fcm_token:
                  type: string
                  nullable: true
      responses:
        "200":
          description: Token aggiornato
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /update-language:
    post:
      tags: [Account]
      summary: Account_UpdateLanguage
      operationId: Account_UpdateLanguage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [language]
              properties:
                language:
                  type: string
                  example: it
      responses:
        "200":
          description: Lingua aggiornata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /notifications:
    get:
      tags: [Account]
      summary: Account_GetNotifications
      operationId: Account_GetNotifications
      parameters:
        - $ref: "#/components/parameters/Page"
        - name: per_page
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 15
      responses:
        "200":
          description: Elenco notifiche paginato
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  notifications:
                    type: array
                    items:
                      $ref: "#/components/schemas/Notification"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /update-password:
    post:
      tags: [Account]
      summary: Account_UpdatePassword
      operationId: Account_UpdatePassword
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [current_password, new_password]
              properties:
                current_password:
                  type: string
                new_password:
                  type: string
                  minLength: 6
      responses:
        "200":
          description: Password aggiornata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"
        "422":
          $ref: "#/components/responses/ValidationError"

  /contact-admin:
    post:
      tags: [Account]
      summary: Account_ContactAdmin
      operationId: Account_ContactAdmin
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [message]
              properties:
                title:
                  type: string
                message:
                  type: string
      responses:
        "200":
          description: Messaggio inviato
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /dashboard/stats:
    get:
      tags: [Dashboard]
      summary: Dashboard_GetStats
      operationId: Dashboard_GetStats
      description: Statistiche flotta, elenco veicoli live e ultime notifiche.
      responses:
        "200":
          description: Statistiche dashboard
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardStatsResponse"

  /vehicles:
    get:
      tags: [Vehicles]
      summary: Vehicles_List
      operationId: Vehicles_List
      parameters:
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: search
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: Elenco veicoli paginato
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicles:
                    type: array
                    items:
                      $ref: "#/components/schemas/VehicleListItem"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /vehicles/{id}:
    get:
      tags: [Vehicles]
      summary: Vehicles_GetById
      operationId: Vehicles_GetById
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Dettaglio veicolo
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicle:
                    $ref: "#/components/schemas/VehicleDetail"

  /vehicles/{vehicleId}/events:
    get:
      tags: [Vehicles]
      summary: Vehicles_GetEvents
      operationId: Vehicles_GetEvents
      parameters:
        - name: vehicleId
          in: path
          required: true
          schema:
            type: integer
        - $ref: "#/components/parameters/Page"
        - name: per_page
          in: query
          schema:
            type: integer
            default: 15
        - name: event_type
          in: query
          schema:
            type: string
        - name: maintenance_status
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Eventi e manutenzioni del veicolo
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  events:
                    type: array
                    items:
                      $ref: "#/components/schemas/VehicleEvent"
                  vehicle:
                    type: object
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /fleet/vehicles:
    get:
      tags: [Fleet]
      summary: Fleet_GetVehicles
      operationId: Fleet_GetVehicles
      description: Tutti i veicoli con dati live (GPS, velocità, carburante). Cache 5 minuti per utente.
      responses:
        "200":
          description: Veicoli con telemetria live
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicles:
                    type: array
                    items:
                      $ref: "#/components/schemas/FleetVehicle"

  /fleet/vehicles-list:
    get:
      tags: [Fleet]
      summary: Fleet_GetVehiclesGrouped
      operationId: Fleet_GetVehiclesGrouped
      description: Veicoli raggruppati per tipologia (es. car, truck).
      responses:
        "200":
          description: Veicoli raggruppati per tipo
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicles:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        $ref: "#/components/schemas/FleetVehicle"

  /fleet/vehicles/{id}/details:
    get:
      tags: [Fleet]
      summary: Fleet_GetVehicleDetails
      operationId: Fleet_GetVehicleDetails
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Dettaglio completo veicolo (indirizzo, percorso, fermate, indicatori)
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicle:
                    $ref: "#/components/schemas/FleetVehicleDetails"

  /fleet/vehicles/history:
    post:
      tags: [Fleet]
      summary: Fleet_GetVehicleHistory
      operationId: Fleet_GetVehicleHistory
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [imei, date]
              properties:
                imei:
                  type: string
                  example: "352094123456789"
                date:
                  type: string
                  description: Formato DD-MM-YYYY
                  example: "09-06-2026"
      responses:
        "200":
          description: Tracciato GPS, fermate e consumo al minimo del giorno
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FleetHistoryResponse"

  /reports/vehicles:
    get:
      tags: [Reports]
      summary: Reports_GetVehicles
      operationId: Reports_GetVehicles
      parameters:
        - name: search
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Veicoli disponibili per report
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicles:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        display_name:
                          type: string
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /reports/generate:
    post:
      tags: [Reports]
      summary: Reports_Generate
      operationId: Reports_Generate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReportGenerateRequest"
      responses:
        "200":
          description: Report generato o accodato
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  message:
                    type: string
                  redirect:
                    type: boolean
                  data:
                    type: object
                    nullable: true

  /reports/download-daily:
    post:
      tags: [Reports]
      summary: Reports_DownloadDaily
      operationId: Reports_DownloadDaily
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [vehicle_id, report_type, date, format]
              properties:
                vehicle_id:
                  type: integer
                report_type:
                  type: string
                  enum: [routes, fuel_consumption, alarms]
                date:
                  type: string
                  format: date
                format:
                  type: string
                  enum: [pdf, csv]
      responses:
        "200":
          description: File PDF o CSV
          content:
            application/pdf:
              schema:
                type: string
                format: binary
            text/csv:
              schema:
                type: string
                format: binary

  /reports/export-history:
    get:
      tags: [Reports]
      summary: Reports_GetExportHistory
      operationId: Reports_GetExportHistory
      parameters:
        - $ref: "#/components/parameters/Page"
        - name: per_page
          in: query
          schema:
            type: integer
            default: 10
      responses:
        "200":
          description: Storico export report
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  reports:
                    type: array
                    items:
                      $ref: "#/components/schemas/ExportReport"

  /reports/export-delete/{reportId}:
    post:
      tags: [Reports]
      summary: Reports_DeleteExport
      operationId: Reports_DeleteExport
      parameters:
        - name: reportId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Export eliminato
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /geofences:
    get:
      tags: [Geofences]
      summary: Geofences_List
      operationId: Geofences_List
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 15
        - $ref: "#/components/parameters/PerPage"
        - name: search
          in: query
          schema:
            type: string
        - name: filter
          in: query
          schema:
            type: string
            enum: [all, active, inactive]
      responses:
        "200":
          description: Elenco geofence
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  geofences:
                    type: array
                    items:
                      $ref: "#/components/schemas/Geofence"
                  pagination:
                    $ref: "#/components/schemas/Pagination"
    post:
      tags: [Geofences]
      summary: Geofences_Create
      operationId: Geofences_Create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GeofenceCreateRequest"
      responses:
        "201":
          description: Geofence creata
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  geofence:
                    $ref: "#/components/schemas/Geofence"

  /geofences/{id}:
    get:
      tags: [Geofences]
      summary: Geofences_GetById
      operationId: Geofences_GetById
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Dettaglio geofence con veicoli assegnati
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  geofence:
                    $ref: "#/components/schemas/GeofenceDetail"

  /geofences/update:
    post:
      tags: [Geofences]
      summary: Geofences_Update
      operationId: Geofences_Update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/GeofenceCreateRequest"
                - type: object
                  required: [id]
                  properties:
                    id:
                      type: integer
      responses:
        "200":
          description: Geofence aggiornata
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  geofence:
                    $ref: "#/components/schemas/Geofence"

  /geofences/delete:
    post:
      tags: [Geofences]
      summary: Geofences_Delete
      operationId: Geofences_Delete
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [id]
              properties:
                id:
                  type: integer
      responses:
        "200":
          description: Geofence eliminata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /geofences/vehicles/list:
    get:
      tags: [Geofences]
      summary: Geofences_GetVehiclesList
      operationId: Geofences_GetVehiclesList
      parameters:
        - name: search
          in: query
          schema:
            type: string
        - name: geofence_id
          in: query
          schema:
            type: integer
      responses:
        "200":
          description: Veicoli per assegnazione geofence
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  vehicles:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        license_plate:
                          type: string
                        imei:
                          type: string
                        is_assigned:
                          type: boolean

  /geofences/assign-vehicles:
    post:
      tags: [Geofences]
      summary: Geofences_AssignVehicles
      operationId: Geofences_AssignVehicles
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [geofence_id, vehicle_ids]
              properties:
                geofence_id:
                  type: integer
                vehicle_ids:
                  type: array
                  minItems: 1
                  items:
                    type: integer
                push_notification:
                  type: boolean
                email_notification:
                  type: boolean
                geofence_in_notification:
                  type: boolean
                geofence_out_notification:
                  type: boolean
      responses:
        "200":
          description: Veicoli assegnati (max 5 zone per IMEI)
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                  assigned_vehicles:
                    type: array
                    items:
                      type: object
                  errors:
                    type: array
                    items:
                      type: string

  /geofences/remove-vehicle:
    post:
      tags: [Geofences]
      summary: Geofences_RemoveVehicle
      operationId: Geofences_RemoveVehicle
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [geofence_id, vehicle_id]
              properties:
                geofence_id:
                  type: integer
                vehicle_id:
                  type: integer
      responses:
        "200":
          description: Assegnazione rimossa
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /geofences/vehicles/sync:
    post:
      tags: [Geofences]
      summary: Geofences_SyncVehicle
      operationId: Geofences_SyncVehicle
      description: Re-invia i comandi geofence Teltonika al dispositivo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [geofence_id, vehicle_id]
              properties:
                geofence_id:
                  type: integer
                vehicle_id:
                  type: integer
      responses:
        "200":
          description: Sincronizzazione avviata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusMessage"

  /update-route:
    post:
      tags: [RouteTracking]
      summary: RouteTracking_UpdateRoute
      operationId: RouteTracking_UpdateRoute
      security: []
      description: Aggiorna stato percorso (partenza, fermata, arrivo). Usato dal parser Python.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [route_id, type, timestamp]
              properties:
                route_id:
                  type: integer
                type:
                  type: string
                  enum: [start_point, stop_point, end_point]
                timestamp:
                  type: string
                  format: date-time
                stop_id:
                  type: integer
                  description: Obbligatorio se type = stop_point
                io_data:
                  type: object
                  description: Dati IO Teltonika (chiavi 16=odometro, 33/83/12=carburante)
      responses:
        "200":
          description: Percorso aggiornato
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        "404":
          description: Percorso non trovato

  /complete-route:
    post:
      tags: [RouteTracking]
      summary: RouteTracking_CompleteRoute
      operationId: RouteTracking_CompleteRoute
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [route_id, timestamp]
              properties:
                route_id:
                  type: integer
                timestamp:
                  type: string
                  format: date-time
      responses:
        "200":
          description: Percorso completato
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        "400":
          description: Fermate ancora pending

  /log-device-event:
    post:
      tags: [Device]
      summary: Device_LogEvent
      operationId: Device_LogEvent
      security: []
      description: Registra eventi dispositivo (crash, batteria, geofence zone 155-159).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [imei, data]
              properties:
                imei:
                  type: string
                data:
                  type: object
                  properties:
                    eventID:
                      type: integer
                      example: 247
      responses:
        "200":
          description: Evento registrato
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  message:
                    type: string

  /log-geofence-event:
    post:
      tags: [Device]
      summary: Device_LogGeofenceEvent
      operationId: Device_LogGeofenceEvent
      security: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                imei:
                  type: string
                geofence_id:
                  type: integer
                type:
                  type: string
                latitude:
                  type: number
                longitude:
                  type: number
      responses:
        "200":
          description: Evento geofence registrato
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success

  /save-command-response:
    post:
      tags: [Device]
      summary: Device_SaveCommandResponse
      operationId: Device_SaveCommandResponse
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [imei, response]
              properties:
                imei:
                  type: string
                response:
                  type: string
                command:
                  type: string
      responses:
        "200":
          description: Risposta comando salvata
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  message:
                    type: string

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Sanctum
      description: Token ottenuto da POST /login

  parameters:
    Page:
      name: page
      in: query
      schema:
        type: integer
        minimum: 1
        default: 1
    PerPage:
      name: per_page
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 10

  responses:
    ValidationError:
      description: Errore di validazione
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: boolean
                example: false
              message:
                type: string
              errors:
                type: object
    Unauthorized:
      description: Token non valido o scaduto
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/StatusMessage"

  schemas:
    StatusMessage:
      type: object
      properties:
        status:
          type: boolean
        message:
          type: string

    Pagination:
      type: object
      properties:
        total:
          type: integer
        per_page:
          type: integer
        current_page:
          type: integer
        last_page:
          type: integer

    Permissions:
      type: object
      properties:
        fleet_view:
          type: boolean
        dashboard_view:
          type: boolean
        user_view:
          type: boolean
        driver_view:
          type: boolean
        vehicle_view:
          type: boolean
        remote_control:
          type: boolean
        geofence_view:
          type: boolean
        reporting_view:
          type: boolean

    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
        language:
          type: string

    LoginResponse:
      type: object
      properties:
        status:
          type: boolean
        message:
          type: string
        token:
          type: string
        user:
          $ref: "#/components/schemas/User"
        permissions:
          $ref: "#/components/schemas/Permissions"

    Notification:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        body:
          type: string
        created_at:
          type: string
        created_at_human:
          type: string

    VehicleListItem:
      type: object
      properties:
        id:
          type: integer
        license_plate:
          type: string
        driver_name:
          type: string
        model:
          type: string
        mileage:
          type: number
        type:
          type: string
        icon_url:
          type: string
        status:
          type: boolean
        status_text:
          type: string

    VehicleDetail:
      allOf:
        - $ref: "#/components/schemas/VehicleListItem"
        - type: object
          properties:
            imei:
              type: string
            vin:
              type: string
            year_of_registration:
              type: integer
            current_odometer_reading:
              type: number

    VehicleEvent:
      type: object
      properties:
        id:
          type: integer
        event_type:
          type: string
        description:
          type: string
        start_date:
          type: string
        end_date:
          type: string
        maintenance_status:
          type: string

    FleetVehicle:
      type: object
      properties:
        id:
          type: integer
        imei:
          type: string
        license_plate:
          type: string
        model:
          type: string
        latitude:
          type: number
        longitude:
          type: number
        speed:
          type: number
        angle:
          type: number
        movement_status:
          type: integer
        ignition_status:
          type: integer
        fuel_level_percentage:
          type: number
        last_update:
          type: string

    FleetVehicleDetails:
      allOf:
        - $ref: "#/components/schemas/FleetVehicle"
        - type: object
          properties:
            address:
              type: string
            daily_distance:
              type: number
            daily_fuel:
              type: number
            current_route:
              type: object
              nullable: true
            indicators:
              type: object

    FleetHistoryResponse:
      type: object
      properties:
        status:
          type: boolean
        history_data:
          type: array
          items:
            type: object
            properties:
              latitude:
                type: number
              longitude:
                type: number
              speed:
                type: number
              timestamp:
                type: string
        stops:
          type: array
          items:
            type: object
        total_stops:
          type: integer
        total_stop_time:
          type: string
        idle_consumption:
          type: number

    DashboardStatsResponse:
      type: object
      properties:
        status:
          type: boolean
        stats:
          type: object
          properties:
            total_vehicles:
              type: integer
            moving_count:
              type: integer
            parked_count:
              type: integer
            stopped_count:
              type: integer
        vehicles:
          type: array
          items:
            $ref: "#/components/schemas/FleetVehicle"
        notifications:
          type: array
          items:
            $ref: "#/components/schemas/Notification"

    ReportGenerateRequest:
      type: object
      required: [vehicle_id, report_type, period_type]
      properties:
        vehicle_id:
          type: integer
        report_type:
          type: string
          enum: [routes, fuel_consumption, alarms]
        period_type:
          type: string
          enum: [daily, monthly, custom]
        start_date:
          type: string
          format: date
        end_date:
          type: string
          format: date

    ExportReport:
      type: object
      properties:
        id:
          type: integer
        report_type:
          type: string
        status:
          type: string
        download_url:
          type: string
        created_at:
          type: string

    Geofence:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        location:
          type: string
        is_active:
          type: boolean
        push_notification:
          type: boolean
        email_notification:
          type: boolean
        geofence_data:
          type: object
        assigned_vehicles_count:
          type: integer

    GeofenceDetail:
      allOf:
        - $ref: "#/components/schemas/Geofence"
        - type: object
          properties:
            assigned_vehicles:
              type: array
              items:
                type: object
                properties:
                  vehicle_id:
                    type: integer
                  license_plate:
                    type: string
                  zone_number:
                    type: integer

    GeofenceCreateRequest:
      type: object
      required: [name, geofence_data]
      properties:
        name:
          type: string
        location:
          type: string
        geofence_data:
          type: object
          description: Forma circle o polygon con coordinate
        push_notification:
          type: boolean
        email_notification:
          type: boolean
        is_active:
          type: boolean

security:
  - bearerAuth: []
