openapi: 3.0.3
info:
  title: FlowChat dve_exchange API
  description: |
    Очередь сообщений между пользователями (сессия как у ленты).
    Лимиты и идемпотентность см. GET action=capabilities.
  version: "1.0"
servers:
  - url: https://api.f-chat.ru
paths:
  /dve_exchange.php:
    get:
      summary: inbox / outbox / gateway keys / capabilities / metrics
      parameters:
        - name: action
          in: query
          schema:
            type: string
            enum: [inbox, outbox, gateway_public_key, capabilities, metrics]
        - name: after_id
          in: query
          schema: { type: integer, default: 0 }
        - name: limit
          in: query
          schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
        - name: unread
          in: query
          description: только для inbox
          schema: { type: string, enum: ["1", "true", "yes"] }
        - name: key
          in: query
          description: секрет для metrics (env FLOWCHAT_DVE_EX_METRICS_SECRET)
          schema: { type: string }
      responses:
        "200":
          description: JSON (ok, messages, limits, …)
        "401":
          description: не авторизован
        "503":
          description: gateway не настроен (gateway_public_key)
    post:
      summary: send / ack_read
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/Send"
                - $ref: "#/components/schemas/AckRead"
      responses:
        "200":
          description: успех
        "400":
          description: ошибка запроса / расшифровки
        "401":
          description: не авторизован
        "429":
          description: лимит отправки / непрочитанных у получателя
        "503":
          description: gateway недоступен
components:
  schemas:
    Send:
      type: object
      required: [action, to_user_hash]
      properties:
        action:
          type: string
          enum: [send]
        to_user_hash:
          type: string
          pattern: "^[a-f0-9]{64}$"
        routing_mode:
          type: string
          enum: [e2e, gateway]
          default: e2e
        client_msg_id:
          type: string
          maxLength: 128
          description: идемпотентность повторных запросов
        payload:
          type: string
          description: для e2e — opaque текст
        gateway_envelope:
          type: object
          description: для gateway
          properties:
            ek: { type: string, format: byte }
            iv: { type: string, format: byte }
            ct: { type: string, format: byte }
            kid: { type: string, description: id ключа шифрования }
    AckRead:
      type: object
      required: [action, ids]
      properties:
        action:
          type: string
          enum: [ack_read]
        ids:
          type: array
          items: { type: integer }
          maxItems: 200
