Тема оформления
Эндпоинты датасетов и истории расчётов
В данном разделе представлена Swagger-спецификация микросервисов управления конфигурациями агрегатов (HeatBalance.DatasetService) и протоколирования истории вычислений (HeatBalance.RunService).
1. Спецификация HeatBalance.DatasetService
Базовый путь: /api/v1/datasets. Все методы требуют авторизации Bearer <JWT-токен>. Доступ к объектам строго изолирован по OwnerId текущего пользователя (администраторы имеют доступ ко всем датасетам).
1.1. Получение списка датасетов (GET /api/v1/datasets)
Возвращает коллекцию сохраненных технологических карт текущего пользователя, отсортированных по дате обновления.
Запрос:
http
GET /api/v1/datasets HTTP/1.1
Host: heatbalance.ru
Authorization: Bearer <JWT_TOKEN>Ответ (200 OK):
json
[
{
"id": "8c7b6a5e-4d3c-2b1a-0f9e-8d7c6b5a4a3b",
"ownerId": "b2f65a12-88d3-4f91-9c3a-8b1e0f3a6b5c",
"name": "Камерная печь №1 (Огнеупорный цех)",
"calculationType": 2,
"comment": "Базовый технологический режим обжига шамотного кирпича",
"schemaVersion": 1,
"inputJson": "{\"dryMaterialMass\": 10000, \"initialMoisture\": 8.0, ...}",
"createdAt": "2026-08-10T09:15:00Z",
"updatedAt": "2026-09-15T14:20:00Z"
}
]1.2. Получение датасета по идентификатору (GET /api/v1/datasets/{id})
Метод реализует шаблон кэширования Cache-Aside с использованием Redis 7.0:
- Проверяется наличие ключа
dataset:{id}в Redis; - При попадании в кэш (Cache Hit) данные возвращаются за мс;
- При промахе (Cache Miss) данные считываются из PostgreSQL, записываются в Redis с TTL 10 минут и возвращаются клиенту.
Запрос:
http
GET /api/v1/datasets/8c7b6a5e-4d3c-2b1a-0f9e-8d7c6b5a4a3b HTTP/1.1
Host: heatbalance.ru
Authorization: Bearer <JWT_TOKEN>Ответ (200 OK):
json
{
"id": "8c7b6a5e-4d3c-2b1a-0f9e-8d7c6b5a4a3b",
"ownerId": "b2f65a12-88d3-4f91-9c3a-8b1e0f3a6b5c",
"name": "Камерная печь №1 (Огнеупорный цех)",
"calculationType": 2,
"comment": "Базовый технологический режим обжига шамотного кирпича",
"schemaVersion": 1,
"inputJson": "{\n \"dryMaterialMass\": 10000,\n \"initialMoisture\": 8.0,\n \"finalMoisture\": 2.0,\n \"airFlowCoefficient\": 1.15,\n \"airTemperature\": 20.0,\n \"recirculateTemp\": 230.0\n}",
"createdAt": "2026-08-10T09:15:00Z",
"updatedAt": "2026-09-15T14:20:00Z"
}1.3. Создание нового датасета (POST /api/v1/datasets)
Создаёт новую запись в таблице InputDataSets.
Спецификация полей CreateDatasetRequest:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
name | string | Да | Наименование агрегата / варианта расчёта (до 200 символов) |
calculationType | integer | Да | 1: ConveyorKiln, 2: ChamberKiln, 3: ElectricKiln, 4: DrumDryer |
comment | string | Нет | Произвольное технологическое описание (до 4000 символов) |
inputJson | string | Да | Полный сериализованный JSON входных физических параметров |
Пример запроса:
http
POST /api/v1/datasets HTTP/1.1
Host: heatbalance.ru
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"name": "Сушильный барабан №3 — Опытный режим",
"calculationType": 4,
"comment": "Испытания новой партии гранулированного шлака",
"inputJson": "{\"dryMaterialMass\": 3000, \"initialMoisture\": 18.0, \"finalMoisture\": 1.5, \"dryingAgentTempIn\": 650}"
}Ответ (201 Created):
- Заголовок
Location:/api/v1/datasets/3fa85f64-5717-4562-b3fc-2c963f66afa6 - Тело ответа: полный объект
DatasetDto.
1.4. Обновление датасета (PUT /api/v1/datasets/{id})
Обновляет существующий датасет, сбрасывает соответствующий ключ в кэше Redis и публикует событие DatasetUpdatedEvent в RabbitMQ.
http
PUT /api/v1/datasets/3fa85f64-5717-4562-b3fc-2c963f66afa6 HTTP/1.1
Host: heatbalance.ru
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"name": "Сушильный барабан №3 — Скорректированный",
"comment": "Снижена температура агента до 600 °C",
"inputJson": "{\"dryMaterialMass\": 3000, \"initialMoisture\": 18.0, \"finalMoisture\": 1.5, \"dryingAgentTempIn\": 600}"
}1.5. Удаление датасета (DELETE /api/v1/datasets/{id})
Удаляет запись из БД, очищает кэш Redis и рассылает событие DatasetDeletedEvent для каскадной очистки зависимых сущностей в IoTService. Возвращает 204 No Content.
2. Спецификация HeatBalance.RunService
Базовый путь: /api/v1/runs. Сервис отвечает за хранение и аудит выполненных технологических расчётов.
2.1. Получение истории расчетов (GET /api/v1/runs)
Query-параметры:
limit(integer, по умолчанию50): максимальное количество возвращаемых записей;offset(integer, по умолчанию0): смещение выборки для пагинации;datasetId(Guid, опционально): фильтрация истории по конкретному датасету.
Ответ (200 OK):
json
[
{
"id": "e4b2c1a0-9f8e-7d6c-5b4a-3a2b1c0d9e8f",
"inputDataSetId": "8c7b6a5e-4d3c-2b1a-0f9e-8d7c6b5a4a3b",
"executedAt": "2026-09-18T16:30:00Z",
"resultJson": "{\"efficiency\": 0.6838, \"totalInputKJPerHour\": 1485200.0, ...}",
"notes": "Штатный автоматический расчёт",
"dataset": {
"name": "Камерная печь №1 (Огнеупорный цех)",
"calculationType": 2
}
}
]2.2. Запуск и протоколирование расчёта (POST /api/v1/runs)
Инициирует сквозной расчёт на основе указанного датасета:
- Загружает параметры
inputJsonизDatasetService; - Вызывает соответствующий расчётный микросервис;
- Сохраняет результат в таблице
CalculationRuns.
Запрос:
http
POST /api/v1/runs HTTP/1.1
Host: heatbalance.ru
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"inputDataSetId": "8c7b6a5e-4d3c-2b1a-0f9e-8d7c6b5a4a3b"
}Ответ (201 Created):
json
{
"runId": "e4b2c1a0-9f8e-7d6c-5b4a-3a2b1c0d9e8f",
"resultJson": "{\"unitType\": 2, \"efficiency\": 0.6838, \"totalInputKJPerHour\": 1485200.0, ...}"
}2.3. Прямое межсервисное сохранение (POST /api/v1/runs/direct-save)
Служебный внутренний эндпоинт, используемый консьюмером TelemetryReceivedConsumer и контроллером групп DeviceGroupsController для гарантированного сохранения выполненных вычислений без повторного обращения к расчетным модулям.