612 lines
20 KiB
Markdown
612 lines
20 KiB
Markdown
# Prompt - 元数据拉取核心功能
|
||
|
||
## 输入引用
|
||
|
||
引用相关的 docs 文档链接:
|
||
|
||
- [REQ-010-6.md](../requirements/REQ-010-6.md) - 元数据拉取核心功能需求文档
|
||
- [REQ-010-1.md](../requirements/REQ-010-1.md) - 数据库表结构设计和创建
|
||
- [REQ-010-2.md](../requirements/REQ-010-2.md) - 基础实体类和Mapper创建
|
||
- [REQ-010-3.md](../requirements/REQ-010-3.md) - Salesforce组织配置管理
|
||
- [REQ-010-4.md](../requirements/REQ-010-4.md) - 元数据任务定义管理
|
||
- [REQ-010-5.md](../requirements/REQ-010-5.md) - Metadata API客户端封装
|
||
- [0015-metadata-retrieve-core.md](../decisions/adr/0015-metadata-retrieve-core.md) - 元数据拉取核心功能架构决策
|
||
|
||
## Context Maps
|
||
|
||
强制列出本次 Prompt 依赖的 Canvas 文件:
|
||
|
||
- [Authentication.canvas](../Authentication.canvas) - 项目架构视觉化展示
|
||
- **相关节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式
|
||
- **相关节点**: [SessionManager](node_session_manager_detail) - 会话管理,提供登录服务
|
||
|
||
## 目标
|
||
|
||
实现 Salesforce 元数据拉取的核心功能,包括手动触发拉取、异步拉取执行、状态监控、拉取历史记录、拉取进度查询、拉取取消功能等。
|
||
|
||
## 输出格式
|
||
|
||
### 代码示例(语言:Java)
|
||
|
||
#### 1. JobExecutionStatus 枚举类
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.enums;
|
||
|
||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||
import com.fasterxml.jackson.annotation.JsonValue;
|
||
|
||
/**
|
||
* 作业执行状态枚举
|
||
*/
|
||
public enum JobExecutionStatus {
|
||
PENDING("pending", "待执行"),
|
||
PROCESSING("processing", "执行中"),
|
||
SUCCESS("success", "成功"),
|
||
FAILED("failed", "失败"),
|
||
PARTIAL_SUCCESS("partial_success", "部分成功"),
|
||
CANCELLED("cancelled", "已取消");
|
||
|
||
@EnumValue
|
||
private final String code;
|
||
|
||
@JsonValue
|
||
private final String displayName;
|
||
|
||
JobExecutionStatus(String code, String displayName) {
|
||
this.code = code;
|
||
this.displayName = displayName;
|
||
}
|
||
|
||
public String getCode() {
|
||
return code;
|
||
}
|
||
|
||
public String getDisplayName() {
|
||
return displayName;
|
||
}
|
||
|
||
public static JobExecutionStatus fromCode(String code) {
|
||
for (JobExecutionStatus status : JobExecutionStatus.values()) {
|
||
if (status.getCode().equals(code)) {
|
||
return status;
|
||
}
|
||
}
|
||
throw new IllegalArgumentException("Invalid job execution status code: " + code);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2. MetadataRetrieveController 控制器
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.controller;
|
||
|
||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||
import com.datai.salesforce.metadata.dto.RetrieveRequest;
|
||
import com.datai.salesforce.metadata.dto.RetrieveResponse;
|
||
import com.datai.salesforce.metadata.dto.RetrieveProgressResponse;
|
||
import com.datai.salesforce.metadata.entity.DataiMetaJobExecution;
|
||
import com.datai.salesforce.metadata.service.IMetadataRetrieveService;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.http.ResponseEntity;
|
||
import org.springframework.validation.annotation.Validated;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import javax.validation.Valid;
|
||
|
||
/**
|
||
* 元数据拉取控制器
|
||
*/
|
||
@Slf4j
|
||
@RestController
|
||
@RequestMapping("/api/metadata/retrieve")
|
||
@Validated
|
||
public class MetadataRetrieveController {
|
||
|
||
@Autowired
|
||
private IMetadataRetrieveService metadataRetrieveService;
|
||
|
||
/**
|
||
* 手动触发拉取
|
||
*/
|
||
@PostMapping
|
||
public ResponseEntity<RetrieveResponse> triggerRetrieve(@Valid @RequestBody RetrieveRequest request) {
|
||
log.info("Trigger metadata retrieve, taskId: {}, orgConfigId: {}", request.getTaskId(), request.getOrgConfigId());
|
||
RetrieveResponse response = metadataRetrieveService.triggerRetrieve(request);
|
||
return ResponseEntity.ok(response);
|
||
}
|
||
|
||
/**
|
||
* 查询拉取历史记录
|
||
*/
|
||
@GetMapping("/history")
|
||
public ResponseEntity<Page<DataiMetaJobExecution>> getRetrieveHistory(
|
||
@RequestParam(required = false) Long taskId,
|
||
@RequestParam(required = false) Long orgConfigId,
|
||
@RequestParam(defaultValue = "1") int page,
|
||
@RequestParam(defaultValue = "10") int size) {
|
||
log.info("Get retrieve history, taskId: {}, orgConfigId: {}, page: {}, size: {}", taskId, orgConfigId, page, size);
|
||
Page<DataiMetaJobExecution> pageResult = metadataRetrieveService.getRetrieveHistory(taskId, orgConfigId, page, size);
|
||
return ResponseEntity.ok(pageResult);
|
||
}
|
||
|
||
/**
|
||
* 查询拉取进度
|
||
*/
|
||
@GetMapping("/progress/{jobId}")
|
||
public ResponseEntity<RetrieveProgressResponse> getRetrieveProgress(@PathVariable String jobId) {
|
||
log.info("Get retrieve progress, jobId: {}", jobId);
|
||
RetrieveProgressResponse response = metadataRetrieveService.getRetrieveProgress(jobId);
|
||
return ResponseEntity.ok(response);
|
||
}
|
||
|
||
/**
|
||
* 取消拉取
|
||
*/
|
||
@PostMapping("/cancel/{jobId}")
|
||
public ResponseEntity<Void> cancelRetrieve(@PathVariable String jobId) {
|
||
log.info("Cancel retrieve, jobId: {}", jobId);
|
||
metadataRetrieveService.cancelRetrieve(jobId);
|
||
return ResponseEntity.ok().build();
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 3. RetrieveRequest DTO
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.dto;
|
||
|
||
import lombok.Data;
|
||
|
||
import javax.validation.constraints.NotNull;
|
||
|
||
/**
|
||
* 拉取请求
|
||
*/
|
||
@Data
|
||
public class RetrieveRequest {
|
||
@NotNull(message = "任务ID不能为空")
|
||
private Long taskId;
|
||
|
||
@NotNull(message = "组织配置ID不能为空")
|
||
private Long orgConfigId;
|
||
}
|
||
```
|
||
|
||
#### 4. RetrieveResponse DTO
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.dto;
|
||
|
||
import lombok.AllArgsConstructor;
|
||
import lombok.Data;
|
||
import lombok.NoArgsConstructor;
|
||
|
||
/**
|
||
* 拉取响应
|
||
*/
|
||
@Data
|
||
@NoArgsConstructor
|
||
@AllArgsConstructor
|
||
public class RetrieveResponse {
|
||
private String jobId;
|
||
private String message;
|
||
}
|
||
```
|
||
|
||
#### 5. RetrieveProgressResponse DTO
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.dto;
|
||
|
||
import lombok.AllArgsConstructor;
|
||
import lombok.Data;
|
||
import lombok.NoArgsConstructor;
|
||
|
||
/**
|
||
* 拉取进度响应
|
||
*/
|
||
@Data
|
||
@NoArgsConstructor
|
||
@AllArgsConstructor
|
||
public class RetrieveProgressResponse {
|
||
private String jobId;
|
||
private String status;
|
||
private int progress;
|
||
private String message;
|
||
}
|
||
```
|
||
|
||
#### 6. IMetadataRetrieveService 服务接口
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.service;
|
||
|
||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||
import com.datai.salesforce.metadata.dto.RetrieveProgressResponse;
|
||
import com.datai.salesforce.metadata.dto.RetrieveRequest;
|
||
import com.datai.salesforce.metadata.dto.RetrieveResponse;
|
||
import com.datai.salesforce.metadata.entity.DataiMetaJobExecution;
|
||
|
||
/**
|
||
* 元数据拉取服务接口
|
||
*/
|
||
public interface IMetadataRetrieveService {
|
||
|
||
/**
|
||
* 手动触发拉取
|
||
*/
|
||
RetrieveResponse triggerRetrieve(RetrieveRequest request);
|
||
|
||
/**
|
||
* 查询拉取历史记录
|
||
*/
|
||
Page<DataiMetaJobExecution> getRetrieveHistory(Long taskId, Long orgConfigId, int page, int size);
|
||
|
||
/**
|
||
* 查询拉取进度
|
||
*/
|
||
RetrieveProgressResponse getRetrieveProgress(String jobId);
|
||
|
||
/**
|
||
* 取消拉取
|
||
*/
|
||
void cancelRetrieve(String jobId);
|
||
}
|
||
```
|
||
|
||
#### 7. MetadataRetrieveServiceImpl 服务实现
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.service.impl;
|
||
|
||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||
import com.datai.salesforce.metadata.client.MetadataApiClient;
|
||
import com.datai.salesforce.metadata.dto.RetrieveProgressResponse;
|
||
import com.datai.salesforce.metadata.dto.RetrieveRequest;
|
||
import com.datai.salesforce.metadata.dto.RetrieveResponse;
|
||
import com.datai.salesforce.metadata.entity.DataiMetaJobExecution;
|
||
import com.datai.salesforce.metadata.entity.DataiMetaTask;
|
||
import com.datai.salesforce.metadata.enums.JobExecutionStatus;
|
||
import com.datai.salesforce.metadata.enums.ScheduleType;
|
||
import com.datai.salesforce.metadata.exception.RetrieveException;
|
||
import com.datai.salesforce.metadata.mapper.DataiMetaJobExecutionMapper;
|
||
import com.datai.salesforce.metadata.mapper.DataiMetaTaskMapper;
|
||
import com.datai.salesforce.metadata.model.RetrieveRequest as SfRetrieveRequest;
|
||
import com.datai.salesforce.metadata.model.RetrieveResult as SfRetrieveResult;
|
||
import com.datai.salesforce.metadata.service.IMetadataRetrieveService;
|
||
import com.datai.salesforce.metadata.util.PackageXmlEditor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.scheduling.annotation.Async;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import java.util.Date;
|
||
import java.util.UUID;
|
||
import java.util.concurrent.ConcurrentHashMap;
|
||
import java.util.concurrent.Future;
|
||
|
||
/**
|
||
* 元数据拉取服务实现
|
||
*/
|
||
@Slf4j
|
||
@Service
|
||
public class MetadataRetrieveServiceImpl implements IMetadataRetrieveService {
|
||
|
||
@Autowired
|
||
private MetadataApiClient metadataApiClient;
|
||
|
||
@Autowired
|
||
private DataiMetaTaskMapper taskMapper;
|
||
|
||
@Autowired
|
||
private DataiMetaJobExecutionMapper jobExecutionMapper;
|
||
|
||
@Autowired
|
||
private PackageXmlEditor packageXmlEditor;
|
||
|
||
private final ConcurrentHashMap<String, Future<?>> runningJobs = new ConcurrentHashMap<>();
|
||
|
||
@Override
|
||
@Transactional
|
||
public RetrieveResponse triggerRetrieve(RetrieveRequest request) {
|
||
DataiMetaTask task = taskMapper.selectById(request.getTaskId());
|
||
if (task == null) {
|
||
throw new RetrieveException("任务不存在");
|
||
}
|
||
|
||
String jobId = UUID.randomUUID().toString();
|
||
|
||
DataiMetaJobExecution jobExecution = new DataiMetaJobExecution();
|
||
jobExecution.setJobId(jobId);
|
||
jobExecution.setTaskId(request.getTaskId());
|
||
jobExecution.setOrgConfigId(request.getOrgConfigId());
|
||
jobExecution.setJobType("RETRIEVE");
|
||
jobExecution.setStatus(JobExecutionStatus.PENDING.getCode());
|
||
jobExecution.setStartTime(new Date());
|
||
jobExecution.setCreateTime(new Date());
|
||
jobExecution.setUpdateTime(new Date());
|
||
jobExecutionMapper.insert(jobExecution);
|
||
|
||
executeRetrieveAsync(jobId, request.getTaskId(), request.getOrgConfigId());
|
||
|
||
return new RetrieveResponse(jobId, "拉取任务已创建");
|
||
}
|
||
|
||
@Async("metadataTaskExecutor")
|
||
public void executeRetrieveAsync(String jobId, Long taskId, Long orgConfigId) {
|
||
try {
|
||
updateJobStatus(jobId, JobExecutionStatus.PROCESSING);
|
||
|
||
DataiMetaTask task = taskMapper.selectById(taskId);
|
||
String packageXml = task.getPackageXml();
|
||
|
||
SfRetrieveRequest sfRequest = new SfRetrieveRequest();
|
||
sfRequest.setOrgConfigId(orgConfigId);
|
||
sfRequest.setPackageNames(new String[]{});
|
||
sfRequest.setSinglePackage(false);
|
||
sfRequest.setSpecificFiles(new String[]{});
|
||
sfRequest.setUnpackaged(packageXmlEditor.parsePackageXml(packageXml));
|
||
sfRequest.setTimeout(300000);
|
||
|
||
SfRetrieveResult result = metadataApiClient.retrieve(sfRequest);
|
||
|
||
if (result.isSuccess()) {
|
||
updateJobStatus(jobId, JobExecutionStatus.SUCCESS);
|
||
log.info("Retrieve job {} completed successfully", jobId);
|
||
} else {
|
||
updateJobStatus(jobId, JobExecutionStatus.FAILED);
|
||
log.error("Retrieve job {} failed: {}", jobId, result.getMessage());
|
||
}
|
||
} catch (Exception e) {
|
||
log.error("Retrieve job {} failed", jobId, e);
|
||
updateJobStatus(jobId, JobExecutionStatus.FAILED);
|
||
} finally {
|
||
runningJobs.remove(jobId);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public Page<DataiMetaJobExecution> getRetrieveHistory(Long taskId, Long orgConfigId, int page, int size) {
|
||
QueryWrapper<DataiMetaJobExecution> queryWrapper = new QueryWrapper<>();
|
||
queryWrapper.eq("job_type", "RETRIEVE");
|
||
if (taskId != null) {
|
||
queryWrapper.eq("task_id", taskId);
|
||
}
|
||
if (orgConfigId != null) {
|
||
queryWrapper.eq("org_config_id", orgConfigId);
|
||
}
|
||
queryWrapper.orderByDesc("create_time");
|
||
|
||
Page<DataiMetaJobExecution> pageParam = new Page<>(page, size);
|
||
return jobExecutionMapper.selectPage(pageParam, queryWrapper);
|
||
}
|
||
|
||
@Override
|
||
public RetrieveProgressResponse getRetrieveProgress(String jobId) {
|
||
DataiMetaJobExecution jobExecution = jobExecutionMapper.selectOne(
|
||
new QueryWrapper<DataiMetaJobExecution>().eq("job_id", jobId)
|
||
);
|
||
|
||
if (jobExecution == null) {
|
||
throw new RetrieveException("作业不存在");
|
||
}
|
||
|
||
int progress = calculateProgress(jobExecution.getStatus());
|
||
|
||
return new RetrieveProgressResponse(
|
||
jobId,
|
||
jobExecution.getStatus(),
|
||
progress,
|
||
jobExecution.getMessage()
|
||
);
|
||
}
|
||
|
||
@Override
|
||
public void cancelRetrieve(String jobId) {
|
||
Future<?> future = runningJobs.get(jobId);
|
||
if (future != null) {
|
||
boolean cancelled = future.cancel(true);
|
||
if (cancelled) {
|
||
updateJobStatus(jobId, JobExecutionStatus.CANCELLED);
|
||
log.info("Retrieve job {} cancelled successfully", jobId);
|
||
} else {
|
||
throw new RetrieveException("取消失败,作业可能已完成或无法取消");
|
||
}
|
||
} else {
|
||
throw new RetrieveException("作业不存在或已完成");
|
||
}
|
||
}
|
||
|
||
private void updateJobStatus(String jobId, JobExecutionStatus status) {
|
||
DataiMetaJobExecution jobExecution = new DataiMetaJobExecution();
|
||
jobExecution.setJobId(jobId);
|
||
jobExecution.setStatus(status.getCode());
|
||
jobExecution.setUpdateTime(new Date());
|
||
|
||
if (status == JobExecutionStatus.SUCCESS || status == JobExecutionStatus.FAILED || status == JobExecutionStatus.CANCELLED) {
|
||
jobExecution.setEndTime(new Date());
|
||
}
|
||
|
||
jobExecutionMapper.update(jobExecution, new QueryWrapper<DataiMetaJobExecution>().eq("job_id", jobId));
|
||
}
|
||
|
||
private int calculateProgress(String status) {
|
||
switch (JobExecutionStatus.fromCode(status)) {
|
||
case PENDING:
|
||
return 0;
|
||
case PROCESSING:
|
||
return 50;
|
||
case SUCCESS:
|
||
case PARTIAL_SUCCESS:
|
||
return 100;
|
||
case FAILED:
|
||
case CANCELLED:
|
||
return 0;
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 8. RetrieveException 异常类
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.exception;
|
||
|
||
/**
|
||
* 拉取异常
|
||
*/
|
||
public class RetrieveException extends RuntimeException {
|
||
public RetrieveException(String message) {
|
||
super(message);
|
||
}
|
||
|
||
public RetrieveException(String message, Throwable cause) {
|
||
super(message, cause);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 9. 单元测试
|
||
|
||
```java
|
||
package com.datai.salesforce.metadata.service.impl;
|
||
|
||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||
import com.datai.salesforce.metadata.dto.RetrieveProgressResponse;
|
||
import com.datai.salesforce.metadata.dto.RetrieveRequest;
|
||
import com.datai.salesforce.metadata.dto.RetrieveResponse;
|
||
import com.datai.salesforce.metadata.entity.DataiMetaJobExecution;
|
||
import com.datai.salesforce.metadata.enums.JobExecutionStatus;
|
||
import com.datai.salesforce.metadata.exception.RetrieveException;
|
||
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 static org.junit.jupiter.api.Assertions.*;
|
||
import static org.mockito.ArgumentMatchers.any;
|
||
import static org.mockito.Mockito.*;
|
||
|
||
@ExtendWith(MockitoExtension.class)
|
||
class MetadataRetrieveServiceImplTest {
|
||
|
||
@Mock
|
||
private MetadataApiClient metadataApiClient;
|
||
|
||
@Mock
|
||
private DataiMetaTaskMapper taskMapper;
|
||
|
||
@Mock
|
||
private DataiMetaJobExecutionMapper jobExecutionMapper;
|
||
|
||
@InjectMocks
|
||
private MetadataRetrieveServiceImpl metadataRetrieveService;
|
||
|
||
@Test
|
||
void testTriggerRetrieve() {
|
||
RetrieveRequest request = new RetrieveRequest();
|
||
request.setTaskId(1L);
|
||
request.setOrgConfigId(1L);
|
||
|
||
when(taskMapper.selectById(any())).thenReturn(new com.datai.salesforce.metadata.entity.DataiMetaTask());
|
||
when(jobExecutionMapper.insert(any())).thenReturn(1);
|
||
|
||
RetrieveResponse response = metadataRetrieveService.triggerRetrieve(request);
|
||
|
||
assertNotNull(response);
|
||
assertNotNull(response.getJobId());
|
||
}
|
||
|
||
@Test
|
||
void testGetRetrieveHistory() {
|
||
Page<DataiMetaJobExecution> page = metadataRetrieveService.getRetrieveHistory(1L, 1L, 1, 10);
|
||
|
||
assertNotNull(page);
|
||
}
|
||
|
||
@Test
|
||
void testGetRetrieveProgress() {
|
||
DataiMetaJobExecution jobExecution = new DataiMetaJobExecution();
|
||
jobExecution.setJobId("test-job-id");
|
||
jobExecution.setStatus(JobExecutionStatus.PROCESSING.getCode());
|
||
|
||
when(jobExecutionMapper.selectOne(any())).thenReturn(jobExecution);
|
||
|
||
RetrieveProgressResponse response = metadataRetrieveService.getRetrieveProgress("test-job-id");
|
||
|
||
assertNotNull(response);
|
||
assertEquals("test-job-id", response.getJobId());
|
||
assertEquals(JobExecutionStatus.PROCESSING.getCode(), response.getStatus());
|
||
assertEquals(50, response.getProgress());
|
||
}
|
||
|
||
@Test
|
||
void testCancelRetrieve() {
|
||
assertThrows(RetrieveException.class, () -> {
|
||
metadataRetrieveService.cancelRetrieve("test-job-id");
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
## 约束
|
||
|
||
列出使用此提示词时的约束条件,例如:
|
||
|
||
- **技术栈限制**: 必须使用 Spring Boot 3、MyBatis Plus、Redis
|
||
- **架构约束**: 必须遵循 Authentication.canvas 中定义的架构和调用关系
|
||
- **模块约束**: 必须在 datai-salesforce-metadata 模块下实现
|
||
- **认证约束**: 必须使用 SessionManager 进行会话管理和自动重新登录
|
||
- **API约束**: 必须使用现有的集成核心功能进行 API 调用
|
||
- **异步约束**: 必须使用异步线程池执行长时间任务
|
||
- **依赖约束**: 必须依赖于 REQ-010-1, REQ-010-2, REQ-010-3, REQ-010-4, REQ-010-5
|
||
|
||
## Rule Set
|
||
|
||
"请严格参考 @Authentication.canvas 中的状态机转移逻辑,不要自行发挥。"
|
||
|
||
**具体规则**:
|
||
- 必须使用 Canvas 中定义的类名和方法名
|
||
- 必须遵循 Canvas 中定义的调用关系
|
||
- 必须参考 Canvas 中的流程图逻辑
|
||
- 必须使用 SessionManager 进行会话管理和自动重新登录
|
||
- 必须使用现有的认证模块进行 OAuth 认证
|
||
- 必须使用现有的集成核心功能进行 API 调用
|
||
- 必须遵循现有的异常处理机制
|
||
- 必须遵循现有的日志记录规范
|
||
|
||
## 验收标准
|
||
|
||
定义验证输出质量的具体标准,例如:
|
||
|
||
- **功能完整性**: 所有拉取功能能够正常工作,异步执行机制正常
|
||
- **代码规范性**: 代码符合项目编码规范,有清晰的注释
|
||
- **性能要求**: 异步执行不影响系统响应,状态轮询频率合理
|
||
- **可维护性**: 代码结构清晰,易于扩展和维护
|
||
- **可测试性**: 代码易于单元测试和集成测试
|
||
|
||
## 风险
|
||
|
||
识别使用此提示词可能带来的风险,例如:
|
||
|
||
- **异步执行风险**: 异步执行机制复杂可能导致状态管理困难
|
||
- **状态轮询风险**: 状态轮询频率不当可能导致 API 限流
|
||
- **拉取取消风险**: 拉取取消功能复杂可能导致资源泄漏
|
||
- **历史记录风险**: 拉取历史记录过多可能影响查询性能
|
||
- **进度查询风险**: 进度查询不准确可能导致用户体验差
|
||
|
||
## 使用记录
|
||
|
||
| 日期 | 使用场景 | 输入参数 | 输出结果 | 反馈 | 改进措施 |
|
||
|------|---------|---------|---------|------|----------|
|
||
| 2026-01-19 | 元数据拉取核心功能实现 | REQ-010-6 需求文档、ADR 文档 | JobExecutionStatus 枚举类、MetadataRetrieveController 控制器、RetrieveRequest DTO、RetrieveResponse DTO、RetrieveProgressResponse DTO、IMetadataRetrieveService 服务接口、MetadataRetrieveServiceImpl 服务实现、RetrieveException 异常类、单元测试 | 待反馈 | 待改进 |
|