pcp-tgu: «снять с учёта» терминально-негативный план (dismissed_at)
Оператор деактивирует отменённый/неудавшийся план, чтобы он не считался
проблемой и не красил индикатор КА. Косметико-статистический флаг
dismissed_at: статус плана и состояние цепочки не трогает, обратим.
- planned_plan.dismissed_at (V14) + поле в сущности и PlanResponse;
- DismissPlanUseCase.dismiss/restore с гардом на терминально-негативные
статусы (REJECTED, START_AMBIGUOUS, LAYIN_FAILED, NOT_ACCEPTED,
SUPERSEDED), идемпотентно; эндпоинты POST /api/plans/{id}/dismiss|restore;
- BFF (pcp-ui-service): проброс dismissedAt в TguPlanResponse и
/api/tgu-planning/plans/{id}/dismiss|restore;
- тест DismissPlanUseCaseTest; починен предсуществующий TguPlanningServiceTest
(мок-JSON не отдавал projected — WebClient падал на null→boolean).
This commit is contained in:
+8
@@ -47,6 +47,14 @@ class TguPlanningRestController(
|
||||
@RequestParam(required = false) reason: String?
|
||||
) = tguPlanningService.sendDecision(planId, decision, reason)
|
||||
|
||||
/** «Снять с учёта» терминально-негативный план (чтобы не красил индикатор КА). */
|
||||
@PostMapping("/plans/{planId}/dismiss")
|
||||
fun dismissPlan(@PathVariable planId: UUID) = tguPlanningService.dismissPlan(planId)
|
||||
|
||||
/** «Вернуть на учёт» план. */
|
||||
@PostMapping("/plans/{planId}/restore")
|
||||
fun restorePlan(@PathVariable planId: UUID) = tguPlanningService.restorePlan(planId)
|
||||
|
||||
/** ТЕСТ: подтвердить закладку плана (AWAITING_LAYIN → LAID_IN). */
|
||||
@PostMapping("/plans/{planId}/confirm-layin")
|
||||
fun confirmLayin(
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ data class TguPlanResponse(
|
||||
/** Предшественник в цепочке (`null` — старт без предыстории). Проксируется из pcp-tgu-service. */
|
||||
val basePlanId: UUID? = null,
|
||||
/** `true` — проекция будущего (не persisted). Проксируется из pcp-tgu-service. */
|
||||
val projected: Boolean = false
|
||||
val projected: Boolean = false,
|
||||
/** Время «снятия с учёта» (`null` — план на учёте). Проксируется из pcp-tgu-service. */
|
||||
val dismissedAt: LocalDateTime? = null
|
||||
)
|
||||
|
||||
enum class TguPlanDecision {
|
||||
|
||||
+22
@@ -87,6 +87,28 @@ class TguPlanningService(webClientBuilderProvider: ObjectProvider<WebClient.Buil
|
||||
throw error
|
||||
}
|
||||
|
||||
/** «Снять с учёта» терминально-негативный план (pcp-tgu-service, реальный API, не тест-контроллер). */
|
||||
fun dismissPlan(planId: UUID) {
|
||||
webClientBuilder.build()
|
||||
.post()
|
||||
.uri(buildUri("/api/plans/{planId}/dismiss") { builder -> builder.buildAndExpand(planId) })
|
||||
.retrieve()
|
||||
.onStatus({ status -> status.isError }, ::mapReadError)
|
||||
.bodyToMono(Void::class.java)
|
||||
.block()
|
||||
}
|
||||
|
||||
/** «Вернуть на учёт» план (pcp-tgu-service). */
|
||||
fun restorePlan(planId: UUID) {
|
||||
webClientBuilder.build()
|
||||
.post()
|
||||
.uri(buildUri("/api/plans/{planId}/restore") { builder -> builder.buildAndExpand(planId) })
|
||||
.retrieve()
|
||||
.onStatus({ status -> status.isError }, ::mapReadError)
|
||||
.bodyToMono(Void::class.java)
|
||||
.block()
|
||||
}
|
||||
|
||||
fun confirmLayin(planId: UUID, reason: String?) {
|
||||
runCatching {
|
||||
webClientBuilder.build()
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ class TguPlanningServiceTest {
|
||||
exchange.requestURI.path == "/api/plans" || exchange.requestURI.path == "/api/plans/56756" -> respond(
|
||||
exchange,
|
||||
200,
|
||||
"""[{"planId":"6d0941e4-61d6-4f96-8fa8-90ba11db121e","spacecraftId":"56756","startTime":"2026-05-29T10:00:00Z","endTime":"2026-05-29T10:15:00Z","kppId":"KPP-1","status":"WAITING_DECISION"}]"""
|
||||
"""[{"planId":"6d0941e4-61d6-4f96-8fa8-90ba11db121e","spacecraftId":"56756","startTime":"2026-05-29T10:00:00Z","endTime":"2026-05-29T10:15:00Z","kppId":"KPP-1","status":"WAITING_DECISION","basePlanId":null,"projected":false,"dismissedAt":null}]"""
|
||||
)
|
||||
exchange.requestURI.path.startsWith("/test/tgu/plans/") -> respond(
|
||||
exchange,
|
||||
|
||||
Reference in New Issue
Block a user