"/admin/shipper/next":
    get:
        tags: [Shipping]
        operationId: findNextShippableBigOrder
        summary: Find the next shippable Big Order
        description: |
            Returns the next Big Order ready to ship. Checks shipment groups to ensure
            all items in a group are ready before suggesting an order.
        parameters:
            - in: query
              name: limit
              schema: { type: integer, maximum: 1000 }
              description: Max results.
        responses:
            "200":
                description: Next shippable Big Order with metadata.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                bigOrder: { $ref: "../components/schemas/BigOrder.yaml" }
                                readyToShip: { type: boolean }
                                reason: { type: string, description: Why this order was selected (or skipped). }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No orders are ready to ship.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/next3":
    get:
        tags: [Shipping]
        operationId: findNextShippableBigOrder3
        summary: Alias for /admin/shipper/next
        description: Identical to `GET /admin/shipper/next`.
        parameters:
            - in: query
              name: limit
              schema: { type: integer, maximum: 1000 }
        responses:
            "200":
                description: Next shippable Big Order with metadata.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                bigOrder: { $ref: "../components/schemas/BigOrder.yaml" }
                                readyToShip: { type: boolean }
                                reason: { type: string, description: Why this order was selected (or skipped). }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No orders are ready to ship.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/stats":
    get:
        tags: [Shipping]
        operationId: getBigShipperStats
        summary: Shipping system stats
        description: Returns statistics about the shipping system — shipment counts in various states, average processing times, oldest active shipment age, etc.
        responses:
            "200":
                description: Stats payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                totalShipments: { type: integer }
                                activeShipments: { type: integer }
                                shippedToday: { type: integer }
                                shippedThisWeek: { type: integer }
                                shippedThisMonth: { type: integer }
                                byStatus:
                                    type: object
                                    description: Count of shipments by `BigShipmentStatus`.
                                    properties:
                                        Init: { type: integer }
                                        Picking: { type: integer }
                                        ReadyToPack: { type: integer }
                                        Packing: { type: integer }
                                        WaitingForPickup: { type: integer }
                                        Shipped: { type: integer }
                                        Cancelled: { type: integer }
                                averageProcessingTimeMinutes: { type: number }
                                oldestActiveShipmentAge: { type: number, description: Age in minutes. }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipments":
    get:
        tags: [Shipping]
        operationId: getBigShipments
        summary: Query shipments
        description: Returns shipments matching the filter criteria.
        parameters:
            - in: query
              name: status
              schema: { type: string }
              description: Shipment status filter.
            - in: query
              name: shopifyOrderId
              schema: { type: string }
            - in: query
              name: bigOrderId
              schema: { type: string }
            - in: query
              name: limit
              schema: { type: integer, default: 100 }
            - in: query
              name: offset
              schema: { type: integer, default: 0 }
            - in: query
              name: sortBy
              schema: { type: string, default: createdAt }
            - in: query
              name: sortDirection
              schema: { type: string, enum: [asc, desc], default: desc }
            - in: query
              name: createdAfter
              schema: { type: string, format: date-time }
            - in: query
              name: createdBefore
              schema: { type: string, format: date-time }
        responses:
            "200":
                description: Shipments page.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [shipments, total, limit, offset]
                            properties:
                                shipments: { type: array, items: { $ref: "../components/schemas/BigShipment.yaml" } }
                                total: { type: integer }
                                limit: { type: integer }
                                offset: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipments/stats":
    get:
        tags: [Shipping]
        operationId: getBigShipmentsStats
        summary: Shipment stats
        responses:
            "200":
                description: Shipment stats.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                totalShipments: { type: integer }
                                byStatus:
                                    type: object
                                    additionalProperties: { type: integer }
                                averageProcessingTimeMinutes: { type: number }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipments/status":
    get:
        tags: [Shipping]
        operationId: getShipmentsWithCarrierStatus
        summary: Shipments with carrier tracking status
        description: Returns shipments paired with their current carrier tracking status.
        responses:
            "200":
                description: Shipments paired with carrier status.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                items:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            shipment: { $ref: "../components/schemas/BigShipment.yaml" }
                                            trackingStatus:
                                                type: string
                                                description: "Carrier-reported status (e.g. `in_transit`, `delivered`, `failure`)."
                                            trackingNumber: { type: string }
                                            carrier: { type: string }
                                            lastUpdatedAt: { type: string, format: date-time }
                                count: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipment":
    post:
        tags: [Shipping]
        operationId: createBigShipment
        summary: Create a shipment for a Big Order
        description: Creates a new shipment for a Big Order. If `lineItemIds` is omitted, all line items are included.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [bigOrderId]
                        properties:
                            bigOrderId: { type: string }
                            lineItemIds:
                                type: array
                                items: { type: string }
        responses:
            "200":
                description: Created shipment.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/BigShipment.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:write", "admin:all"]

"/admin/shipper/shipment/{id}":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Shipping]
        operationId: getBigShipmentExtended
        summary: Fetch a shipment with extended info
        description: Returns a shipment with embedded inventory items, history, and the associated Big Order.
        responses:
            "200":
                description: Shipment record (extended).
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/BigShipment.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No shipment with this id.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]
    put:
        tags: [Shipping]
        operationId: updateBigShipment
        summary: RPC on a shipment (state-machine action)
        description: |
            Run a remote-procedure call on an existing shipment. Shipments operate in a
            state machine — the available `action` depends on the current status. Common
            actions include `Init`, `PickInventoryItem`, `FinishPicking`,
            `CalculateShippingRates`, `GenerateShippingLabel`, `StartPacking`,
            `VerifyInventoryItem`, `FinishPacking`, `ShipIt`, `Cancel`,
            `ForceWaitingForPickup`, `ForceShipped`, `RegenerateShippingLabel`,
            `UpdateCarrierStatus`, `Update`, `ForceRemovePickedInventoryItem`. See the
            shipping module's markdown for action details.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [id, action]
                        properties:
                            id: { type: string, description: Shipment id (must match the path). }
                            action:
                                type: string
                                description: The state-machine action to run.
                            inventoryItemId: { type: string, description: For picking / verification actions. }
                            shippingRateObjectId: { type: string, description: A rate id from Shippo. }
                            shippingCode: { type: string }
                            overrideCarrierCode:
                                type: string
                                description: "Override carrier (e.g. `ups`, `usps`, `dhl_express`, `sendle`)."
                            bigShippingLabelAddressType:
                                type: string
                                enum: [Default, CustomerReturn]
                            productType:
                                type: string
                                description: "Product type — helps with slot matching."
                            accessoryProductType:
                                type: string
                                description: Deprecated.
                        additionalProperties: true
        responses:
            "200":
                description: Updated shipment.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/BigShipment.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No shipment with this id.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "422":
                description: Action invalid for the shipment's current status, or required parameters missing.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:write", "admin:all"]
    delete:
        tags: [Shipping]
        operationId: deleteBigShipment
        summary: Delete a shipment
        description: Deletes a shipment. Stricter auth than the other shipping endpoints.
        responses:
            "200":
                description: Shipment deleted.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                success: { type: boolean }
                                message: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No shipment with this id.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, FabricatorAdmin]
        x-scopes: ["shipping:write", "admin:all"]

"/admin/shipper/shipment/{id}/shopify":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Shipping]
        operationId: getBigShipmentShopifyInfo
        summary: Shopify info for a shipment
        description: Returns Shopify information related to the shipment, including fulfillment orders and fulfillment status.
        responses:
            "200":
                description: Shopify info payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                shopifyOrder:
                                    type: object
                                    description: Shape per Shopify Admin API.
                                    additionalProperties: true
                                fulfillmentOrders:
                                    type: array
                                    items:
                                        type: object
                                        description: Shopify fulfillment-order record.
                                        additionalProperties: true
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipment/{id}/checklist":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Shipping]
        operationId: getBigShipmentChecklist
        summary: Run shipment checklist
        description: Runs the shipment checklist — validates the shipment's status and identifies any issues or next steps.
        responses:
            "200":
                description: Checklist payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                status: { type: string, description: Current shipment status. }
                                nextAction: { type: string, description: Suggested next state-machine action. }
                                issues:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            severity: { type: string, description: "e.g. `error`, `warning`, `info`." }
                                            message: { type: string }
                                            code: { type: string }
                                inventoryStatus:
                                    type: object
                                    properties:
                                        required: { type: integer }
                                        picked: { type: integer }
                                        verified: { type: integer }
                                        missing:
                                            type: array
                                            items: { type: string }
                                shippingLabelStatus: { type: string }
                                canShip: { type: boolean }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/shipment/{id}/customs-preview":
    parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
    get:
        tags: [Shipping]
        operationId: getCustomsPreview
        summary: Customs declaration preview
        description: Returns a customs declaration preview for an international shipment.
        responses:
            "200":
                description: Customs preview payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                shipmentId: { type: string }
                                contentsType: { type: string, description: "e.g. `merchandise`, `gift`, `documents`." }
                                contentsExplanation: { type: string }
                                eelPfc:
                                    type: string
                                    description: Electronic Export Information / FTR exemption code.
                                nonDeliveryOption:
                                    type: string
                                    description: "`return` or `abandon`."
                                items:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            description: { type: string }
                                            quantity: { type: integer }
                                            valueAmount: { type: string }
                                            valueCurrency: { type: string }
                                            originCountry: { type: string }
                                            tariffNumber: { type: string }
                                            netWeight: { type: number }
                                            massUnit: { type: string }
                                totalDeclaredValue: { type: string }
                                currency: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, Inventory]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/sync":
    get:
        tags: [Shipping]
        operationId: shipperSync
        summary: Sync shipments
        description: Triggers a shipment sync.
        responses:
            "200":
                description: Sync result.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                shipmentsProcessed: { type: integer }
                                shipmentsUpdated: { type: integer }
                                durationMs: { type: integer }
                                errors:
                                    type: array
                                    items: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, FabricatorReadOnly]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shipper/cache_transactions":
    get:
        tags: [Shipping]
        operationId: cacheShippoTransactions
        summary: Cache Shippo transactions
        description: Triggers caching of Shippo transactions.
        responses:
            "200":
                description: Cache result.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                transactionsCached: { type: integer }
                                pagesFetched: { type: integer }
                                durationMs: { type: integer }
                                errors:
                                    type: array
                                    items: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, FabricatorReadOnly]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shippo/analytics":
    get:
        tags: [Shipping]
        operationId: getShippoAnalytics
        summary: Shippo analytics summary
        description: Returns the most recently computed analytics summary (status breakdown, time-series, totals).
        responses:
            "200":
                description: Analytics summary payload (from the Redis-backed cache).
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                generatedAt: { type: string, format: date-time }
                                totalTransactions: { type: integer }
                                totalSpend: { type: number }
                                statusBreakdown:
                                    type: object
                                    additionalProperties: { type: integer }
                                carrierBreakdown:
                                    type: object
                                    additionalProperties:
                                        type: object
                                        properties:
                                            count: { type: integer }
                                            totalCost: { type: number }
                                timeSeries:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            date: { type: string, format: date }
                                            count: { type: integer }
                                            cost: { type: number }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: '"No analytics cached yet. Trigger a refresh first."'
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, FabricatorReadOnly]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shippo/analytics/transactions":
    get:
        tags: [Shipping]
        operationId: getShippoAnalyticsTransactions
        summary: Browse cached Shippo transactions
        description: |
            Returns the cached transaction rows behind the analytics summary. Returns an
            empty `transactions` array (not 404) when the cache is empty.
        parameters:
            - in: query
              name: status
              schema: { type: string }
              description: Filter by `tx.trackingStatus`.
            - in: query
              name: minDate
              schema: { type: string, format: date-time }
            - in: query
              name: maxDate
              schema: { type: string, format: date-time }
            - in: query
              name: limit
              schema: { type: integer, default: 50 }
            - in: query
              name: offset
              schema: { type: integer, default: 0 }
        responses:
            "200":
                description: Transactions page.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [transactions, total, limit, offset]
                            properties:
                                transactions:
                                    type: array
                                    items:
                                        type: object
                                        description: Shippo transaction record (passthrough — see Shippo's spec).
                                        properties:
                                            _trackingNumber:
                                                type: string
                                                description: Redis hash key surfaced onto each row.
                                            objectId: { type: string }
                                            status: { type: string }
                                            trackingNumber: { type: string }
                                            trackingStatus: { type: string }
                                            rate: { type: string }
                                            createdAt: { type: string, format: date-time }
                                            labelUrl: { type: string, format: uri }
                                            carrier: { type: string }
                                            servicelevel:
                                                type: object
                                                additionalProperties: true
                                        additionalProperties: true
                                total: { type: integer }
                                limit: { type: integer }
                                offset: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin, FabricatorReadOnly]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shippo/analytics/cache-status":
    get:
        tags: [Shipping]
        operationId: getShippoAnalyticsCacheStatus
        summary: Shippo analytics cache status
        description: Returns when the analytics cache was last built, how many transactions it covers, and how much TTL remains.
        responses:
            "200":
                description: Cache metadata.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [metadata, ttlSeconds]
                            properties:
                                metadata:
                                    type: object
                                    properties:
                                        totalCached: { type: integer }
                                        fetchedAt: { type: string, format: date-time }
                                        maxTransactions: { type: integer }
                                ttlSeconds: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: '"No cache exists yet."'
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin, FabricatorReadOnly]
        x-scopes: ["shipping:read", "admin:all"]

"/admin/shippo/analytics/refresh":
    post:
        tags: [Shipping]
        operationId: refreshShippoAnalytics
        summary: Trigger Shippo analytics rebuild
        description: |
            Triggers the background worker that rebuilds the analytics cache: paginates
            through every Shippo transaction, writes them to Redis with a 1-hour TTL, and
            computes the summary. Fire-and-forget in production; synchronous under test.
            Stricter auth than the read-side endpoints.
        parameters:
            - in: query
              name: maxTransactions
              schema: { type: integer, default: 10000 }
              description: Max transactions to fetch in this run.
        responses:
            "200":
                description: '"OK" (plain text). The worker continues asynchronously in production — watch `/admin/workers/status` for completion.'
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["shipping:write", "admin:all"]
