feat(slots-service): #50 M3 — держатели BUSY-слотов в request-cover

reqCover(all=true) обогащает занятые (BUSY) слоты держателями: какие заявки
блокируют слот, с именем и важностью (обзор конфликтов при ручной броне).

- SlotHolderDTO (requestId + опц. name/importance), поле holders в SlotDTO
  (null для AVAILABLE/BOOKED и прочих путей — обратно совместимо).
- TestSatelliteImpl: для BUSY-слота собирает держателей по пересечению
  сдвинутых на cycle интервалов активных броней (та же логика, что band, с mmi),
  distinct по requestId (множественный держатель).
- EarthService.requestHolders: батч-резолв name/importance заявок; деградация
  через runCatching → emptyMap (request-service недоступен → только id, без падения).
- SlotService.enrichHolders: один батч-запрос на обзор, slot.copy(holders=...).
- SlotDTO переведён в data class (copy вместо ручного перечисления полей).
- Тест: BUSY несёт держателей, BOOKED/AVAILABLE — нет.
This commit is contained in:
Дмитрий Соловьев
2026-06-17 09:05:52 +03:00
parent 5869994690
commit bd35280691
7 changed files with 149 additions and 5 deletions
@@ -3,7 +3,7 @@ package space.nstart.pcp.pcp_types_lib.dto.requests.slots
import space.nstart.pcp.pcp_types_lib.dto.ballistics.RevolutionSign
import java.time.LocalDateTime
class SlotDTO(
data class SlotDTO(
val cycle : Long = 0,
val satelliteId : Long = 0,
val tn : LocalDateTime,
@@ -16,4 +16,7 @@ class SlotDTO(
val state : SlotStatus = SlotStatus.AVAILABLE,
val latitude : Double = 0.0,
val longitude : Double = 0.0,
// Держатели слота — заполняются только для BUSY-слотов в обзорном request-cover (all=true).
// null/пусто для AVAILABLE/BOOKED и для всех прочих путей (обратно совместимо).
val holders : List<SlotHolderDTO>? = null,
)
@@ -0,0 +1,12 @@
package space.nstart.pcp.pcp_types_lib.dto.requests.slots
/**
* Держатель занятого (BUSY) слота — заявка, чья бронь блокирует слот на этом проходе КА.
* Заполняется только в обзорном ответе request-cover (all=true); name/importance могут быть null,
* если request-service недоступен (деградация — бейдж показывает только идентификатор заявки).
*/
data class SlotHolderDTO(
val requestId: String,
val name: String? = null,
val importance: Double? = null,
)