Skip to content

Commit e86932d

Browse files
authored
SW-7695 Add endpoint to edit observation details (#3647)
`PATCH /api/v1/tracking/observations/{observationId}/plots/{plotId}` updates information about completed observations of monitoring plots. It will eventually replace the existing `PUT` endpoint. Initially, it only supports updating the description and soil assessment properties of biomass observations, but it's structured to support editing additional kinds of details in future changes. The request payload uses `PATCH` semantics, where omitting a property means leaving the current value in place.
1 parent 4f2a96f commit e86932d

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.terraformation.backend.tracking.api
2+
3+
import com.fasterxml.jackson.annotation.JsonTypeInfo
4+
import com.fasterxml.jackson.annotation.JsonTypeName
5+
import com.terraformation.backend.tracking.model.EditableBiomassDetailsModel
6+
import com.terraformation.backend.util.patchNullable
7+
import java.util.Optional
8+
9+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
10+
sealed interface ObservationUpdateOperationPayload
11+
12+
@JsonTypeName("Biomass")
13+
data class BiomassUpdateOperationPayload(
14+
val description: Optional<String?>?,
15+
val soilAssessment: String?,
16+
) : ObservationUpdateOperationPayload {
17+
fun applyTo(model: EditableBiomassDetailsModel): EditableBiomassDetailsModel {
18+
return model.copy(
19+
description = description.patchNullable(model.description),
20+
soilAssessment = soilAssessment ?: model.soilAssessment,
21+
)
22+
}
23+
}

src/main/kotlin/com/terraformation/backend/tracking/api/ObservationsController.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import org.springframework.http.MediaType
7979
import org.springframework.http.ResponseEntity
8080
import org.springframework.web.bind.annotation.DeleteMapping
8181
import org.springframework.web.bind.annotation.GetMapping
82+
import org.springframework.web.bind.annotation.PatchMapping
8283
import org.springframework.web.bind.annotation.PathVariable
8384
import org.springframework.web.bind.annotation.PostMapping
8485
import org.springframework.web.bind.annotation.PutMapping
@@ -322,6 +323,30 @@ class ObservationsController(
322323
return GetOneAssignedPlotResponsePayload(AssignedPlotPayload(details))
323324
}
324325

326+
@ApiResponse404(
327+
"The plot or observation can't be found, or the plot isn't part of the observation."
328+
)
329+
@ApiResponse409("The plot's observation has not been completed yet.")
330+
@ApiResponseSimpleSuccess
331+
@Operation(summary = "Updates information about a completed plot in an observation.")
332+
@PatchMapping("/{observationId}/plots/{plotId}")
333+
fun updateCompletedObservationPlot(
334+
@PathVariable observationId: ObservationId,
335+
@PathVariable plotId: MonitoringPlotId,
336+
@RequestBody payload: UpdateObservationRequestPayload,
337+
): SimpleSuccessResponsePayload {
338+
observationService.updateCompletedPlot(observationId, plotId) {
339+
payload.updates.forEach { element ->
340+
when (element) {
341+
is BiomassUpdateOperationPayload ->
342+
observationStore.updateBiomassDetails(observationId, plotId, element::applyTo)
343+
}
344+
}
345+
}
346+
347+
return SimpleSuccessResponsePayload()
348+
}
349+
325350
@Operation(summary = "Updates information about the observation of a plot.")
326351
@PutMapping("/{observationId}/plots/{plotId}")
327352
fun updatePlotObservation(
@@ -1035,6 +1060,18 @@ data class UpdatePlotObservationRequestPayload(
10351060
val coordinates: List<ObservationMonitoringPlotCoordinatesPayload>,
10361061
)
10371062

1063+
data class UpdateObservationRequestPayload(
1064+
@ArraySchema(
1065+
arraySchema =
1066+
Schema(
1067+
description =
1068+
"List of changes to make to different parts of the observation. " +
1069+
"Changes are all-or-nothing; if any of them fails, none of them is applied."
1070+
)
1071+
)
1072+
val updates: List<ObservationUpdateOperationPayload>,
1073+
)
1074+
10381075
data class UpdatePlotPhotoRequestPayload(
10391076
val caption: String?,
10401077
) {

0 commit comments

Comments
 (0)