forked from mtusi2026/mtusi2026lab2
2027 lines
63 KiB
JSON
2027 lines
63 KiB
JSON
{
|
|
"openapi": "3.1.0",
|
|
"info": {
|
|
"title": "MTUSI Messenger — лабораторная 2",
|
|
"version": "1.2.0",
|
|
"description": "Нормативный минимум на 3. Семантика: contracts/README.md. Расширения на 4/5 не должны менять этот API. Наличие кода ошибки в схеме не требует реализовать факультативную причину его выдачи."
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "http://localhost:8080",
|
|
"description": "Локальный учебный стенд"
|
|
}
|
|
],
|
|
"security": [
|
|
{
|
|
"bearerAuth": []
|
|
}
|
|
],
|
|
"paths": {
|
|
"/health/live": {
|
|
"get": {
|
|
"operationId": "liveness",
|
|
"summary": "Процесс жив",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Health"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"security": []
|
|
}
|
|
},
|
|
"/health/ready": {
|
|
"get": {
|
|
"operationId": "readiness",
|
|
"summary": "Готов принимать трафик",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Health"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"security": []
|
|
}
|
|
},
|
|
"/api/v1/users": {
|
|
"post": {
|
|
"operationId": "registerUser",
|
|
"summary": "Создать пользователя",
|
|
"responses": {
|
|
"201": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/User"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"security": [],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CreateUser"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/users/me": {
|
|
"get": {
|
|
"operationId": "currentUser",
|
|
"summary": "Текущий пользователь",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/User"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/chats": {
|
|
"post": {
|
|
"operationId": "createChat",
|
|
"summary": "Создать чат; вызывающий должен входить в member_ids",
|
|
"responses": {
|
|
"201": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Chat"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CreateChat"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"get": {
|
|
"operationId": "listChats",
|
|
"summary": "Чаты текущего пользователя",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ChatPage"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 50
|
|
}
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/chats/{chat_id}": {
|
|
"get": {
|
|
"operationId": "getChat",
|
|
"summary": "Получить доступный чат",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Chat"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "chat_id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/chats/{chat_id}/messages": {
|
|
"post": {
|
|
"operationId": "createMessage",
|
|
"summary": "Отправить сообщение",
|
|
"responses": {
|
|
"201": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Message"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "chat_id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CreateMessage"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"get": {
|
|
"operationId": "listMessages",
|
|
"summary": "Сообщения по (created_at, id) по возрастанию",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/MessagePage"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Объект отсутствует или недоступен",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Конфликт",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "chat_id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 50
|
|
}
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/auth/sessions": {
|
|
"post": {
|
|
"operationId": "createSession",
|
|
"summary": "Вход: Basic username:password; выдаёт сессию",
|
|
"responses": {
|
|
"201": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Session"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Неверный запрос",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"basicAuth": []
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/auth/sessions/current": {
|
|
"delete": {
|
|
"operationId": "revokeSession",
|
|
"summary": "Отозвать текущую сессию",
|
|
"responses": {
|
|
"204": {
|
|
"description": "Успех",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Нет действительной аутентификации",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"WWW-Authenticate": {
|
|
"description": "Basic realm=\"messenger\", charset=\"UTF-8\" для входа; Bearer realm=\"messenger\" для защищённого API lab2+.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Ограничение частоты запросов",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"Retry-After": {
|
|
"description": "Положительное число секунд.",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Зависимость недоступна",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Неожиданная ошибка без внутренних деталей",
|
|
"headers": {
|
|
"X-Request-Id": {
|
|
"description": "Непустой идентификатор запроса; обязателен во всех ответах.",
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"securitySchemes": {
|
|
"basicAuth": {
|
|
"type": "http",
|
|
"scheme": "basic"
|
|
},
|
|
"bearerAuth": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "opaque session token"
|
|
}
|
|
},
|
|
"schemas": {
|
|
"Error": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "object",
|
|
"properties": {
|
|
"code": {
|
|
"type": "string",
|
|
"enum": [
|
|
"invalid_request",
|
|
"unauthorized",
|
|
"not_found",
|
|
"conflict",
|
|
"payload_too_large",
|
|
"unsupported_media_type",
|
|
"rate_limited",
|
|
"unavailable",
|
|
"internal_error"
|
|
]
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"request_id": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
},
|
|
"required": [
|
|
"code",
|
|
"message",
|
|
"request_id"
|
|
],
|
|
"additionalProperties": false
|
|
}
|
|
},
|
|
"required": [
|
|
"error"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"error": {
|
|
"code": "not_found",
|
|
"message": "Объект не найден",
|
|
"request_id": "example-request-id"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"Health": {
|
|
"type": "object",
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"ok"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"status"
|
|
],
|
|
"additionalProperties": false
|
|
},
|
|
"User": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"username": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9_]{3,32}$"
|
|
},
|
|
"display_name": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 100
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"username",
|
|
"display_name",
|
|
"created_at"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"id": "11111111-1111-4111-8111-111111111111",
|
|
"username": "alice",
|
|
"display_name": "Алиса",
|
|
"created_at": "2026-09-01T12:00:00Z"
|
|
}
|
|
]
|
|
},
|
|
"CreateUser": {
|
|
"type": "object",
|
|
"properties": {
|
|
"username": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9_]{3,32}$"
|
|
},
|
|
"display_name": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 100
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"minLength": 12,
|
|
"maxLength": 128,
|
|
"writeOnly": true
|
|
}
|
|
},
|
|
"required": [
|
|
"username",
|
|
"display_name",
|
|
"password"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"username": "alice",
|
|
"display_name": "Алиса",
|
|
"password": "Example-only-not-a-real-secret-123"
|
|
}
|
|
]
|
|
},
|
|
"Chat": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 100
|
|
},
|
|
"member_ids": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"minItems": 1,
|
|
"maxItems": 100,
|
|
"uniqueItems": true
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"title",
|
|
"member_ids",
|
|
"created_at"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"title": "Проект по ВНП",
|
|
"member_ids": [
|
|
"11111111-1111-4111-8111-111111111111",
|
|
"22222222-2222-4222-8222-222222222222"
|
|
],
|
|
"id": "33333333-3333-4333-8333-333333333333",
|
|
"created_at": "2026-09-01T12:00:00Z"
|
|
}
|
|
]
|
|
},
|
|
"CreateChat": {
|
|
"type": "object",
|
|
"properties": {
|
|
"title": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 100
|
|
},
|
|
"member_ids": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"minItems": 1,
|
|
"maxItems": 100,
|
|
"uniqueItems": true
|
|
}
|
|
},
|
|
"required": [
|
|
"title",
|
|
"member_ids"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"title": "Проект по ВНП",
|
|
"member_ids": [
|
|
"11111111-1111-4111-8111-111111111111",
|
|
"22222222-2222-4222-8222-222222222222"
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"Message": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"chat_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"sender_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"text": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 4000
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"chat_id",
|
|
"sender_id",
|
|
"text",
|
|
"created_at"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"id": "44444444-4444-4444-8444-444444444444",
|
|
"chat_id": "33333333-3333-4333-8333-333333333333",
|
|
"sender_id": "11111111-1111-4111-8111-111111111111",
|
|
"text": "Привет, Боб!",
|
|
"created_at": "2026-09-01T12:00:00Z"
|
|
}
|
|
]
|
|
},
|
|
"CreateMessage": {
|
|
"type": "object",
|
|
"properties": {
|
|
"text": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 4000
|
|
}
|
|
},
|
|
"required": [
|
|
"text"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"text": "Привет, Боб!"
|
|
}
|
|
]
|
|
},
|
|
"ChatPage": {
|
|
"type": "object",
|
|
"properties": {
|
|
"items": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Chat"
|
|
}
|
|
},
|
|
"next_cursor": {
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"items",
|
|
"next_cursor"
|
|
],
|
|
"additionalProperties": false
|
|
},
|
|
"MessagePage": {
|
|
"type": "object",
|
|
"properties": {
|
|
"items": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Message"
|
|
}
|
|
},
|
|
"next_cursor": {
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"items",
|
|
"next_cursor"
|
|
],
|
|
"additionalProperties": false,
|
|
"examples": [
|
|
{
|
|
"items": [
|
|
{
|
|
"id": "44444444-4444-4444-8444-444444444444",
|
|
"chat_id": "33333333-3333-4333-8333-333333333333",
|
|
"sender_id": "11111111-1111-4111-8111-111111111111",
|
|
"text": "Привет, Боб!",
|
|
"created_at": "2026-09-01T12:00:00Z"
|
|
}
|
|
],
|
|
"next_cursor": null
|
|
}
|
|
]
|
|
},
|
|
"Session": {
|
|
"type": "object",
|
|
"properties": {
|
|
"token": {
|
|
"type": "string",
|
|
"minLength": 32
|
|
},
|
|
"token_type": {
|
|
"type": "string",
|
|
"const": "Bearer"
|
|
},
|
|
"expires_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"user": {
|
|
"$ref": "#/components/schemas/User"
|
|
}
|
|
},
|
|
"required": [
|
|
"token",
|
|
"token_type",
|
|
"expires_at",
|
|
"user"
|
|
],
|
|
"additionalProperties": false
|
|
}
|
|
}
|
|
}
|
|
}
|