feat(audit): 补齐摄取管道入口并沉淀完成度审计
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
package com.bruce.rag.controller;
|
||||
|
||||
import com.bruce.common.domain.model.RequestResult;
|
||||
import com.bruce.rag.dto.request.IngestionRunCreateRequest;
|
||||
import com.bruce.rag.service.IIngestionRunService;
|
||||
import com.bruce.rag.vo.IngestionRunVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -25,6 +29,16 @@ public class IngestionRunController {
|
||||
|
||||
private final IIngestionRunService ingestionRunService;
|
||||
|
||||
@Operation(summary = "创建文件解析管道聚合视图")
|
||||
@PostMapping
|
||||
public RequestResult<IngestionRunVO> create(@Valid @RequestBody IngestionRunCreateRequest request) {
|
||||
log.info("文件解析管道创建开始,storeId={}, documentId={}", request.getStoreId(), request.getDocumentId());
|
||||
IngestionRunVO view = ingestionRunService.createRun(request);
|
||||
log.info("文件解析管道创建结束,runId={}, storeId={}, documentId={}",
|
||||
view.getRunId(), view.getStoreId(), view.getDocumentId());
|
||||
return RequestResult.success(view);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询文件解析管道聚合视图")
|
||||
@GetMapping("/{runId}")
|
||||
public RequestResult<IngestionRunVO> detail(@PathVariable("runId") String runId,
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.bruce.rag.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 文件解析管道创建请求。
|
||||
* <p>
|
||||
* 首轮实现不额外落摄取运行表,而是基于知识库与文档主数据生成可追踪的聚合 runId,
|
||||
* 让前端能够按统一入口进入管道详情页。
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "文件解析管道创建请求")
|
||||
public class IngestionRunCreateRequest {
|
||||
|
||||
@NotNull(message = "知识库ID不能为空")
|
||||
@Schema(description = "知识库ID")
|
||||
private Long storeId;
|
||||
|
||||
@NotNull(message = "文档ID不能为空")
|
||||
@Schema(description = "文档ID")
|
||||
private Long documentId;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bruce.rag.service;
|
||||
|
||||
import com.bruce.rag.dto.request.IngestionRunCreateRequest;
|
||||
import com.bruce.rag.vo.IngestionRunVO;
|
||||
|
||||
/**
|
||||
@@ -7,6 +8,11 @@ import com.bruce.rag.vo.IngestionRunVO;
|
||||
*/
|
||||
public interface IIngestionRunService {
|
||||
|
||||
/**
|
||||
* 创建文件解析管道视图入口。
|
||||
*/
|
||||
IngestionRunVO createRun(IngestionRunCreateRequest request);
|
||||
|
||||
/**
|
||||
* 按知识库和文档聚合摄取流水线视图。
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bruce.rag.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.bruce.modelprovider.dto.response.RagStoreModelConfigResponse;
|
||||
import com.bruce.modelprovider.service.IRagStoreModelConfigService;
|
||||
import com.bruce.rag.dto.request.IngestionRunCreateRequest;
|
||||
import com.bruce.rag.dto.response.RagDocumentResponse;
|
||||
import com.bruce.rag.dto.response.RagStoreResponse;
|
||||
import com.bruce.rag.entity.RagChunk;
|
||||
@@ -53,6 +54,19 @@ public class IngestionRunServiceImpl implements IIngestionRunService {
|
||||
private final IRagChunkEmbeddingService ragChunkEmbeddingService;
|
||||
private final IRagStoreModelConfigService ragStoreModelConfigService;
|
||||
|
||||
@Override
|
||||
public IngestionRunVO createRun(IngestionRunCreateRequest request) {
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException("文件解析管道创建请求不能为空");
|
||||
}
|
||||
log.info("文件解析管道创建聚合开始,storeId={}, documentId={}", request.getStoreId(), request.getDocumentId());
|
||||
IngestionRunVO view = getRun(request.getStoreId(), request.getDocumentId());
|
||||
view.setRunId(buildRunId(request.getStoreId(), request.getDocumentId()));
|
||||
log.info("文件解析管道创建聚合结束,runId={}, storeId={}, documentId={}",
|
||||
view.getRunId(), view.getStoreId(), view.getDocumentId());
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IngestionRunVO getRun(Long storeId, Long documentId) {
|
||||
log.info("文件解析管道聚合开始,storeId={}, documentId={}", storeId, documentId);
|
||||
@@ -104,6 +118,10 @@ public class IngestionRunServiceImpl implements IIngestionRunService {
|
||||
return view;
|
||||
}
|
||||
|
||||
private String buildRunId(Long storeId, Long documentId) {
|
||||
return "ingestion-" + safeNumber(storeId) + "-" + safeNumber(documentId);
|
||||
}
|
||||
|
||||
private IngestionRunFileVO toFileVO(RagDocumentResponse document) {
|
||||
IngestionRunFileVO file = new IngestionRunFileVO();
|
||||
file.setDocumentId(document.getId());
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.bruce.rag.controller;
|
||||
|
||||
import com.bruce.common.handler.GlobalExceptionHandler;
|
||||
import com.bruce.rag.service.IIngestionRunService;
|
||||
import com.bruce.rag.vo.IngestionRunVO;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* 验证文件解析管道聚合接口的请求绑定与响应结构。
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class IngestionRunControllerTests {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private IIngestionRunService ingestionRunService;
|
||||
|
||||
@InjectMocks
|
||||
private IngestionRunController ingestionRunController;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(ingestionRunController)
|
||||
.setControllerAdvice(new GlobalExceptionHandler())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createShouldReturnStructuredRunView() throws Exception {
|
||||
IngestionRunVO run = new IngestionRunVO();
|
||||
run.setRunId("ingestion-1001-11");
|
||||
run.setStoreId(1001L);
|
||||
run.setDocumentId(11L);
|
||||
|
||||
when(ingestionRunService.createRun(any())).thenReturn(run);
|
||||
|
||||
mockMvc.perform(post("/api/knowledge/ingestion-runs")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"storeId": 1001,
|
||||
"documentId": 11
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.resultcode").value("0"))
|
||||
.andExpect(jsonPath("$.data.runId").value("ingestion-1001-11"))
|
||||
.andExpect(jsonPath("$.data.storeId").value("1001"))
|
||||
.andExpect(jsonPath("$.data.documentId").value("11"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void detailShouldReturnStructuredRunView() throws Exception {
|
||||
IngestionRunVO run = new IngestionRunVO();
|
||||
run.setRunId("run-20260601");
|
||||
run.setStoreId(1001L);
|
||||
run.setDocumentId(11L);
|
||||
|
||||
when(ingestionRunService.getRun(1001L, 11L)).thenReturn(run);
|
||||
|
||||
mockMvc.perform(get("/api/knowledge/ingestion-runs/run-20260601")
|
||||
.param("storeId", "1001")
|
||||
.param("documentId", "11"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.resultcode").value("0"))
|
||||
.andExpect(jsonPath("$.data.runId").value("run-20260601"))
|
||||
.andExpect(jsonPath("$.data.storeId").value("1001"))
|
||||
.andExpect(jsonPath("$.data.documentId").value("11"));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.bruce.rag.ingestion;
|
||||
|
||||
import com.bruce.modelprovider.dto.response.RagStoreModelConfigResponse;
|
||||
import com.bruce.modelprovider.service.IRagStoreModelConfigService;
|
||||
import com.bruce.rag.dto.request.IngestionRunCreateRequest;
|
||||
import com.bruce.rag.dto.response.RagDocumentResponse;
|
||||
import com.bruce.rag.dto.response.RagStoreResponse;
|
||||
import com.bruce.rag.entity.RagChunk;
|
||||
@@ -51,6 +52,43 @@ class IngestionRunServiceTests {
|
||||
@InjectMocks
|
||||
private IngestionRunServiceImpl ingestionRunService;
|
||||
|
||||
@Test
|
||||
void createRunShouldGenerateStableRunId() {
|
||||
RagStoreResponse store = new RagStoreResponse();
|
||||
store.setId(1001L);
|
||||
store.setStoreCode("PROD_DOC");
|
||||
store.setStoreName("产品制度库");
|
||||
|
||||
RagDocumentResponse document = new RagDocumentResponse();
|
||||
document.setId(11L);
|
||||
document.setStoreId(1001L);
|
||||
document.setDocumentTitle("售前方案模板.pdf");
|
||||
document.setParseStatus("PARSED");
|
||||
document.setIndexStatus("INDEXED");
|
||||
document.setCreateTime(new Date(1748780000000L));
|
||||
document.setUpdateTime(new Date(1748780300000L));
|
||||
|
||||
when(ragStoreService.getResponseById(1001L)).thenReturn(store);
|
||||
when(ragDocumentService.getResponseById(11L)).thenReturn(document);
|
||||
when(ragDocumentParseResultService.getByDocumentId(11L)).thenReturn(null);
|
||||
when(ragChunkService.list(org.mockito.ArgumentMatchers.<com.baomidou.mybatisplus.core.conditions.Wrapper<RagChunk>>any()))
|
||||
.thenReturn(List.of());
|
||||
when(ragChunkEmbeddingService.list(org.mockito.ArgumentMatchers.<com.baomidou.mybatisplus.core.conditions.Wrapper<RagChunkEmbedding>>any()))
|
||||
.thenReturn(List.of());
|
||||
when(ragStoreModelConfigService.getByStoreId(1001L)).thenReturn(null);
|
||||
|
||||
IngestionRunCreateRequest request = new IngestionRunCreateRequest();
|
||||
request.setStoreId(1001L);
|
||||
request.setDocumentId(11L);
|
||||
|
||||
IngestionRunVO view = ingestionRunService.createRun(request);
|
||||
|
||||
assertNotNull(view);
|
||||
assertEquals("ingestion-1001-11", view.getRunId());
|
||||
assertEquals(1001L, view.getStoreId());
|
||||
assertEquals(11L, view.getDocumentId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRunShouldAggregatePipelinePreviewAndLogs() {
|
||||
RagStoreResponse store = new RagStoreResponse();
|
||||
|
||||
Reference in New Issue
Block a user