1469 lines
43 KiB
YAML
1469 lines
43 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: Volunteer Coordination API
|
||
description: |
|
||
API для системы координации волонтёрской помощи маломобильным людям.
|
||
|
||
Система позволяет:
|
||
- Маломобильным гражданам создавать заявки на помощь
|
||
- Волонтёрам находить заявки рядом с собой и откликаться на них
|
||
- Модераторам управлять заявками и пользователями
|
||
- Администраторам управлять пользователями и ролями
|
||
version: 1.0.1
|
||
contact:
|
||
name: API Support
|
||
email: api@volontery.example.com
|
||
license:
|
||
name: MIT
|
||
url: https://opensource.org/licenses/MIT
|
||
|
||
servers:
|
||
- url: http://localhost:8080/api/v1
|
||
description: Development server
|
||
- url: https://api.volontery.example.com/api/v1
|
||
description: Production server
|
||
|
||
tags:
|
||
- name: health
|
||
description: Проверка здоровья сервиса
|
||
- name: auth
|
||
description: Аутентификация и авторизация
|
||
- name: users
|
||
description: Управление пользователями
|
||
- name: requests
|
||
description: Управление заявками на помощь
|
||
- name: responses
|
||
description: Отклики волонтёров на заявки
|
||
- name: moderation
|
||
description: Модерация заявок (требуется роль moderator или admin)
|
||
- name: admin
|
||
description: Административные функции (требуется роль admin)
|
||
|
||
security:
|
||
- BearerAuth: []
|
||
|
||
paths:
|
||
/health:
|
||
get:
|
||
tags: [health]
|
||
summary: Проверка здоровья сервиса
|
||
security: []
|
||
responses:
|
||
'200':
|
||
description: Сервис работает
|
||
content:
|
||
text/plain:
|
||
schema:
|
||
type: string
|
||
example: OK
|
||
|
||
# ==================== AUTH ====================
|
||
/auth/register:
|
||
post:
|
||
tags: [auth]
|
||
summary: Регистрация нового пользователя
|
||
description: Создает нового пользователя в системе
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/RegisterRequest'
|
||
responses:
|
||
'201':
|
||
description: Пользователь успешно зарегистрирован
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/AuthResponse'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/auth/login:
|
||
post:
|
||
tags: [auth]
|
||
summary: Вход в систему
|
||
description: Аутентификация пользователя по email и паролю
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/LoginRequest'
|
||
responses:
|
||
'200':
|
||
description: Успешная аутентификация
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/AuthResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/auth/refresh:
|
||
post:
|
||
tags: [auth]
|
||
summary: Обновление токенов
|
||
description: Получение новой пары access/refresh токенов
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [refresh_token]
|
||
properties:
|
||
refresh_token:
|
||
type: string
|
||
description: Refresh токен
|
||
responses:
|
||
'200':
|
||
description: Токены успешно обновлены
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/AuthResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/auth/me:
|
||
get:
|
||
tags: [auth]
|
||
summary: Информация о текущем пользователе
|
||
description: Возвращает базовую информацию об аутентифицированном пользователе
|
||
responses:
|
||
'200':
|
||
description: Информация о пользователе
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
email:
|
||
type: string
|
||
format: email
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/auth/logout:
|
||
post:
|
||
tags: [auth]
|
||
summary: Выход из системы
|
||
description: Отзывает все refresh токены пользователя
|
||
responses:
|
||
'200':
|
||
description: Успешный выход
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: logged out successfully
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
# ==================== USERS ====================
|
||
/users/me:
|
||
get:
|
||
tags: [users]
|
||
summary: Получение профиля текущего пользователя
|
||
description: Возвращает детальную информацию о профиле
|
||
responses:
|
||
'200':
|
||
description: Профиль пользователя
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserProfile'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
patch:
|
||
tags: [users]
|
||
summary: Обновление профиля
|
||
description: Обновляет информацию в профиле пользователя
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateProfileInput'
|
||
responses:
|
||
'200':
|
||
description: Профиль успешно обновлен
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: profile updated successfully
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/me/location:
|
||
post:
|
||
tags: [users]
|
||
summary: Обновление местоположения
|
||
description: Обновляет координаты домашнего адреса пользователя
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [latitude, longitude]
|
||
properties:
|
||
latitude:
|
||
type: number
|
||
format: double
|
||
minimum: -90
|
||
maximum: 90
|
||
example: 55.751244
|
||
longitude:
|
||
type: number
|
||
format: double
|
||
minimum: -180
|
||
maximum: 180
|
||
example: 37.618423
|
||
responses:
|
||
'200':
|
||
description: Местоположение обновлено
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: location updated successfully
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/me/verify-email:
|
||
post:
|
||
tags: [users]
|
||
summary: Подтверждение email адреса
|
||
description: |
|
||
Подтверждает email адрес текущего пользователя.
|
||
В полноценной системе должен принимать токен подтверждения из письма.
|
||
responses:
|
||
'200':
|
||
description: Email успешно подтвержден
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: email verified successfully
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'500':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/me/roles:
|
||
get:
|
||
tags: [users]
|
||
summary: Получение ролей пользователя
|
||
description: Возвращает список ролей текущего пользователя
|
||
responses:
|
||
'200':
|
||
description: Список ролей
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Role'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/me/permissions:
|
||
get:
|
||
tags: [users]
|
||
summary: Получение разрешений пользователя
|
||
description: Возвращает список всех разрешений текущего пользователя
|
||
responses:
|
||
'200':
|
||
description: Список разрешений
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Permission'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/me/permissions/{permission_name}/check:
|
||
get:
|
||
tags: [users]
|
||
summary: Проверка наличия разрешения
|
||
description: Проверяет, есть ли у текущего пользователя указанное разрешение
|
||
parameters:
|
||
- name: permission_name
|
||
in: path
|
||
required: true
|
||
description: Название разрешения для проверки
|
||
schema:
|
||
type: string
|
||
example: create_request
|
||
examples:
|
||
create_request:
|
||
value: create_request
|
||
summary: Разрешение на создание заявок
|
||
moderate_request:
|
||
value: moderate_request
|
||
summary: Разрешение на модерацию заявок
|
||
manage_users:
|
||
value: manage_users
|
||
summary: Разрешение на управление пользователями
|
||
responses:
|
||
'200':
|
||
description: Результат проверки разрешения
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PermissionCheckResult'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'500':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/users/{id}:
|
||
get:
|
||
tags: [users]
|
||
summary: Получение профиля пользователя по ID
|
||
description: Возвращает публичную информацию о пользователе
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
responses:
|
||
'200':
|
||
description: Профиль пользователя
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserProfile'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
# ==================== REQUEST TYPES ====================
|
||
/request-types:
|
||
get:
|
||
tags: [requests]
|
||
summary: Получение списка типов заявок
|
||
description: Возвращает справочник типов помощи
|
||
security: []
|
||
responses:
|
||
'200':
|
||
description: Список типов заявок
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestType'
|
||
|
||
# ==================== REQUESTS ====================
|
||
/requests:
|
||
post:
|
||
tags: [requests]
|
||
summary: Создание новой заявки
|
||
description: Создает заявку на помощь от имени текущего пользователя
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateRequestInput'
|
||
responses:
|
||
'201':
|
||
description: Заявка успешно создана
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Request'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/my:
|
||
get:
|
||
tags: [requests]
|
||
summary: Получение заявок пользователя
|
||
description: Возвращает список заявок, созданных текущим пользователем
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Список заявок
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestListItem'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/nearby:
|
||
get:
|
||
tags: [requests]
|
||
summary: Поиск заявок рядом с точкой
|
||
description: Геопространственный поиск заявок в радиусе от указанной точки
|
||
parameters:
|
||
- name: lat
|
||
in: query
|
||
required: true
|
||
description: Широта
|
||
schema:
|
||
type: number
|
||
format: double
|
||
minimum: -90
|
||
maximum: 90
|
||
- name: lon
|
||
in: query
|
||
required: true
|
||
description: Долгота
|
||
schema:
|
||
type: number
|
||
format: double
|
||
minimum: -180
|
||
maximum: 180
|
||
- name: radius
|
||
in: query
|
||
required: false
|
||
description: Радиус поиска в метрах (по умолчанию 5000)
|
||
schema:
|
||
type: number
|
||
format: double
|
||
default: 5000
|
||
minimum: 100
|
||
maximum: 50000
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Список найденных заявок
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestWithDistance'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/bounds:
|
||
get:
|
||
tags: [requests]
|
||
summary: Поиск заявок в прямоугольной области
|
||
description: Возвращает заявки в заданной прямоугольной области (для отображения на карте)
|
||
parameters:
|
||
- name: min_lon
|
||
in: query
|
||
required: true
|
||
description: Минимальная долгота (левый нижний угол)
|
||
schema:
|
||
type: number
|
||
format: double
|
||
- name: min_lat
|
||
in: query
|
||
required: true
|
||
description: Минимальная широта (левый нижний угол)
|
||
schema:
|
||
type: number
|
||
format: double
|
||
- name: max_lon
|
||
in: query
|
||
required: true
|
||
description: Максимальная долгота (правый верхний угол)
|
||
schema:
|
||
type: number
|
||
format: double
|
||
- name: max_lat
|
||
in: query
|
||
required: true
|
||
description: Максимальная широта (правый верхний угол)
|
||
schema:
|
||
type: number
|
||
format: double
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Список заявок в области
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestListItem'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/{id}:
|
||
get:
|
||
tags: [requests]
|
||
summary: Получение заявки по ID
|
||
description: Возвращает детальную информацию о заявке
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
responses:
|
||
'200':
|
||
description: Детальная информация о заявке
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/RequestDetail'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/{id}/complete:
|
||
post:
|
||
tags: [requests]
|
||
summary: Завершение заявки с оценкой
|
||
description: Создатель заявки завершает выполненную заявку и оценивает волонтёра
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- rating
|
||
properties:
|
||
rating:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 5
|
||
description: Оценка работы волонтёра (от 1 до 5)
|
||
example: 5
|
||
comment:
|
||
type: string
|
||
nullable: true
|
||
description: Комментарий к оценке
|
||
example: Отличная работа, спасибо!
|
||
responses:
|
||
'200':
|
||
description: Заявка завершена успешно
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
example: true
|
||
message:
|
||
type: string
|
||
example: request completed successfully
|
||
rating_id:
|
||
type: integer
|
||
format: int64
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
# ==================== RESPONSES ====================
|
||
/requests/{id}/responses:
|
||
get:
|
||
tags: [responses]
|
||
summary: Получение откликов на заявку
|
||
description: Возвращает список откликов волонтёров на заявку
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
responses:
|
||
'200':
|
||
description: Список откликов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/VolunteerResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
post:
|
||
tags: [responses]
|
||
summary: Создание отклика на заявку
|
||
description: Волонтёр откликается на заявку о помощи
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
description: Сообщение волонтёра
|
||
example: Готов помочь завтра после 15:00
|
||
responses:
|
||
'201':
|
||
description: Отклик успешно создан
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/VolunteerResponse'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/requests/{id}/responses/{response_id}/accept:
|
||
post:
|
||
tags: [responses]
|
||
summary: Принятие отклика волонтёра
|
||
description: Создатель заявки принимает отклик волонтёра и назначает его на заявку
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
- name: response_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
responses:
|
||
'200':
|
||
description: Отклик принят, волонтёр назначен
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
example: true
|
||
message:
|
||
type: string
|
||
example: volunteer assigned successfully
|
||
request_id:
|
||
type: integer
|
||
format: int64
|
||
volunteer_id:
|
||
type: integer
|
||
format: int64
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
# ==================== MODERATION ====================
|
||
/moderation/requests/pending:
|
||
get:
|
||
tags: [moderation]
|
||
summary: Получение заявок на модерацию
|
||
description: Возвращает заявки со статусом pending_moderation (требуется роль moderator или admin)
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Список заявок на модерацию
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestListItem'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/moderation/requests/my:
|
||
get:
|
||
tags: [moderation]
|
||
summary: Получение моих промодерированных заявок
|
||
description: Возвращает заявки, которые были промодерированы текущим пользователем
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Список промодерированных заявок
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/RequestListItem'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/moderation/requests/{id}/approve:
|
||
post:
|
||
tags: [moderation]
|
||
summary: Одобрение заявки
|
||
description: Модератор одобряет заявку, меняет её статус на approved
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
requestBody:
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
comment:
|
||
type: string
|
||
nullable: true
|
||
description: Комментарий модератора (необязательно)
|
||
example: Заявка соответствует требованиям
|
||
responses:
|
||
'200':
|
||
description: Заявка одобрена
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
status:
|
||
type: string
|
||
example: approved
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/moderation/requests/{id}/reject:
|
||
post:
|
||
tags: [moderation]
|
||
summary: Отклонение заявки
|
||
description: Модератор отклоняет заявку, меняет её статус на rejected
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- comment
|
||
properties:
|
||
comment:
|
||
type: string
|
||
description: Причина отклонения (обязательно)
|
||
example: Недостаточно информации для выполнения заявки
|
||
responses:
|
||
'200':
|
||
description: Заявка отклонена
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
status:
|
||
type: string
|
||
example: rejected
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
/moderation/requests/{id}/moderate:
|
||
post:
|
||
tags: [moderation]
|
||
summary: Модерация заявки (альтернативный метод)
|
||
description: |
|
||
Модерирует заявку через stored procedure в БД.
|
||
Альтернатива отдельным эндпоинтам approve/reject.
|
||
Выполняет approve или reject в одной транзакции через БД процедуру.
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ModerationAction'
|
||
responses:
|
||
'200':
|
||
description: Заявка успешно промодерирована
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ModerationResult'
|
||
'400':
|
||
description: Некорректные данные запроса
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: string
|
||
examples:
|
||
- value: action must be 'approve' or 'reject'
|
||
- value: comment is required when rejecting
|
||
- value: request is not in pending_moderation status
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
# ==================== ADMIN ====================
|
||
/admin/users/{user_id}/roles/{role_id}:
|
||
post:
|
||
tags: [admin]
|
||
summary: Назначение роли пользователю
|
||
description: |
|
||
Назначает роль пользователю (требуется роль admin или разрешение manage_users).
|
||
Только администраторы могут управлять ролями пользователей.
|
||
parameters:
|
||
- name: user_id
|
||
in: path
|
||
required: true
|
||
description: ID пользователя
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
- name: role_id
|
||
in: path
|
||
required: true
|
||
description: ID роли для назначения
|
||
schema:
|
||
type: integer
|
||
format: int64
|
||
responses:
|
||
'200':
|
||
description: Роль успешно назначена
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/RoleAssignmentResult'
|
||
'400':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'401':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
'403':
|
||
description: Недостаточно прав доступа
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: string
|
||
example: admin role required
|
||
'404':
|
||
$ref: '#/components/responses/ErrorResponse'
|
||
|
||
components:
|
||
securitySchemes:
|
||
BearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
description: 'JWT токен в формате: Bearer {token}'
|
||
|
||
parameters:
|
||
Limit:
|
||
name: limit
|
||
in: query
|
||
description: Количество результатов на странице
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 100
|
||
default: 20
|
||
|
||
Offset:
|
||
name: offset
|
||
in: query
|
||
description: Смещение для пагинации
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
default: 0
|
||
|
||
schemas:
|
||
# ==================== AUTH SCHEMAS ====================
|
||
RegisterRequest:
|
||
type: object
|
||
required:
|
||
- email
|
||
- password
|
||
- first_name
|
||
- last_name
|
||
properties:
|
||
email:
|
||
type: string
|
||
format: email
|
||
example: user@example.com
|
||
password:
|
||
type: string
|
||
format: password
|
||
minLength: 8
|
||
example: SecureP@ssw0rd
|
||
first_name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
example: Иван
|
||
last_name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
example: Иванов
|
||
phone:
|
||
type: string
|
||
pattern: '^\+?[1-9]\d{1,14}$'
|
||
example: '+79001234567'
|
||
latitude:
|
||
type: number
|
||
format: double
|
||
minimum: -90
|
||
maximum: 90
|
||
example: 55.751244
|
||
longitude:
|
||
type: number
|
||
format: double
|
||
minimum: -180
|
||
maximum: 180
|
||
example: 37.618423
|
||
address:
|
||
type: string
|
||
example: Красная площадь, 1
|
||
city:
|
||
type: string
|
||
example: Москва
|
||
bio:
|
||
type: string
|
||
maxLength: 500
|
||
example: Рад помочь пожилым людям с покупками
|
||
|
||
LoginRequest:
|
||
type: object
|
||
required:
|
||
- email
|
||
- password
|
||
properties:
|
||
email:
|
||
type: string
|
||
format: email
|
||
example: user@example.com
|
||
password:
|
||
type: string
|
||
format: password
|
||
example: SecureP@ssw0rd
|
||
|
||
AuthResponse:
|
||
type: object
|
||
properties:
|
||
access_token:
|
||
type: string
|
||
description: JWT access токен
|
||
refresh_token:
|
||
type: string
|
||
description: Refresh токен
|
||
expires_in:
|
||
type: integer
|
||
format: int64
|
||
description: Время жизни access токена в секундах
|
||
user:
|
||
$ref: '#/components/schemas/UserInfo'
|
||
|
||
UserInfo:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
email:
|
||
type: string
|
||
format: email
|
||
first_name:
|
||
type: string
|
||
last_name:
|
||
type: string
|
||
email_verified:
|
||
type: boolean
|
||
|
||
# ==================== USER SCHEMAS ====================
|
||
UserProfile:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
email:
|
||
type: string
|
||
format: email
|
||
first_name:
|
||
type: string
|
||
last_name:
|
||
type: string
|
||
phone:
|
||
type: string
|
||
nullable: true
|
||
bio:
|
||
type: string
|
||
nullable: true
|
||
avatar_url:
|
||
type: string
|
||
nullable: true
|
||
address:
|
||
type: string
|
||
nullable: true
|
||
city:
|
||
type: string
|
||
nullable: true
|
||
volunteer_rating:
|
||
type: number
|
||
format: double
|
||
nullable: true
|
||
completed_requests_count:
|
||
type: integer
|
||
nullable: true
|
||
is_verified:
|
||
type: boolean
|
||
is_blocked:
|
||
type: boolean
|
||
email_verified:
|
||
type: boolean
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
UpdateProfileInput:
|
||
type: object
|
||
properties:
|
||
first_name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
last_name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 100
|
||
phone:
|
||
type: string
|
||
bio:
|
||
type: string
|
||
maxLength: 500
|
||
address:
|
||
type: string
|
||
city:
|
||
type: string
|
||
|
||
Role:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
name:
|
||
type: string
|
||
example: volunteer
|
||
description:
|
||
type: string
|
||
nullable: true
|
||
|
||
Permission:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
name:
|
||
type: string
|
||
example: create_request
|
||
resource:
|
||
type: string
|
||
example: request
|
||
action:
|
||
type: string
|
||
example: create
|
||
description:
|
||
type: string
|
||
nullable: true
|
||
|
||
PermissionCheckResult:
|
||
type: object
|
||
properties:
|
||
has_permission:
|
||
type: boolean
|
||
description: Есть ли у пользователя это разрешение
|
||
permission_name:
|
||
type: string
|
||
description: Название проверяемого разрешения
|
||
|
||
# ==================== REQUEST SCHEMAS ====================
|
||
RequestType:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
name:
|
||
type: string
|
||
example: Покупка продуктов
|
||
description:
|
||
type: string
|
||
nullable: true
|
||
icon:
|
||
type: string
|
||
nullable: true
|
||
is_active:
|
||
type: boolean
|
||
|
||
CreateRequestInput:
|
||
type: object
|
||
required:
|
||
- request_type_id
|
||
- title
|
||
- description
|
||
- latitude
|
||
- longitude
|
||
- address
|
||
- urgency
|
||
properties:
|
||
request_type_id:
|
||
type: integer
|
||
format: int64
|
||
title:
|
||
type: string
|
||
minLength: 5
|
||
maxLength: 200
|
||
example: Нужна помощь с покупкой продуктов
|
||
description:
|
||
type: string
|
||
minLength: 10
|
||
maxLength: 2000
|
||
example: Прошу помочь купить продукты в ближайшем магазине
|
||
latitude:
|
||
type: number
|
||
format: double
|
||
minimum: -90
|
||
maximum: 90
|
||
longitude:
|
||
type: number
|
||
format: double
|
||
minimum: -180
|
||
maximum: 180
|
||
address:
|
||
type: string
|
||
example: ул. Ленина, д. 10, кв. 5
|
||
city:
|
||
type: string
|
||
example: Москва
|
||
desired_completion_date:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
urgency:
|
||
type: string
|
||
enum: [low, medium, high, urgent]
|
||
example: high
|
||
contact_phone:
|
||
type: string
|
||
example: '+79001234567'
|
||
contact_notes:
|
||
type: string
|
||
example: Код домофона 123, 3 этаж
|
||
|
||
Request:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
requester_id:
|
||
type: integer
|
||
format: int64
|
||
request_type_id:
|
||
type: integer
|
||
format: int64
|
||
assigned_volunteer_id:
|
||
type: integer
|
||
format: int64
|
||
nullable: true
|
||
title:
|
||
type: string
|
||
description:
|
||
type: string
|
||
address:
|
||
type: string
|
||
city:
|
||
type: string
|
||
nullable: true
|
||
desired_completion_date:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
urgency:
|
||
type: string
|
||
nullable: true
|
||
status:
|
||
$ref: '#/components/schemas/RequestStatus'
|
||
contact_phone:
|
||
type: string
|
||
nullable: true
|
||
contact_notes:
|
||
type: string
|
||
nullable: true
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
RequestListItem:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
title:
|
||
type: string
|
||
description:
|
||
type: string
|
||
address:
|
||
type: string
|
||
city:
|
||
type: string
|
||
urgency:
|
||
type: string
|
||
status:
|
||
$ref: '#/components/schemas/RequestStatus'
|
||
requester_name:
|
||
type: string
|
||
request_type_name:
|
||
type: string
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
RequestWithDistance:
|
||
allOf:
|
||
- $ref: '#/components/schemas/RequestListItem'
|
||
- type: object
|
||
properties:
|
||
distance_meters:
|
||
type: number
|
||
format: double
|
||
description: Расстояние до заявки в метрах
|
||
|
||
RequestDetail:
|
||
allOf:
|
||
- $ref: '#/components/schemas/Request'
|
||
- type: object
|
||
properties:
|
||
requester:
|
||
$ref: '#/components/schemas/UserInfo'
|
||
request_type:
|
||
$ref: '#/components/schemas/RequestType'
|
||
assigned_volunteer:
|
||
$ref: '#/components/schemas/UserInfo'
|
||
nullable: true
|
||
|
||
RequestStatus:
|
||
type: string
|
||
enum:
|
||
- pending_moderation
|
||
- approved
|
||
- in_progress
|
||
- completed
|
||
- cancelled
|
||
- rejected
|
||
|
||
# ==================== RESPONSE SCHEMAS ====================
|
||
VolunteerResponse:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: integer
|
||
format: int64
|
||
request_id:
|
||
type: integer
|
||
format: int64
|
||
volunteer_id:
|
||
type: integer
|
||
format: int64
|
||
volunteer_name:
|
||
type: string
|
||
status:
|
||
$ref: '#/components/schemas/ResponseStatus'
|
||
message:
|
||
type: string
|
||
nullable: true
|
||
responded_at:
|
||
type: string
|
||
format: date-time
|
||
accepted_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
rejected_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
ResponseStatus:
|
||
type: string
|
||
enum:
|
||
- pending
|
||
- accepted
|
||
- rejected
|
||
- cancelled
|
||
|
||
# ==================== MODERATION SCHEMAS ====================
|
||
ModerationAction:
|
||
type: object
|
||
required:
|
||
- action
|
||
properties:
|
||
action:
|
||
type: string
|
||
enum: [approve, reject]
|
||
description: Действие модерации
|
||
example: approve
|
||
comment:
|
||
type: string
|
||
nullable: true
|
||
description: Комментарий модератора (обязателен при reject)
|
||
example: Заявка соответствует требованиям
|
||
|
||
ModerationResult:
|
||
type: object
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
example: true
|
||
message:
|
||
type: string
|
||
example: request moderated successfully
|
||
new_status:
|
||
type: string
|
||
enum: [approved, rejected]
|
||
example: approved
|
||
|
||
# ==================== ADMIN SCHEMAS ====================
|
||
RoleAssignmentResult:
|
||
type: object
|
||
properties:
|
||
message:
|
||
type: string
|
||
example: role assigned successfully
|
||
user_id:
|
||
type: integer
|
||
format: int64
|
||
role_id:
|
||
type: integer
|
||
format: int64
|
||
|
||
# ==================== ERROR SCHEMAS ====================
|
||
responses:
|
||
ErrorResponse:
|
||
description: Ошибка
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: string
|
||
description: Описание ошибки |