feat(sourcemap): 新增单条删除和全量裁剪接口,列表按上传时间倒序

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-06-23 11:56:35 +08:00
父节点 4c27eb2b97
当前提交 45ea8060b9
共有 3 个文件被更改,包括 50 次插入1 次删除

查看文件

@ -209,6 +209,18 @@ public class LogController {
return ApiResponse.success(sourcemapService.listByAppKey(appKey)); return ApiResponse.success(sourcemapService.listByAppKey(appKey));
} }
@DeleteMapping("/sourcemaps/{id}")
public ApiResponse<Void> deleteSourcemap(@PathVariable Long id) {
sourcemapService.deleteById(id);
return ApiResponse.ok();
}
@PostMapping("/sourcemaps/prune-all")
public ApiResponse<String> pruneAllSourcemaps() {
int deleted = sourcemapService.pruneAll();
return ApiResponse.success("Pruned " + deleted + " records");
}
// Webhooks // Webhooks
@GetMapping("/webhooks") @GetMapping("/webhooks")

查看文件

@ -28,6 +28,8 @@ public interface LogSourcemapRepository extends JpaRepository<LogSourcemapEntity
List<LogSourcemapEntity> findByAppKeyAndPlatformAndBundleNameOrderByUploadedAtDesc( List<LogSourcemapEntity> findByAppKeyAndPlatformAndBundleNameOrderByUploadedAtDesc(
String appKey, String platform, String bundleName); String appKey, String platform, String bundleName);
List<LogSourcemapEntity> findByAppKeyOrderByUploadedAtDesc(String appKey);
List<LogSourcemapEntity> findByAppKey(String appKey); List<LogSourcemapEntity> findByAppKey(String appKey);
void deleteByAppKey(String appKey); void deleteByAppKey(String appKey);

查看文件

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
@Service @Service
public class SourcemapService { public class SourcemapService {
@ -208,12 +209,46 @@ public class SourcemapService {
} }
} }
/** One-time / admin: apply the retention policy to all existing records. Returns deleted count. */
@Transactional
public int pruneAll() {
List<LogSourcemapEntity> all = sourcemapRepository.findAll();
long before = all.size();
record VersionKey(String appKey, String platform, String bundleName, String appVersion) {}
Set<VersionKey> versionKeys = all.stream()
.map(e -> new VersionKey(e.getAppKey(), e.getPlatform(), e.getBundleName(), e.getAppVersion()))
.collect(Collectors.toCollection(LinkedHashSet::new));
for (VersionKey key : versionKeys) {
pruneSourcemaps(key.appKey(), key.platform(), key.appVersion(), key.bundleName());
}
long after = sourcemapRepository.count();
int deleted = (int) (before - after);
log.info("pruneAll: scanned {} records, deleted {}", before, deleted);
return deleted;
}
public String readSourceMapContent(String storageKey) throws IOException { public String readSourceMapContent(String storageKey) throws IOException {
return Files.readString(Paths.get(storageKey)); return Files.readString(Paths.get(storageKey));
} }
@Transactional
public void deleteById(Long id) {
sourcemapRepository.findById(id).ifPresent(entity -> {
try {
Files.deleteIfExists(Paths.get(entity.getStorageKey()));
} catch (IOException e) {
log.warn("Could not delete sourcemap file {}: {}", entity.getStorageKey(), e.getMessage());
}
sourcemapRepository.delete(entity);
log.info("Sourcemap deleted: id={} storageKey={}", id, entity.getStorageKey());
});
}
public List<SourcemapInfo> listByAppKey(String appKey) { public List<SourcemapInfo> listByAppKey(String appKey) {
return sourcemapRepository.findByAppKey(appKey) return sourcemapRepository.findByAppKeyOrderByUploadedAtDesc(appKey)
.stream() .stream()
.map(e -> new SourcemapInfo( .map(e -> new SourcemapInfo(
e.getId(), e.getAppKey(), e.getPlatform(), e.getId(), e.getAppKey(), e.getPlatform(),