SolutionCatalogController.java
package com.taxonomy.portfolio.controller;
import com.taxonomy.portfolio.dto.PortfolioDtos.CreateSolutionRequest;
import com.taxonomy.portfolio.dto.PortfolioDtos.SolutionView;
import com.taxonomy.portfolio.dto.PortfolioDtos.UpdateSolutionRequest;
import com.taxonomy.portfolio.dto.PortfolioDtos.UpsertTaxonomyCoverageRequest;
import com.taxonomy.portfolio.service.SolutionPortfolioService;
import com.taxonomy.workspace.service.WorkspaceContext;
import com.taxonomy.workspace.service.WorkspaceResolver;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URI;
import java.util.List;
@RestController
@RequestMapping("/api/solutions")
@Tag(name = "Solution Catalogue")
public class SolutionCatalogController {
private final SolutionPortfolioService solutionService;
private final WorkspaceResolver workspaceResolver;
public SolutionCatalogController(SolutionPortfolioService solutionService,
WorkspaceResolver workspaceResolver) {
this.solutionService = solutionService;
this.workspaceResolver = workspaceResolver;
}
@PostMapping
@Operation(summary = "Create a reusable workspace solution")
public ResponseEntity<SolutionView> create(@RequestBody CreateSolutionRequest request) {
RequestScope scope = scope();
SolutionView solution = solutionService.createSolution(
request, scope.username(), scope.context());
return ResponseEntity.created(URI.create("/api/solutions/" + solution.id())).body(solution);
}
@GetMapping
@Operation(summary = "List reusable solutions in the current workspace")
public List<SolutionView> list() {
RequestScope scope = scope();
return solutionService.listSolutions(scope.username(), scope.context());
}
@GetMapping("/{solutionId}")
@Operation(summary = "Read one reusable solution")
public SolutionView get(@PathVariable Long solutionId) {
RequestScope scope = scope();
return solutionService.getSolution(solutionId, scope.username(), scope.context());
}
@PatchMapping("/{solutionId}")
@Operation(summary = "Update reusable solution metadata")
public SolutionView update(@PathVariable Long solutionId,
@RequestBody UpdateSolutionRequest request) {
RequestScope scope = scope();
return solutionService.updateSolution(
solutionId, request, scope.username(), scope.context());
}
@PostMapping("/{solutionId}/taxonomy-coverage")
@Operation(summary = "Create or update evidence-backed taxonomy coverage")
public SolutionView upsertCoverage(@PathVariable Long solutionId,
@RequestBody UpsertTaxonomyCoverageRequest request) {
RequestScope scope = scope();
return solutionService.upsertTaxonomyCoverage(
solutionId, request, scope.username(), scope.context());
}
private RequestScope scope() {
return new RequestScope(
workspaceResolver.resolveCurrentUsername(),
workspaceResolver.resolveCurrentContext());
}
private record RequestScope(String username, WorkspaceContext context) {
}
}