From 45ea8060b959b2def798ba2ff0a55dbe1216bbbf Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Tue, 23 Jun 2026 11:56:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(sourcemap):=20=E6=96=B0=E5=A2=9E=E5=8D=95?= =?UTF-8?q?=E6=9D=A1=E5=88=A0=E9=99=A4=E5=92=8C=E5=85=A8=E9=87=8F=E8=A3=81?= =?UTF-8?q?=E5=89=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=88=97=E8=A1=A8=E6=8C=89?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=97=B6=E9=97=B4=E5=80=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../bugcollect/controller/LogController.java | 12 ++++++ .../repository/LogSourcemapRepository.java | 2 + .../bugcollect/service/SourcemapService.java | 37 ++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/controller/LogController.java b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/controller/LogController.java index e3b1f38..f3077ec 100644 --- a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/controller/LogController.java +++ b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/controller/LogController.java @@ -209,6 +209,18 @@ public class LogController { return ApiResponse.success(sourcemapService.listByAppKey(appKey)); } + @DeleteMapping("/sourcemaps/{id}") + public ApiResponse deleteSourcemap(@PathVariable Long id) { + sourcemapService.deleteById(id); + return ApiResponse.ok(); + } + + @PostMapping("/sourcemaps/prune-all") + public ApiResponse pruneAllSourcemaps() { + int deleted = sourcemapService.pruneAll(); + return ApiResponse.success("Pruned " + deleted + " records"); + } + // ── Webhooks ─────────────────────────────────────────────────────────────── @GetMapping("/webhooks") diff --git a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/repository/LogSourcemapRepository.java b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/repository/LogSourcemapRepository.java index 348d35e..d2e0c7a 100644 --- a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/repository/LogSourcemapRepository.java +++ b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/repository/LogSourcemapRepository.java @@ -28,6 +28,8 @@ public interface LogSourcemapRepository extends JpaRepository findByAppKeyAndPlatformAndBundleNameOrderByUploadedAtDesc( String appKey, String platform, String bundleName); + List findByAppKeyOrderByUploadedAtDesc(String appKey); + List findByAppKey(String appKey); void deleteByAppKey(String appKey); diff --git a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/service/SourcemapService.java b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/service/SourcemapService.java index 9eccfb4..66f3cb1 100644 --- a/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/service/SourcemapService.java +++ b/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/service/SourcemapService.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; @Service 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 all = sourcemapRepository.findAll(); + long before = all.size(); + + record VersionKey(String appKey, String platform, String bundleName, String appVersion) {} + Set 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 { 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 listByAppKey(String appKey) { - return sourcemapRepository.findByAppKey(appKey) + return sourcemapRepository.findByAppKeyOrderByUploadedAtDesc(appKey) .stream() .map(e -> new SourcemapInfo( e.getId(), e.getAppKey(), e.getPlatform(),