ExplanationTraceApiController.java
package com.taxonomy.architecture.controller;
import com.taxonomy.dto.ExplanationTrace;
import com.taxonomy.architecture.service.ExplanationTraceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* REST API for Structured Explainable Reasoning.
*
* <p>Endpoints:
* <ul>
* <li>{@code POST /api/explain/{nodeCode}} — Get structured explanation for a node</li>
* <li>{@code POST /api/explain} — Get explanations for all scored nodes</li>
* </ul>
*/
@RestController
@RequestMapping("/api/explain")
@Tag(name = "Explainable Reasoning")
public class ExplanationTraceApiController {
private final ExplanationTraceService traceService;
public ExplanationTraceApiController(ExplanationTraceService traceService) {
this.traceService = traceService;
}
/**
* Request body for explanation trace.
*/
public record ExplainRequest(
Map<String, Integer> scores,
Map<String, String> reasons,
String businessText,
int minScore) {
}
@Operation(summary = "Explain single node",
description = "Returns a structured explanation trace for why a specific node was scored")
@PostMapping("/{nodeCode}")
public ResponseEntity<ExplanationTrace> explainNode(
@Parameter(description = "Taxonomy node code") @PathVariable String nodeCode,
@RequestBody ExplainRequest request) {
ExplanationTrace trace = traceService.buildTrace(
nodeCode,
request.scores() != null ? request.scores() : Map.of(),
request.reasons(),
request.businessText());
return ResponseEntity.ok(trace);
}
@Operation(summary = "Explain all scored nodes",
description = "Returns structured explanation traces for all nodes above the score threshold")
@PostMapping
public ResponseEntity<Map<String, ExplanationTrace>> explainAll(
@RequestBody ExplainRequest request) {
Map<String, ExplanationTrace> traces = traceService.buildTraces(
request.scores() != null ? request.scores() : Map.of(),
request.reasons(),
request.businessText(),
request.minScore());
return ResponseEntity.ok(traces);
}
}