Files
diploma-server/docs/rest-api.md
Evgenii Saenko ea390b1533 Add docker
2025-12-17 11:52:18 +03:00

14 KiB
Raw Blame History

REST API (Swagger-Style)

Общая информация

  • Базовый URL: http://0.0.0.0:8080/api/v1
  • Форматы: все конечные точки принимают и возвращают application/json, если не указан иной Content-Type.
  • Часовой формат: даты/время сериализуются в ISO_LOCAL_DATE_TIME, например 2024-05-12T13:45:00.
  • JWT-аутентификация: приватные маршруты располагаются под /api/v1/admin/** и требуют заголовок Authorization: Bearer <token> из POST /admin/login.
  • Ошибки: при валидационных/авторизационных ошибках сервер возвращает код 4xx с телом {"error": "описание"}.

Базовые схемы

Схема Описание
Page Обёртка пагинации: items (список сущностей T), total (общее количество), limit (число элементов на странице), offset (смещение).
ServiceCategoryDTO { id: number, name: string, slug: string }.
ServiceDTO { id, title, slug, description, priceFrom: number|null, imageUrl: string|null, status: "PUBLISHED"|"DRAFT"|"ARCHIVED", category: ServiceCategoryDTO|null, createdAt, updatedAt }.
NewsDTO { id, title, slug, summary, content, status: "draft"|"published"|"archived", imageUrl: string|null, publishedAt: string|null }.
LeadDTO { id, fullName, email, phone: string|null, createdAt }.
AdminDTO { id, username, createdAt }.

Администраторы и аутентификация

Метод Путь Требуется JWT Описание
POST /admin/login Нет Получение JWT токена.
GET /admin/password_hash Нет Вспомогательный эндпойнт для генерации bcrypt-хэша.
GET /admin Да Получить профиль текущего администратора.
POST /admin Да Создать нового администратора.
PUT /admin/{id}/password Да Сменить пароль администратора.
DELETE /admin/{id} Да Удалить администратора.

POST /api/v1/admin/login

Тело запроса

Поле Тип Обязательно Примечание
username string да Мин. 3 символа ([A-Za-z0-9_.-]).
password string да Мин. 8 символов.

Ответ 200

Поле Тип Примечание
id number Идентификатор администратора.
username string Введённое имя.
token string JWT access token.
tokenType string Всегда Bearer.
expiresInMinutes number Время жизни токена (минуты).

Пример:

{
  "id": 1,
  "username": "admin",
  "token": "eyJhbGciOi...",
  "tokenType": "Bearer",
  "expiresInMinutes": 60
}

GET /api/v1/admin/password_hash

Query-параметры

Параметр Тип Обязательно Описание
password string нет Исходный пароль. По умолчанию admin123.

Ответ 200: { "pass": "<bcrypt-hash>" }.

GET /api/v1/admin

Возвращает AdminDTO текущего пользователя по subject токена.

POST /api/v1/admin

Тело запроса AdminRegisterRequest:

Поле Тип Обязательно Примечание
username string да Уникальное имя (регулярное выражение как при логине).
password string да Мин. 8 символов.

Ответ 201 AdminRegisterResponse:

Поле Тип
id number
username string

PUT /api/v1/admin/{id}/password

Параметры пути: id numeric ID.

Тело запроса ChangePasswordRequest:

Поле Тип Обязательно Примечание
currentPassword string да Текущий пароль (проверяется через bcrypt).
newPassword string да Новый пароль, минимум 8 символов.

Ответ 200: { "updated": true }.

DELETE /api/v1/admin/{id}

Удаляет администратора. Ответ 200 OK: { "deleted": true }.


Лиды (заявки)

Метод Путь JWT Описание
POST /leads Нет Оставить заявку.
GET /admin/leads Да Список лидов с фильтром.
GET /admin/leads/{id} Да Получить лид по ID.
DELETE /admin/leads/{id} Да Удалить лид.

POST /api/v1/leads

Тело запроса LeadCreateRequest:

Поле Тип Обязательно Примечание
fullName string да Имя клиента.
email string да Проверяется регуляркой ^[\\w.+-]+@[\\w.-]+\\.[A-Za-z]{2,}$.
phone string нет Любой формат, сохраняется как строка.

Ответ 201: { "id": 42 }.

GET /api/v1/admin/leads

Query-параметры

Имя Тип По умолчанию Описание
limit integer 50 Размер страницы.
page integer 1 Должна быть ≥ 1, иначе 400.
q string null Поиск по fullName, email, phone.

Ответ 200: Page<LeadDTO>. Пример элемента: { "id": 7, "fullName": "Иван Иванов", "email": "ivan@example.com", "phone": "+79001234567", "createdAt": "2024-05-05T10:34:00" }.

GET /api/v1/admin/leads/{id}

Параметр id (long). Ответ LeadDTO.

DELETE /api/v1/admin/leads/{id}

Ответ { "deleted": true }.


Новости

Метод Путь JWT Описание
GET /news Нет Пагинированный список опубликованных новостей.
GET /news/{slug} Нет Получение новости по slug.
GET /admin/news Да Список всех новостей.
POST /admin/news Да Создать новость.
PUT /admin/news/{slug} Да Обновить новость.
POST /admin/news/{slug}/publish Да Публикация новости.
DELETE /admin/news/{slug} Да Удалить новость.

GET /api/v1/news

Query-параметры: limit (default 20), page (default 1, ≥1). Ответ: Page<NewsDTO>, где items отсортированы по publishedAt у опубликованных записей.

GET /api/v1/news/{slug}

Возвращает NewsDTO опубликованной новости (если slug неактивен — 404).

GET /api/v1/admin/news

Query-параметры: limit (50), page (1, ≥1). Ответ: Page<NewsDTO> (включая черновики).

POST /api/v1/admin/news

Тело запроса NewsCreate:

Поле Тип Обязательно Примечание
title string да Заголовок.
slug string да Уникальный slug (валидация на уровне базы).
summary string да Краткое описание.
content string да Полный текст (HTML/Markdown).
status string нет draft (по умолчанию) | published | archived.
imageUrl string нет Ссылка на обложку.

Ответ: { "id": <number> }.

PUT /api/v1/admin/news/{slug}

Тело запроса NewsUpdateRequest (все поля опциональны, как в NewsCreate). Ответ { "updated": true }.

POST /api/v1/admin/news/{slug}/publish

Без тела. Устанавливает status = "published", publishedAt = now. Ответ { "published": true }.

DELETE /api/v1/admin/news/{slug}

Ответ { "deleted": true }.


Категории услуг

Метод Путь JWT Описание
GET /service-categories Нет Публичный список категорий.
GET /service-categories/{slug} Нет Получить категорию по slug.
GET /admin/service-categories Да Пагинация категорий.
POST /admin/service-categories Да Создать категорию.
PUT /admin/service-categories/{id} Да Обновить категорию.
DELETE /admin/service-categories/{id} Да Удалить категорию.

GET /api/v1/service-categories

Возвращает массив ServiceCategoryDTO.

GET /api/v1/service-categories/{slug}

Ответ ServiceCategoryDTO.

GET /api/v1/admin/service-categories

Query-параметры: limit (100), offset (0). Ответ: список ServiceCategoryDTO (без обёртки).

POST /api/v1/admin/service-categories

Тело запроса CategoryCreateRequest (name, slug обязательные). Ответ { "id": <number> }.

PUT /api/v1/admin/service-categories/{id}

Тело CategoryUpdateRequest (оба поля опциональны). Ответ { "updated": true }.

DELETE /api/v1/admin/service-categories/{id}

Ответ { "deleted": true }.


Услуги

Метод Путь JWT Описание
GET /services Нет Список опубликованных услуг с фильтрами.
GET /services/{slug} Нет Одна услуга по slug.
GET /admin/services Да Список всех услуг.
POST /admin/services Да Создать услугу.
PUT /admin/services/{id} Да Обновить услугу.
PUT /admin/services/{id}/status Да Изменить статус.
DELETE /admin/services/{id} Да Удалить услугу.

GET /api/v1/services

Query-параметры

Имя Тип По умолчанию Описание
limit integer 20 Размер страницы.
page integer 1 ≥ 1.
q string null Поиск по title и description (case-insensitive).
category string null slug категории.
minPrice number null Минимальная цена (decimal).
maxPrice number null Максимальная цена (decimal).

Ответ: Page<ServiceDTO>. Пример элемента:

{
  "id": 10,
  "title": "Разработка мобильного приложения",
  "slug": "mobile-dev",
  "description": "Полный цикл разработки",
  "priceFrom": 150000.0,
  "imageUrl": "https://cdn.example/app.jpg",
  "status": "PUBLISHED",
  "category": { "id": 2, "name": "Разработка", "slug": "development" },
  "createdAt": "2024-04-01T09:15:00",
  "updatedAt": "2024-05-05T12:00:00"
}

GET /api/v1/services/{slug}

Ответ ServiceDTO (включая category). Ошибка 404, если slug не найден или услуга скрыта.

GET /api/v1/admin/services

Query-параметры

Имя Тип По умолчанию Описание
limit integer 50 Размер страницы.
page integer 1 ≥ 1.
q string null Фильтр по названию/описанию.
status string null PUBLISHED | DRAFT | ARCHIVED.

Ответ: Page<ServiceDTO> (включая черновики).

POST /api/v1/admin/services

Тело запроса ServiceCreateRequest:

Поле Тип Обязательно Примечание
title string да Название услуги.
slug string да Уникальный slug (^[a-z0-9-]{3,}$).
description string да Детальное описание.
priceFrom string нет Десятичное число, например "1499.99".
imageUrl string нет URL изображения.
status string нет По умолчанию PUBLISHED.
categoryId number нет ID существующей категории.

Ответ 201: { "id": <number> }.

PUT /api/v1/admin/services/{id}

Тело ServiceUpdateRequest (все поля опциональны, формат как в ServiceCreateRequest). Ответ { "updated": true }.

PUT /api/v1/admin/services/{id}/status

Тело запроса StatusRequest с полем status (PUBLISHED|DRAFT|ARCHIVED). Ответ { "updated": true }.

DELETE /api/v1/admin/services/{id}

Ответ { "deleted": true }.


Пример структуры Page

{
  "items": [ /* сущности */ ],
  "total": 125,
  "limit": 20,
  "offset": 0
}