openapi: 3.0.3
info:
  title: Care SPI
  version: 0.1.0
  description: |
    Customer Support 'Care' SPI. Customers can implement this API to bring their own
    backend for conversations.

    Scoping & REST notes:
    - Conversations are scoped to a (productSlug, customerId) pair.
    - We intentionally pass `productSlug` + `customerId` on reads as query parameters.
      `customerId` acts like a stable "external user id"; we avoid putting it in the path
      to keep URLs shorter and because some customers prefer not to treat it as a public
      hierarchy.
    - IDs returned by this API (`conversationId`, `messageId`) MUST be opaque strings.
      UUIDv4 is recommended. Do not use sequential IDs if it would enable enumeration.

servers:
  - url: https://support.premex.se
    description: Production environment
paths:
  /care/conversations:
    get:
      summary: List conversations for a customer
      parameters:
        - in: query
          name: customerId
          schema: { type: string }
          required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  conversations:
                    type: array
                    items:
                      $ref: "#/components/schemas/CareConversationSummary"
    post:
      summary: Create a new conversation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateConversationInput"
      responses:
        "200":
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  conversationId: { type: string }
                  createdAt: { type: string, format: date-time }
  /care/conversations/{conversationId}:
    get:
      summary: Get conversation detail
      parameters:
        - in: path
          name: conversationId
          required: true
          schema: { type: string }
        - in: query
          name: customerId
          schema: { type: string }
          required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CareConversationDetail"
  /care/conversations/{conversationId}/messages:
    post:
      summary: Post a message
      parameters:
        - in: path
          name: conversationId
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PostMessageInput"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  messageId: { type: string }
                  createdAt: { type: string, format: date-time }
  /care/conversations/{conversationId}/close:
    post:
      summary: Close or resolve a conversation
      parameters:
        - in: path
          name: conversationId
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CloseConversationInput"
      responses:
        "204":
          description: No Content
components:
  schemas:
    CareConversationStatus:
      type: string
      enum: [new, waiting-for-agent, waiting-for-customer, resolved, closed, unknown]
    CareConversationSummary:
      type: object
      required: [id, subject, status, isOpen, createdAt, updatedAt]
      properties:
        id: { type: string }
        subject: { type: string }
        status: { $ref: "#/components/schemas/CareConversationStatus" }
        isOpen: { type: boolean }
        createdAt: { type: string, format: date-time }
        updatedAt: { type: string, format: date-time }
    CareMessage:
      type: object
      required: [id, body, createdAt]
      properties:
        id: { type: string }
        body: { type: string, nullable: true }
        author: { type: string }
        createdAt: { type: string, format: date-time }
        isCustomer: { type: boolean }
    CareConversationDetail:
      type: object
      required: [id, subject, status, isOpen, createdAt, updatedAt, messages]
      properties:
        id: { type: string }
        subject: { type: string }
        status: { $ref: "#/components/schemas/CareConversationStatus" }
        isOpen: { type: boolean }
        createdAt: { type: string, format: date-time }
        updatedAt: { type: string, format: date-time }
        messages:
          type: array
          items:
            $ref: "#/components/schemas/CareMessage"
    CreateConversationInput:
      type: object
      required: [customerId, subject, body]
      properties:
        customerId: { type: string }
        subject: { type: string }
        body: { type: string }
    PostMessageInput:
      type: object
      required: [customerId, conversationId, body]
      properties:
        customerId: { type: string }
        conversationId: { type: string }
        body: { type: string }
    CloseConversationInput:
      type: object
      required: [customerId, conversationId, action]
      properties:
        customerId: { type: string }
        conversationId: { type: string }
        action:
          type: string
          enum: [resolve, close]

