openapi: 3.0.3
info:
  title: ExCo Workshop - Static Data API
  version: "1.0.0"
  description: |
    Read-only static API for the Part 2 build session (19.08.2026).
    Every endpoint is a static JSON file served over HTTPS - GET only, no
    authentication, no parameters. The same files ship locally in each group's
    `data/` folder as an offline fallback.

    All data is 100% synthetic (mock). Amounts in kEUR unless stated otherwise.
servers:
  - url: https://downlink.owt.team
    description: Azure static hosting

tags:
  - name: group1
    description: Customer Fleet Status Portal (one customer's fleet view)
  - name: group2
    description: Ticket Triage (18 months of service-desk tickets)
  - name: group3
    description: Group Performance Dashboard (financials per business unit)

paths:
  /group1/fleet_status.json:
    get:
      tags: [group1]
      summary: Current fleet status for the portal customer
      operationId: getFleetStatus
      responses:
        "200":
          description: Snapshot of the customer's fleet with per-vessel status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FleetStatus"

  /group1/tickets.json:
    get:
      tags: [group1]
      summary: Tickets for the portal customer's fleet
      operationId: getGroup1Tickets
      responses:
        "200":
          description: Array of tickets (subset of the service desk, this customer only)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Ticket"

  /group1/usage_daily.json:
    get:
      tags: [group1]
      summary: Daily usage and link quality per vessel, last 90 days
      operationId: getUsageDaily
      responses:
        "200":
          description: Array of daily usage records
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/UsageDaily"

  /group2/tickets.json:
    get:
      tags: [group2]
      summary: Full service-desk ticket dump, 18 months, all customers
      operationId: getGroup2Tickets
      responses:
        "200":
          description: Array of ~7,700 tickets
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Ticket"

  /group2/vessels.json:
    get:
      tags: [group2]
      summary: Vessel reference data (join on vessel name or id)
      operationId: getVessels
      responses:
        "200":
          description: Array of 800 vessels
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Vessel"

  /group2/customers.json:
    get:
      tags: [group2]
      summary: Customer reference data
      operationId: getCustomers
      responses:
        "200":
          description: Array of 40 customers
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Customer"

  /group3/revenue_actuals.json:
    get:
      tags: [group3]
      summary: Monthly revenue actuals per business unit (Jan 2025 - Jul 2026)
      operationId: getRevenueActuals
      responses:
        "200":
          description: Array of revenue records (month x business unit x region x revenue stream)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/RevenueActual"

  /group3/revenue_budget_2026.json:
    get:
      tags: [group3]
      summary: 2026 revenue budget, same dimensions as actuals
      operationId: getRevenueBudget
      responses:
        "200":
          description: Array of budget records (Jan - Dec 2026)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/RevenueBudget"

  /group3/costs_actuals.json:
    get:
      tags: [group3]
      summary: Monthly cost actuals per business unit and cost category
      operationId: getCostsActuals
      responses:
        "200":
          description: Array of cost records (Jan 2025 - Jul 2026)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CostActual"

  /group3/costs_budget_2026.json:
    get:
      tags: [group3]
      summary: 2026 cost budget, same dimensions as cost actuals
      operationId: getCostsBudget
      responses:
        "200":
          description: Array of budget records (Jan - Dec 2026)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CostBudget"

  /group3/headcount_monthly.json:
    get:
      tags: [group3]
      summary: Monthly FTE per business unit
      operationId: getHeadcount
      responses:
        "200":
          description: Array of headcount records (Jan 2025 - Jul 2026)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Headcount"

components:
  schemas:
    FleetStatus:
      type: object
      properties:
        customer:
          type: string
          example: Kystfjord Rederi AS
        customer_id:
          type: string
          example: CUST-001
        generated_at:
          type: string
          format: date
          example: "2026-08-19"
        plan_note:
          type: string
        vessels:
          type: array
          items:
            $ref: "#/components/schemas/FleetVessel"

    FleetVessel:
      type: object
      properties:
        vessel_id:
          type: string
          example: V-0001
        name:
          type: string
          example: MV Kystfjord Vega
        imo:
          type: string
          example: IMO 9621998
        type:
          type: string
          example: Cable Layer
        flag:
          type: string
          example: Bahamas
        position:
          type: object
          properties:
            lat:
              type: number
              example: 61.021
            lon:
              type: number
              example: 3.696
            region:
              type: string
              example: Norwegian Sea
        services:
          type: array
          items:
            type: string
          example: ["Eutelsat OneWeb LEO", "Iridium Certus L-band Backup"]
        link_status:
          type: string
          enum: [online, degraded, offline]
        uptime_30d_pct:
          type: number
          example: 95.4
        data_used_gb_mtd:
          type: number
          description: Data used month-to-date (GB)
        data_plan_gb:
          type: number
          description: Monthly data allowance (GB)
        open_tickets:
          type: integer

    UsageDaily:
      type: object
      properties:
        date:
          type: string
          format: date
          example: "2026-05-22"
        vessel_id:
          type: string
          example: V-0001
        vessel:
          type: string
          example: MV Kystfjord Vega
        uptime_pct:
          type: number
          example: 99
        data_gb:
          type: number
          example: 26.2
        snr_db:
          type: number
          example: 11.8

    Ticket:
      type: object
      properties:
        ticket_id:
          type: string
          example: MRL-105112
        created_at:
          type: string
          example: "2026-02-22 06:47"
          description: UTC, format YYYY-MM-DD HH:MM
        channel:
          type: string
          enum: [email, portal, phone, NOC-auto]
        customer_id:
          type: string
          example: CUST-001
        customer:
          type: string
        vessel:
          type: string
          example: MV Kystfjord Antares
        imo:
          type: string
        subject:
          type: string
        description:
          type: string
          description: Free-text body as written by the reporter
        reported_priority:
          type: string
          enum: [P1, P2, P3, P4]
          description: Priority as entered by the reporter - not always correct
        status:
          type: string
          enum: [open, in_progress, resolved]
        resolved_at:
          type: string
          description: Empty string while unresolved

    Vessel:
      type: object
      properties:
        id:
          type: string
          example: V-0001
        name:
          type: string
        imo:
          type: string
        type:
          type: string
          example: Cable Layer
        flag:
          type: string
        customer_id:
          type: string
        built:
          type: integer
          example: 2002
        status:
          type: string
          enum: [active, sold]
        sold_date:
          type: string
          description: Empty string unless status is sold
        lat:
          type: number
        lon:
          type: number
        region:
          type: string
          example: Norwegian Sea

    Customer:
      type: object
      properties:
        id:
          type: string
          example: CUST-001
        name:
          type: string
        country:
          type: string
        segment:
          type: string
          example: offshore

    RevenueActual:
      type: object
      properties:
        month:
          type: string
          example: "2026-07"
          description: Format YYYY-MM
        business_unit:
          type: string
          enum: [Maritime, Telemar TNL, EEG, OmniAccess, Cyber]
        region:
          type: string
          enum: [EMEA, APAC, Americas]
        revenue_stream:
          type: string
          example: Airtime & connectivity
        revenue_keur:
          type: number
          example: 13314.2

    RevenueBudget:
      type: object
      properties:
        month:
          type: string
          example: "2026-07"
        business_unit:
          type: string
          enum: [Maritime, Telemar TNL, EEG, OmniAccess, Cyber]
        region:
          type: string
          enum: [EMEA, APAC, Americas]
        revenue_stream:
          type: string
        budget_keur:
          type: number

    CostActual:
      type: object
      properties:
        month:
          type: string
          example: "2026-07"
        business_unit:
          type: string
          enum: [Maritime, Telemar TNL, EEG, OmniAccess, Cyber]
        cost_category:
          type: string
          example: Space segment & airtime
        cost_keur:
          type: number

    CostBudget:
      type: object
      properties:
        month:
          type: string
          example: "2026-07"
        business_unit:
          type: string
          enum: [Maritime, Telemar TNL, EEG, OmniAccess, Cyber]
        cost_category:
          type: string
        budget_keur:
          type: number

    Headcount:
      type: object
      properties:
        month:
          type: string
          example: "2026-07"
        business_unit:
          type: string
          enum: [Maritime, Telemar TNL, EEG, OmniAccess, Cyber]
        fte:
          type: integer
          example: 165
