openapi: 3.0.3

info:
  title: Stamp Verification — Public QR API (consumed)
  version: "1.0.0"
  description: |
    Контракт публичного эндпоинта, который потребляет фронтенд
    **stamp-verification-frontend** (`pdm/stamp-verification-frontend`).

    Сам фронтенд — статическая страница на nginx (ванильный JS, `static/js/index.js`)
    и **не предоставляет** собственного HTTP API. Данная спецификация описывает
    единственный внешний эндпоинт backend-сервиса **documentations**, к которому
    страница обращается для получения информации о документе по QR-коду штампа.
    Спецификация восстановлена по клиентскому коду (`index.js`) и служит
    справочным контрактом (потребитель, а не поставщик).

    ### Базовый хост
    Выбирается на клиенте по `window.location.host`:
    - `stamp-verification.sarex.io` → `https://api.sarex.io` (prod);
    - любой другой хост → `https://stage-api.sarex.io` (stage).

    ### Аутентификация
    Эндпоинт публичный (сегмент пути `/public/`). Текущий клиент тем не менее
    отправляет заголовок `Authorization: Bearer <jwt>` с **захардкоженным и
    истёкшим** токеном — это дефект клиента, а не требование API (см. замечания
    в `ENDPOINTS.md`). Запрос выполняется с `credentials: include` (CORS с
    учётными данными).

    ### Формат
    Ответ — `application/json`. Все поля опциональны/nullable: клиент подставляет
    плейсхолдер `–––` при отсутствии значения.

servers:
  - url: https://api.sarex.io
    description: prod
  - url: https://stage-api.sarex.io
    description: stage

paths:
  /documentations/api/v1/public/qr/{qr_id}/document_info:
    get:
      operationId: getQrDocumentInfo
      summary: Информация о документе по QR-коду штампа
      description: |
        Возвращает публичную информацию о документе, на который указывает QR-код
        штампа: название, версию, автора, дату загрузки, актуальность и статус
        согласования версии, сведения об изменениях (changelog) и ссылку на
        документ в Sarex.
      tags:
        - public-qr
      parameters:
        - name: qr_id
          in: path
          required: true
          description: Идентификатор QR-кода (на клиенте — query-параметр `id`).
          schema:
            type: string
          example: "b46d6b82-9e51-48e3-8dce-a38dfc6b2a26"
        - name: number_page
          in: query
          required: true
          description: Номер страницы документа (на клиенте — query-параметр `page_number`).
          schema:
            type: integer
            minimum: 1
          example: 1
      responses:
        "200":
          description: Информация о документе
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QrDocumentInfo"
        "404":
          description: Документ/QR не найден
        "422":
          description: Некорректные параметры запроса
        "500":
          description: Внутренняя ошибка сервиса

components:
  schemas:
    QrDocumentInfo:
      type: object
      description: |
        Набор полей, используемых клиентом (`static/js/index.js`). Поля
        опциональны — при отсутствии клиент отображает плейсхолдер `–––`.
      properties:
        document_name:
          type: string
          nullable: true
          description: Имя файла документа
          example: some-file-01.pdf
        version_number:
          type: string
          nullable: true
          description: Номер версии документа
          example: v2
        page_number:
          type: integer
          nullable: true
          description: Номер страницы (эхо параметра запроса); участвует в сборке ссылки на документ
          example: 1
        author:
          type: string
          nullable: true
          description: Автор версии (отображаемое имя)
          example: Андрей Алешков
        upload_date:
          type: string
          format: date-time
          nullable: true
          description: Дата и время загрузки версии (ISO 8601); на клиенте форматируется как `DD.MM.YYYY / HH:mm`
          example: "2023-05-23T20:01:55.496768Z"
        is_actual_version:
          type: boolean
          nullable: true
          description: >-
            `true` — последняя версия; `false` — не последняя; отсутствие/`null` —
            актуальность неизвестна
          example: true
        is_canceled:
          type: boolean
          nullable: true
          description: >-
            `true` — QR-код/версия аннулированы (клиент показывает предупреждение
            «QR-код аннулирован»)
          example: false
        does_bundle_have_flows:
          type: boolean
          nullable: true
          description: Есть ли у бандла процессы согласования (управляет показом блока статуса согласования)
          example: false
        is_actual_version_approved:
          type: boolean
          nullable: true
          description: Согласована ли текущая версия (при `does_bundle_have_flows = true`)
          example: true
        document_review_status:
          type: string
          nullable: true
          description: Человекочитаемый статус документа (показывается при согласованной актуальной версии)
          example: Согласован
        document_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Ссылка на документ в Sarex. Клиент открывает её как
            `${document_url}&page_number=${page_number}`
          example: https://stage.sarex.io/workspaces-v2/0244d9f9-8f32-4b65-80c7-7c403b85c81e?type=pdf
        is_latest_changelog:
          type: boolean
          nullable: true
          description: >-
            Является ли `changelog` последним. Если `false` при наличии
            `changelog` — клиент показывает предупреждение «Была выпущена новая
            версия изменения»
          example: true
        changelog:
          $ref: "#/components/schemas/Changelog"

    Changelog:
      type: object
      nullable: true
      description: Сведения об изменении версии документа
      properties:
        bundle_id:
          type: string
          format: uuid
          example: b46d6b82-9e51-48e3-8dce-a38dfc6b2a26
        "no":
          type: string
          description: Порядковый номер изменения (на клиенте выводится как `№{no}`)
          example: "2"
        description:
          type: string
          nullable: true
          description: >-
            Описание изменения. Если длиннее 20 символов — клиент включает
            сворачивание текста; при отсутствии показывает «Нет описания изменений»
          example: Внесены изменения в структуру документа. Добавлена подпись руководителя проекта.
        created_at:
          type: string
          format: date-time
          example: "2023-05-23T20:01:55.496768Z"
        updated_at:
          type: string
          format: date-time
          example: "2023-05-23T20:01:55.496768Z"
        created_by:
          type: integer
          example: 2203
        author:
          $ref: "#/components/schemas/ChangelogAuthor"

    ChangelogAuthor:
      type: object
      description: Автор изменения
      properties:
        id:
          type: integer
          example: 2203
        username:
          type: string
          example: a.aleshkov
        email:
          type: string
          format: email
          example: a.aleshkov@sarex.io
        first_name:
          type: string
          example: Андрей
        last_name:
          type: string
          example: Алешков
