openapi: 3.0.3
info:
  title: JCT CRM Mobile API
  version: 1.0.0
  description: |
    OpenAPI specification for the Android/mobile API.
    Base path is /api/v1 and authentication is Bearer token via Laravel Sanctum.
servers:
  - url: http://localhost/api/v1
    description: Local development
  - url: https://your-domain.example/api/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Auth
  - name: Health
  - name: Lookups
  - name: Customers
  - name: Vehicles
  - name: Job Cards
  - name: Tasks
  - name: Parts
  - name: Suppliers
  - name: Files
  - name: Inspection Categories
  - name: Notes
  - name: Stock
  - name: Vehicle MOTs
  - name: Vehicle Defects
  - name: Plans
  - name: Users
paths:
  /health:
    get:
      tags: [Health]
      summary: Health check
      security: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok

  /auth/login:
    post:
      tags: [Auth]
      summary: Login and create API token
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                device_name:
                  type: string
                  example: android-app
      responses:
        '200':
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  token_type:
                    type: string
                    example: Bearer
                  access_token:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
        '422':
          $ref: '#/components/responses/ValidationError'

  /auth/me:
    get:
      tags: [Auth]
      summary: Get current authenticated user
      responses:
        '200':
          description: Current user
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    $ref: '#/components/schemas/User'

  /auth/switch-team:
    post:
      tags: [Auth]
      summary: Switch current team context
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [team_id]
              properties:
                team_id:
                  type: integer
      responses:
        '200':
          description: Team switched
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
        '403':
          $ref: '#/components/responses/Forbidden'

  /auth/logout:
    post:
      tags: [Auth]
      summary: Revoke current token
      responses:
        '200':
          description: Logged out
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /lookups/vehicle-types:
    get:
      tags: [Lookups]
      summary: List vehicle types
      responses:
        '200':
          description: Vehicle types
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VehicleType'

  /lookups/job-card-types:
    get:
      tags: [Lookups]
      summary: List job card types
      responses:
        '200':
          description: Job card types
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobCardType'

  /lookups/job-card-statuses:
    get:
      tags: [Lookups]
      summary: List job card statuses
      responses:
        '200':
          description: Job card statuses
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobCardStatus'

  /lookups/file-types:
    get:
      tags: [Lookups]
      summary: List file types
      responses:
        '200':
          description: File types
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FileType'

  /customers:
    get:
      tags: [Customers]
      summary: List customers
      parameters:
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: Customer list
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedCustomer'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Customer'
    post:
      tags: [Customers]
      summary: Create customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerWrite'
      responses:
        '200':
          description: Customer created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '201':
          description: Customer created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '422':
          $ref: '#/components/responses/ValidationError'

  /customers/{id}:
    get:
      tags: [Customers]
      summary: Get customer
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Customer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
    put:
      tags: [Customers]
      summary: Update customer
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerWrite'
      responses:
        '200':
          description: Customer updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
    delete:
      tags: [Customers]
      summary: Delete customer
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Customer deleted

  /vehicles:
    get:
      tags: [Vehicles]
      summary: List vehicles
      parameters:
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: Vehicles
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedVehicle'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Vehicle'
    post:
      tags: [Vehicles]
      summary: Create vehicle
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleWrite'
      responses:
        '200':
          description: Vehicle created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehicle'
        '201':
          description: Vehicle created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehicle'

  /vehicles/{id}:
    get:
      tags: [Vehicles]
      summary: Get vehicle
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Vehicle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehicle'
    put:
      tags: [Vehicles]
      summary: Update vehicle
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleWrite'
      responses:
        '200':
          description: Vehicle updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehicle'
    delete:
      tags: [Vehicles]
      summary: Delete vehicle
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Vehicle deleted

  /job-cards:
    get:
      tags: [Job Cards]
      summary: List job cards
      parameters:
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: Job cards
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedJobCard'
                  - type: array
                    items:
                      $ref: '#/components/schemas/JobCard'
    post:
      tags: [Job Cards]
      summary: Create job card
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobCardWrite'
      responses:
        '200':
          description: Job card created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCard'
        '201':
          description: Job card created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCard'

  /job-cards/{id}:
    get:
      tags: [Job Cards]
      summary: Get job card
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Job card
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCard'
    put:
      tags: [Job Cards]
      summary: Update job card
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobCardWrite'
      responses:
        '200':
          description: Job card updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCard'
    delete:
      tags: [Job Cards]
      summary: Delete job card
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Job card deleted

  /tasks:
    get:
      tags: [Tasks]
      summary: List tasks
      responses:
        '200':
          description: Tasks
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedTask'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Task'
    post:
      tags: [Tasks]
      summary: Create task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskWrite'
      responses:
        '200':
          description: Task created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '201':
          description: Task created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'

  /tasks/{id}:
    get:
      tags: [Tasks]
      summary: Get task
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Task
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
    put:
      tags: [Tasks]
      summary: Update task
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskWrite'
      responses:
        '200':
          description: Task updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
    delete:
      tags: [Tasks]
      summary: Delete task
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Task deleted

  /parts:
    get:
      tags: [Parts]
      summary: List parts
      responses:
        '200':
          description: Parts
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedPart'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Part'
    post:
      tags: [Parts]
      summary: Create part
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartWrite'
      responses:
        '200':
          description: Part created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Part'
        '201':
          description: Part created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Part'

  /parts/{id}:
    get:
      tags: [Parts]
      summary: Get part
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Part
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Part'
    put:
      tags: [Parts]
      summary: Update part
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartWrite'
      responses:
        '200':
          description: Part updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Part'
    delete:
      tags: [Parts]
      summary: Delete part
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Part deleted

  /suppliers:
    get:
      tags: [Suppliers]
      summary: List suppliers
      responses:
        '200':
          description: Suppliers
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedSupplier'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Supplier'
    post:
      tags: [Suppliers]
      summary: Create supplier
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SupplierWrite'
      responses:
        '200':
          description: Supplier created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Supplier'
        '201':
          description: Supplier created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Supplier'

  /suppliers/{id}:
    get:
      tags: [Suppliers]
      summary: Get supplier
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Supplier
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Supplier'
    put:
      tags: [Suppliers]
      summary: Update supplier
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SupplierWrite'
      responses:
        '200':
          description: Supplier updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Supplier'
    delete:
      tags: [Suppliers]
      summary: Delete supplier
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Supplier deleted

  /files:
    get:
      tags: [Files]
      summary: List files
      responses:
        '200':
          description: Files
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedFile'
                  - type: array
                    items:
                      $ref: '#/components/schemas/File'
    post:
      tags: [Files]
      summary: Upload files
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                files:
                  type: array
                  items:
                    type: string
                    format: binary
      responses:
        '200':
          description: Files uploaded

  /files/{id}:
    get:
      tags: [Files]
      summary: Get file
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: File
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/File'
    put:
      tags: [Files]
      summary: Update file
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
      responses:
        '200':
          description: File updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/File'
    delete:
      tags: [Files]
      summary: Delete file
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: File deleted

  /inspection-categories:
    get:
      tags: [Inspection Categories]
      summary: List inspection categories
      responses:
        '200':
          description: Inspection categories
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedInspectionCategory'
                  - type: array
                    items:
                      $ref: '#/components/schemas/InspectionCategory'
    post:
      tags: [Inspection Categories]
      summary: Create inspection category
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InspectionCategoryWrite'
      responses:
        '200':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InspectionCategory'
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InspectionCategory'

  /inspection-categories/{id}:
    get:
      tags: [Inspection Categories]
      summary: Get inspection category
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Inspection category
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InspectionCategory'
    put:
      tags: [Inspection Categories]
      summary: Update inspection category
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InspectionCategoryWrite'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InspectionCategory'
    delete:
      tags: [Inspection Categories]
      summary: Delete inspection category
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Deleted

  /job-card-types:
    get:
      tags: [Job Cards]
      summary: List job card types
      responses:
        '200':
          description: Job card types
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobCardType'

  /job-card-types/{id}:
    get:
      tags: [Job Cards]
      summary: Get job card type
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Job card type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCardType'

  /users:
    get:
      tags: [Users]
      summary: List users in scope
      responses:
        '200':
          description: Users
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaginatedUser'
                  - type: array
                    items:
                      $ref: '#/components/schemas/User'

  /users/{id}:
    get:
      tags: [Users]
      summary: Get user
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: User
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  /notes:
    get:
      tags: [Notes]
      summary: List notes
      parameters:
        - $ref: '#/components/parameters/PerPage'
        - in: query
          name: noteable_type
          schema:
            type: string
            enum: [vehicle, job_card, customer]
        - in: query
          name: noteable_id
          schema:
            type: integer
      responses:
        '200':
          description: Notes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedNote'
    post:
      tags: [Notes]
      summary: Create note
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoteWrite'
      responses:
        '201':
          description: Note created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Note'

  /notes/{id}:
    get:
      tags: [Notes]
      summary: Get note
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Note
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Note'
    put:
      tags: [Notes]
      summary: Update note
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [note]
              properties:
                note:
                  type: string
      responses:
        '200':
          description: Note updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Note'
    delete:
      tags: [Notes]
      summary: Delete note
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Note deleted

  /stocks:
    get:
      tags: [Stock]
      summary: List stock
      parameters:
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: Stock list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedStock'
    post:
      tags: [Stock]
      summary: Create stock item
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StockWrite'
      responses:
        '201':
          description: Stock created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Stock'

  /stocks/{id}:
    get:
      tags: [Stock]
      summary: Get stock item
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Stock
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Stock'
    put:
      tags: [Stock]
      summary: Update stock item
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StockWrite'
      responses:
        '200':
          description: Stock updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Stock'
    delete:
      tags: [Stock]
      summary: Delete stock item
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Stock deleted

  /vehicle-mots:
    get:
      tags: [Vehicle MOTs]
      summary: List MOT records
      parameters:
        - $ref: '#/components/parameters/PerPage'
        - in: query
          name: vehicle_id
          schema:
            type: integer
      responses:
        '200':
          description: MOT list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVehicleMot'
    post:
      tags: [Vehicle MOTs]
      summary: Create MOT record
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleMotWrite'
      responses:
        '201':
          description: MOT created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleMot'

  /vehicle-mots/{id}:
    get:
      tags: [Vehicle MOTs]
      summary: Get MOT record
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: MOT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleMot'
    put:
      tags: [Vehicle MOTs]
      summary: Update MOT record
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleMotWrite'
      responses:
        '200':
          description: MOT updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleMot'
    delete:
      tags: [Vehicle MOTs]
      summary: Delete MOT record
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: MOT deleted

  /vehicle-defects:
    get:
      tags: [Vehicle Defects]
      summary: List vehicle defects
      parameters:
        - $ref: '#/components/parameters/PerPage'
        - in: query
          name: vehicle_id
          schema:
            type: integer
        - in: query
          name: vehicle_mot_id
          schema:
            type: integer
      responses:
        '200':
          description: Defects list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVehicleDefect'
    post:
      tags: [Vehicle Defects]
      summary: Create vehicle defect
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleDefectWrite'
      responses:
        '201':
          description: Defect created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleDefect'

  /vehicle-defects/{id}:
    get:
      tags: [Vehicle Defects]
      summary: Get vehicle defect
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Defect
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleDefect'
    put:
      tags: [Vehicle Defects]
      summary: Update vehicle defect
      parameters:
        - $ref: '#/components/parameters/IdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VehicleDefectWrite'
      responses:
        '200':
          description: Defect updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleDefect'
    delete:
      tags: [Vehicle Defects]
      summary: Delete vehicle defect
      parameters:
        - $ref: '#/components/parameters/IdPath'
      responses:
        '200':
          description: Defect deleted

  /plans:
    get:
      tags: [Plans]
      summary: List plans
      responses:
        '200':
          description: Plans
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Plan'

  /plans/{slug}:
    get:
      tags: [Plans]
      summary: Get plan by slug
      parameters:
        - in: path
          name: slug
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plan'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Token

  parameters:
    IdPath:
      in: path
      name: id
      required: true
      schema:
        type: integer
    PerPage:
      in: query
      name: per_page
      schema:
        type: integer
        minimum: 1
        maximum: 100

  responses:
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
              errors:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: string
    Forbidden:
      description: Forbidden
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string

  schemas:
    Team:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
        current_team_id:
          type: integer
          nullable: true
        current_team:
          $ref: '#/components/schemas/Team'
        teams:
          type: array
          items:
            $ref: '#/components/schemas/Team'

    Customer:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          nullable: true
        team_id:
          type: integer
        markup:
          type: number
          format: float
        labour_day_rate:
          type: number
          format: float
        labour_night_rate:
          type: number
          format: float
        call_out_day_rate:
          type: number
          format: float
        call_out_night_rate:
          type: number
          format: float

    CustomerWrite:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
          format: email
          nullable: true
        markup:
          type: number
          format: float
        labour_day_rate:
          type: number
          format: float
        labour_night_rate:
          type: number
          format: float
        call_out_day_rate:
          type: number
          format: float
        call_out_night_rate:
          type: number
          format: float
        accounting_id:
          type: string
          nullable: true
        address:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        county:
          type: string
          nullable: true
        postcode:
          type: string
          nullable: true

    Vehicle:
      type: object
      properties:
        id:
          type: integer
        registration:
          type: string
        customer_id:
          type: integer
        type_id:
          type: integer
        make:
          type: string
        model:
          type: string
        team_id:
          type: integer

    VehicleWrite:
      type: object
      properties:
        registration:
          type: string
        customer_id:
          type: integer
        type_id:
          type: integer
        make:
          type: string
        model:
          type: string
        mileage:
          type: number

    VehicleType:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        slug:
          type: string
        description:
          type: string

    JobCard:
      type: object
      properties:
        id:
          type: integer
        display_number:
          type: string
        customer_id:
          type: integer
        vehicle_id:
          type: integer
        job_card_type_id:
          type: integer
        job_card_status_id:
          type: integer
        summary:
          type: string

    JobCardWrite:
      type: object
      properties:
        customer_id:
          type: integer
        vehicle_id:
          type: integer
        job_card_type_id:
          type: integer
        job_card_status_id:
          type: integer
        user_id:
          type: integer
          nullable: true
        summary:
          type: string

    JobCardType:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
        name:
          type: string

    JobCardStatus:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
        name:
          type: string

    Task:
      type: object
      properties:
        id:
          type: integer
        description:
          type: string
        user_id:
          type: integer
        team_id:
          type: integer

    TaskWrite:
      type: object
      properties:
        description:
          type: string
        job_card_id:
          type: integer
          nullable: true
        assigned_to:
          type: integer
          nullable: true
        due_date:
          type: string
          format: date-time
          nullable: true
        hours:
          type: number
          format: float
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true

    Part:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        cost:
          type: number
          format: float
        sku:
          type: string

    PartWrite:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        cost:
          type: number
          format: float
        sku:
          type: string
        supplier_id:
          type: integer

    Supplier:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        address:
          type: string
        city:
          type: string
        county:
          type: string
        postcode:
          type: string
        phone:
          type: string
        email:
          type: string
          nullable: true

    SupplierWrite:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
          nullable: true
        address:
          type: string
        city:
          type: string
        county:
          type: string
          nullable: true
        postcode:
          type: string
        phone:
          type: string
        email:
          type: string
          nullable: true
        website:
          type: string
          nullable: true

    File:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        extension:
          type: string
        mime_type:
          type: string
        path:
          type: string

    FileType:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
        name:
          type: string

    InspectionCategory:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        im_number:
          type: integer
        is_active:
          type: boolean
        is_mandatory:
          type: boolean
        trailer_excluded:
          type: boolean

    InspectionCategoryWrite:
      type: object
      properties:
        name:
          type: string
        im_number:
          type: integer
        is_active:
          type: boolean
        is_mandatory:
          type: boolean
        trailer_excluded:
          type: boolean

    Note:
      type: object
      properties:
        id:
          type: integer
        note:
          type: string
        noteable_id:
          type: integer
        noteable_type:
          type: string
        user_id:
          type: integer
        team_id:
          type: integer

    NoteWrite:
      type: object
      required: [note, noteable_type, noteable_id]
      properties:
        note:
          type: string
        noteable_type:
          type: string
          enum: [vehicle, job_card, customer]
        noteable_id:
          type: integer

    Stock:
      type: object
      properties:
        id:
          type: integer
        part_id:
          type: integer
        supplier_id:
          type: integer
          nullable: true
        quantity:
          type: number
          format: float
        location:
          type: string
          nullable: true
        user_id:
          type: integer
        team_id:
          type: integer

    StockWrite:
      type: object
      properties:
        part_id:
          type: integer
        supplier_id:
          type: integer
          nullable: true
        quantity:
          type: number
          format: float
        location:
          type: string
          nullable: true

    VehicleMot:
      type: object
      properties:
        id:
          type: integer
        team_id:
          type: integer
        vehicle_id:
          type: integer
        test_date:
          type: string
          format: date
          nullable: true
        test_type:
          type: string
          nullable: true
        mot_test_number:
          type: string
        expiry_date:
          type: string
          format: date
          nullable: true
        location:
          type: string
          nullable: true
        odometer_value:
          type: number
          format: float
          nullable: true
        odometer_unit:
          type: string
          nullable: true
        result:
          type: string
          nullable: true
        odometer_result_type:
          type: string
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true

    VehicleMotWrite:
      type: object
      properties:
        vehicle_id:
          type: integer
        test_date:
          type: string
          format: date
          nullable: true
        test_type:
          type: string
          nullable: true
        mot_test_number:
          type: string
        expiry_date:
          type: string
          format: date
          nullable: true
        location:
          type: string
          nullable: true
        odometer_value:
          type: number
          format: float
          nullable: true
        odometer_unit:
          type: string
          nullable: true
        result:
          type: string
          nullable: true
        odometer_result_type:
          type: string
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true

    VehicleDefect:
      type: object
      properties:
        id:
          type: integer
        vehicle_mot_id:
          type: integer
        vehicle_id:
          type: integer
        team_id:
          type: integer
        defect:
          type: string
        type:
          type: string
          nullable: true
        failure_item_no:
          type: string
          nullable: true
        failure_reason:
          type: string
          nullable: true
        severity_code:
          type: string
          nullable: true
        severity_description:
          type: string
          nullable: true
        dangerous:
          type: boolean
          nullable: true
        test_defect:
          type: boolean
          nullable: true
        resolution:
          type: string
          nullable: true
        resolved_at:
          type: string
          format: date-time
          nullable: true

    VehicleDefectWrite:
      type: object
      properties:
        vehicle_mot_id:
          type: integer
        vehicle_id:
          type: integer
          nullable: true
        defect:
          type: string
        type:
          type: string
          nullable: true
        failure_item_no:
          type: string
          nullable: true
        failure_reason:
          type: string
          nullable: true
        severity_code:
          type: string
          nullable: true
        severity_description:
          type: string
          nullable: true
        dangerous:
          type: boolean
          nullable: true
        test_defect:
          type: boolean
          nullable: true
        resolution:
          type: string
          nullable: true
        resolved_at:
          type: string
          format: date-time
          nullable: true

    Plan:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        slug:
          type: string
        stripe_plan:
          type: string
        cost:
          type: number
          format: float
        description:
          type: string
          nullable: true
        active:
          type: boolean

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

    PaginatedCustomer:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Customer'

    PaginatedVehicle:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Vehicle'

    PaginatedJobCard:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/JobCard'

    PaginatedTask:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Task'

    PaginatedPart:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Part'

    PaginatedSupplier:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Supplier'

    PaginatedFile:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/File'

    PaginatedInspectionCategory:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/InspectionCategory'

    PaginatedUser:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/User'

    PaginatedNote:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Note'

    PaginatedStock:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Stock'

    PaginatedVehicleMot:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/VehicleMot'

    PaginatedVehicleDefect:
      allOf:
        - $ref: '#/components/schemas/PaginationMeta'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/VehicleDefect'
