feat(02-03): ClickHouse search engine, search controller, and 13 integration tests
- ClickHouseSearchEngine with dynamic WHERE clause building and LIKE escape - SearchController with GET (basic filters) and POST (advanced JSON body) - SearchBeanConfig wiring SearchEngine, SearchService, DetailService beans - 13 integration tests covering all filter types, combinations, pagination, empty results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package com.cameleer3.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.search.ExecutionSummary;
|
||||
import com.cameleer3.server.core.search.SearchRequest;
|
||||
import com.cameleer3.server.core.search.SearchResult;
|
||||
import com.cameleer3.server.core.search.SearchService;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Search endpoints for querying route executions.
|
||||
* <p>
|
||||
* GET supports basic filters via query parameters. POST accepts a full
|
||||
* {@link SearchRequest} JSON body for advanced search with all filter types.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/search")
|
||||
@Tag(name = "Search", description = "Transaction search endpoints")
|
||||
public class SearchController {
|
||||
|
||||
private final SearchService searchService;
|
||||
|
||||
public SearchController(SearchService searchService) {
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
@GetMapping("/executions")
|
||||
@Operation(summary = "Search executions with basic filters")
|
||||
public ResponseEntity<SearchResult<ExecutionSummary>> searchGet(
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) Instant timeFrom,
|
||||
@RequestParam(required = false) Instant timeTo,
|
||||
@RequestParam(required = false) String correlationId,
|
||||
@RequestParam(required = false) String text,
|
||||
@RequestParam(defaultValue = "0") int offset,
|
||||
@RequestParam(defaultValue = "50") int limit) {
|
||||
|
||||
SearchRequest request = new SearchRequest(
|
||||
status, timeFrom, timeTo,
|
||||
null, null,
|
||||
correlationId,
|
||||
text, null, null, null,
|
||||
offset, limit
|
||||
);
|
||||
|
||||
return ResponseEntity.ok(searchService.search(request));
|
||||
}
|
||||
|
||||
@PostMapping("/executions")
|
||||
@Operation(summary = "Advanced search with all filters")
|
||||
public ResponseEntity<SearchResult<ExecutionSummary>> searchPost(
|
||||
@RequestBody SearchRequest request) {
|
||||
return ResponseEntity.ok(searchService.search(request));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user