ProjectSolutionController.java
package com.taxonomy.portfolio.controller;
import com.taxonomy.portfolio.dto.PortfolioDtos.AddProjectSolutionRequest;
import com.taxonomy.portfolio.dto.PortfolioDtos.LinkRequirementSolutionRequest;
import com.taxonomy.portfolio.dto.PortfolioDtos.ProjectSolutionView;
import com.taxonomy.portfolio.dto.PortfolioDtos.UpdateProjectSolutionRequest;
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.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.util.List;
@RestController
@RequestMapping("/api/projects/{projectId}/solutions")
@Tag(name = "Project Solutions")
public class ProjectSolutionController {
private final SolutionPortfolioService solutionService;
private final WorkspaceResolver workspaceResolver;
public ProjectSolutionController(SolutionPortfolioService solutionService,
WorkspaceResolver workspaceResolver) {
this.solutionService = solutionService;
this.workspaceResolver = workspaceResolver;
}
@PostMapping
@Operation(summary = "Add or update a reusable solution in a project")
public ProjectSolutionView add(@PathVariable Long projectId,
@RequestBody AddProjectSolutionRequest request) {
RequestScope scope = scope();
return solutionService.addProjectSolution(
projectId, request, scope.username(), scope.context());
}
@GetMapping
@Operation(summary = "List project solutions with requirement and product coverage")
public List<ProjectSolutionView> list(@PathVariable Long projectId) {
RequestScope scope = scope();
return solutionService.listProjectSolutions(
projectId, scope.username(), scope.context());
}
@PostMapping("/propose-from-taxonomy")
@Operation(summary = "Propose reusable solutions from confirmed taxonomy coverage")
public List<ProjectSolutionView> propose(@PathVariable Long projectId) {
RequestScope scope = scope();
return solutionService.proposeFromCurrentMappings(
projectId, scope.username(), scope.context());
}
@PatchMapping("/{projectSolutionId}")
@Operation(summary = "Review and classify a project solution")
public ProjectSolutionView update(@PathVariable Long projectId,
@PathVariable Long projectSolutionId,
@RequestBody UpdateProjectSolutionRequest request) {
RequestScope scope = scope();
return solutionService.updateProjectSolution(
projectId, projectSolutionId, request, scope.username(), scope.context());
}
@PostMapping("/{projectSolutionId}/requirements")
@Operation(summary = "Link a project solution to one requirement snapshot")
public ProjectSolutionView linkRequirement(
@PathVariable Long projectId,
@PathVariable Long projectSolutionId,
@RequestBody LinkRequirementSolutionRequest request) {
RequestScope scope = scope();
return solutionService.linkRequirement(
projectId, projectSolutionId, request, scope.username(), scope.context());
}
private RequestScope scope() {
return new RequestScope(
workspaceResolver.resolveCurrentUsername(),
workspaceResolver.resolveCurrentContext());
}
private record RequestScope(String username, WorkspaceContext context) {
}
}