openapi: 3.0.0
info:
  title: Анонимные опросы API
  description: API для работы с системой анонимных опросов
  version: 1.0.0
servers:
  - url: /questioneer/api
    description: Базовый URL API
paths:
  /questionnaires:
    get:
      summary: Получить список опросов пользователя
      description: Возвращает список всех опросов, сохраненных в локальном хранилище браузера
      operationId: getQuestionnaires
      responses:
        '200':
          description: Успешный запрос
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnairesResponse'
    post:
      summary: Создать новый опрос
      description: Создает новый опрос с указанными параметрами
      operationId: createQuestionnaire
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuestionnaireCreate'
      responses:
        '200':
          description: Опрос успешно создан
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireResponse'
  /questionnaires/public/{publicLink}:
    get:
      summary: Получить опрос для участия
      description: Возвращает данные опроса по публичной ссылке
      operationId: getPublicQuestionnaire
      parameters:
        - name: publicLink
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Успешный запрос
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /questionnaires/admin/{adminLink}:
    get:
      summary: Получить опрос для редактирования и просмотра результатов
      description: Возвращает данные опроса по административной ссылке
      operationId: getAdminQuestionnaire
      parameters:
        - name: adminLink
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Успешный запрос
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    put:
      summary: Обновить опрос
      description: Обновляет существующий опрос
      operationId: updateQuestionnaire
      parameters:
        - name: adminLink
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuestionnaireUpdate'
      responses:
        '200':
          description: Опрос успешно обновлен
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      summary: Удалить опрос
      description: Удаляет опрос вместе со всеми ответами
      operationId: deleteQuestionnaire
      parameters:
        - name: adminLink
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Опрос успешно удален
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /vote/{publicLink}:
    post:
      summary: Отправить ответы на опрос
      description: Отправляет ответы пользователя на опрос
      operationId: submitVote
      parameters:
        - name: publicLink
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VoteRequest'
      responses:
        '200':
          description: Ответы успешно отправлены
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /results/{publicLink}:
    get:
      summary: Получить результаты опроса
      description: Возвращает текущие результаты опроса
      operationId: getResults
      parameters:
        - name: publicLink
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Успешный запрос
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResultsResponse'
        '404':
          description: Опрос не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    QuestionnaireCreate:
      type: object
      required:
        - title
        - questions
      properties:
        title:
          type: string
          description: Название опроса
        description:
          type: string
          description: Описание опроса
        questions:
          type: array
          description: Список вопросов
          items:
            $ref: '#/components/schemas/Question'
        displayType:
          type: string
          description: Тип отображения опроса
          enum: [standard, step_by_step]
          default: standard
    QuestionnaireUpdate:
      type: object
      properties:
        title:
          type: string
          description: Название опроса
        description:
          type: string
          description: Описание опроса
        questions:
          type: array
          description: Список вопросов
          items:
            $ref: '#/components/schemas/Question'
        displayType:
          type: string
          description: Тип отображения опроса
          enum: [standard, step_by_step]
    Question:
      type: object
      required:
        - text
        - type
      properties:
        text:
          type: string
          description: Текст вопроса
        type:
          type: string
          description: Тип вопроса
          enum: [single, multiple, text, scale, rating, tagcloud]
        required:
          type: boolean
          description: Является ли вопрос обязательным
          default: false
        options:
          type: array
          description: Варианты ответа (для single, multiple)
          items:
            $ref: '#/components/schemas/Option'
        tags:
          type: array
          description: Список тегов (для tagcloud)
          items:
            $ref: '#/components/schemas/Tag'
        scaleMin:
          type: integer
          description: Минимальное значение шкалы (для scale)
          default: 0
        scaleMax:
          type: integer
          description: Максимальное значение шкалы (для scale)
          default: 10
        scaleMinLabel:
          type: string
          description: Метка для минимального значения шкалы
          default: "Минимум"
        scaleMaxLabel:
          type: string
          description: Метка для максимального значения шкалы
          default: "Максимум"
    Option:
      type: object
      required:
        - text
      properties:
        text:
          type: string
          description: Текст варианта ответа
        votes:
          type: integer
          description: Количество голосов за этот вариант
          default: 0
    Tag:
      type: object
      required:
        - text
      properties:
        text:
          type: string
          description: Текст тега
        count:
          type: integer
          description: Количество выборов данного тега
          default: 0
    VoteRequest:
      type: object
      required:
        - answers
      properties:
        answers:
          type: array
          description: Список ответов пользователя
          items:
            $ref: '#/components/schemas/Answer'
    Answer:
      type: object
      required:
        - questionIndex
      properties:
        questionIndex:
          type: integer
          description: Индекс вопроса
        optionIndices:
          type: array
          description: Индексы выбранных вариантов (для single, multiple)
          items:
            type: integer
        textAnswer:
          type: string
          description: Текстовый ответ пользователя (для text)
        scaleValue:
          type: integer
          description: Значение шкалы (для scale, rating)
        tagTexts:
          type: array
          description: Тексты выбранных или введенных тегов (для tagcloud)
          items:
            type: string
    QuestionnairesResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Успешность запроса
        data:
          type: array
          description: Список опросов
          items:
            $ref: '#/components/schemas/QuestionnaireInfo'
    QuestionnaireResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Успешность запроса
        data:
          $ref: '#/components/schemas/QuestionnaireData'
    QuestionnaireInfo:
      type: object
      properties:
        title:
          type: string
          description: Название опроса
        description:
          type: string
          description: Описание опроса
        adminLink:
          type: string
          description: Административная ссылка
        publicLink:
          type: string
          description: Публичная ссылка
        createdAt:
          type: string
          format: date-time
          description: Дата создания опроса
        updatedAt:
          type: string
          format: date-time
          description: Дата последнего обновления опроса
    QuestionnaireData:
      type: object
      properties:
        _id:
          type: string
          description: Идентификатор опроса
        title:
          type: string
          description: Название опроса
        description:
          type: string
          description: Описание опроса
        questions:
          type: array
          description: Список вопросов
          items:
            $ref: '#/components/schemas/QuestionData'
        displayType:
          type: string
          description: Тип отображения опроса
          enum: [standard, step_by_step]
        adminLink:
          type: string
          description: Административная ссылка
        publicLink:
          type: string
          description: Публичная ссылка
        createdAt:
          type: string
          format: date-time
          description: Дата создания опроса
        updatedAt:
          type: string
          format: date-time
          description: Дата последнего обновления опроса
    QuestionData:
      type: object
      properties:
        _id:
          type: string
          description: Идентификатор вопроса
        text:
          type: string
          description: Текст вопроса
        type:
          type: string
          description: Тип вопроса
        required:
          type: boolean
          description: Является ли вопрос обязательным
        options:
          type: array
          description: Варианты ответа (для single, multiple)
          items:
            $ref: '#/components/schemas/OptionData'
        tags:
          type: array
          description: Список тегов (для tagcloud)
          items:
            $ref: '#/components/schemas/TagData'
        scaleMin:
          type: integer
          description: Минимальное значение шкалы (для scale)
        scaleMax:
          type: integer
          description: Максимальное значение шкалы (для scale)
        scaleMinLabel:
          type: string
          description: Метка для минимального значения шкалы
        scaleMaxLabel:
          type: string
          description: Метка для максимального значения шкалы
        answers:
          type: array
          description: Текстовые ответы (для text)
          items:
            type: string
        scaleValues:
          type: array
          description: Значения шкалы от пользователей (для scale, rating)
          items:
            type: integer
        textAnswers:
          type: array
          description: Текстовые ответы (для text)
          items:
            type: string
        responses:
          type: array
          description: Значения шкалы от пользователей (для scale, rating)
          items:
            type: integer
    OptionData:
      type: object
      properties:
        _id:
          type: string
          description: Идентификатор варианта ответа
        text:
          type: string
          description: Текст варианта ответа
        votes:
          type: integer
          description: Количество голосов за этот вариант
        count:
          type: integer
          description: Альтернативное поле для количества голосов
    TagData:
      type: object
      properties:
        _id:
          type: string
          description: Идентификатор тега
        text:
          type: string
          description: Текст тега
        count:
          type: integer
          description: Количество выборов данного тега
    ResultsResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Успешность запроса
        data:
          $ref: '#/components/schemas/ResultsData'
    ResultsData:
      type: object
      properties:
        questions:
          type: array
          description: Список вопросов с результатами
          items:
            $ref: '#/components/schemas/QuestionResults'
    QuestionResults:
      type: object
      properties:
        text:
          type: string
          description: Текст вопроса
        type:
          type: string
          description: Тип вопроса
        options:
          type: array
          description: Варианты ответа с количеством голосов (для single, multiple)
          items:
            type: object
            properties:
              text:
                type: string
                description: Текст варианта ответа
              count:
                type: integer
                description: Количество голосов
        tags:
          type: array
          description: Список тегов с количеством выборов (для tagcloud)
          items:
            type: object
            properties:
              text:
                type: string
                description: Текст тега
              count:
                type: integer
                description: Количество выборов
        scaleValues:
          type: array
          description: Значения шкалы от пользователей (для scale, rating)
          items:
            type: integer
        scaleAverage:
          type: number
          description: Среднее значение шкалы (для scale, rating)
        answers:
          type: array
          description: Текстовые ответы (для text)
          items:
            type: string
        responses:
          type: array
          description: Значения шкалы от пользователей (для scale, rating)
          items:
            type: integer
    SuccessResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Успешность запроса
          example: true
        message:
          type: string
          description: Сообщение об успешном выполнении
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Успешность запроса
          example: false
        error:
          type: string
          description: Сообщение об ошибке 