feat(enrichment): ingest KEV,EPSS,OSV feeds with vulnerability rescoring#35
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds CVE persistence, external KEV/EPSS/OSV clients, revised priority scoring, and scheduled feed synchronization that updates stored vulnerabilities. ChangesEnrichment and rescoring
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Scheduler
participant FeedSyncService
participant VulnerabilityRepository
participant FeedService
participant VulnerabilityUpdateService
Scheduler->>FeedSyncService: invoke syncFeeds()
FeedSyncService->>VulnerabilityRepository: load vulnerability page
FeedSyncService->>FeedService: fetchFeeds(cve, packageName, ecosystem)
FeedService-->>FeedSyncService: return FeedResult
FeedSyncService->>VulnerabilityUpdateService: update vulnerability
VulnerabilityUpdateService->>VulnerabilityRepository: save updated vulnerability
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (4)
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.java (1)
17-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExternalize the OSV API URL to configuration.
The hardcoded URL prevents environment-specific overrides (e.g., pointing to a mock or staging OSV instance) and reduces testability. Consider using
@Valueor a@ConfigurationPropertiesclass.♻️ Proposed refactor
`@Component` public class OsvClient { private final RestTemplate restTemplate; + private final String osvUrl; - public OsvClient(RestTemplate restTemplate) { + public OsvClient(RestTemplate restTemplate, + `@Value`("${osv.api.url:https://api.osv.dev/v1/query}") String osvUrl) { this.restTemplate = restTemplate; + this.osvUrl = osvUrl; } - private static final String URL = "https://api.osv.dev/v1/query"; - public OsvResponse query(String packageName, String ecosystem) { OsvPackage osvPackage = new OsvPackage().setName(packageName).setEcosystem(ecosystem); OsvRequest osvRequest = new OsvRequest().setPkg(osvPackage); - return restTemplate.postForObject(URL, osvRequest, OsvResponse.class); + return restTemplate.postForObject(osvUrl, osvRequest, OsvResponse.class); } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.java` around lines 17 - 24, Externalize the hardcoded OSV endpoint in OsvClient by injecting the URL through application configuration, using the existing Spring configuration pattern such as `@Value` or a configuration-properties class. Update query to use the injected/configured value instead of the static URL constant, while preserving the current request and response behavior.backend/libs/domain/src/main/java/dev/cleat/domain/PriorityCalculator.java (1)
16-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd explicit parentheses for operator precedence clarity.
The expression
vulnerability.kev() || vulnerability.cvss() >= 9.0 && vulnerability.reachable() == Reachable.REACHABLErelies on Java's&&binding tighter than||. While correct, this is a common readability trap that could lead to bugs during future edits.♻️ Proposed refactor
- if (vulnerability.kev() || vulnerability.cvss() >= 9.0 && vulnerability.reachable() == Reachable.REACHABLE) { + if (vulnerability.kev() || (vulnerability.cvss() >= 9.0 && vulnerability.reachable() == Reachable.REACHABLE)) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/domain/src/main/java/dev/cleat/domain/PriorityCalculator.java` around lines 16 - 17, Update the condition in PriorityCalculator to add explicit parentheses around the combined CVSS threshold and reachability checks, preserving the existing logic that KEV vulnerabilities or high-CVSS reachable vulnerabilities return Priority.URGENT.backend/libs/enrichment/src/main/java/dev/cleat/enrichment/service/FeedService.java (1)
39-51: 🩺 Stability & Availability | 🔵 TrivialConsider partial enrichment resilience.
fetchFeedsaggregates three external API calls in a single try-catch. If any one feed (e.g., OSV) is unavailable, all enrichment for that CVE is lost — KEV and EPSS updates are also discarded. For a scheduled job processing many vulnerabilities, a single flaky feed can block all enrichment across the batch.Consider catching failures per-feed and returning partial results (e.g., null for the failed feed) so transient failures in one API don't prevent updates from the others.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/service/FeedService.java` around lines 39 - 51, Update FeedService.fetchFeeds to isolate kevClient.isKev, epssClient.fetchScore, and osvClient.query into separate failure-handling paths, allowing each successful feed value to be retained while assigning the failed feed’s result as null. Return a FeedResult with these partial values and avoid rethrowing one feed’s exception as a FeedSyncException that discards the other enrichments.backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java (1)
40-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding tests for null-CVE skip and error-handling paths.
The current test covers only the happy path. Two important branches in
FeedSyncService.syncFeedsare untested:
- Null CVE skip — entities with
cve == nullare logged and skipped. A test verifying thatsaveAllis not called with updated fields for these entities would guard against regressions.- Exception handling — if
fetchFeedsthrows, the entity should retain its original values and processing should continue for remaining entities.Additionally,
new OsvResponse()has a nullsummary, so the title-update path (v.setTitle(feed.osv().getSummary())) is never exercised.🧪 Suggested additional tests
`@Test` void shouldSkipVulnerabilitiesWithoutCve() { VulnerabilityEntity noCveEntity = new VulnerabilityEntity() .setCve(null) .setPackageName("spring-core") .setEcosystem("maven") .setCvss(9.5) .setSeverity(Severity.HIGH) .setReachable(Reachable.REACHABLE); when(vulnerabilityRepository.findAll()).thenReturn(List.of(noCveEntity)); feedSyncService.syncFeeds(); verify(feedService, never()).fetchFeeds(any(), any(), any()); verify(vulnerabilityRepository).saveAll(any()); assertNull(noCveEntity.getKev()); } `@Test` void shouldContinueProcessingWhenFetchFails() { VulnerabilityEntity failingEntity = new VulnerabilityEntity() .setCve("CVE-2025-9999") .setPackageName("log4j-core") .setEcosystem("maven") .setCvss(7.5) .setSeverity(Severity.HIGH) .setReachable(Reachable.NOT_REACHABLE); when(vulnerabilityRepository.findAll()).thenReturn(List.of(failingEntity)); when(feedService.fetchFeeds(any(), any(), any())) .thenThrow(new RuntimeException("Feed unavailable")); feedSyncService.syncFeeds(); verify(vulnerabilityRepository).saveAll(any()); // Entity should retain original values assertNull(failingEntity.getKev()); assertNull(failingEntity.getEpss()); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java` around lines 40 - 70, Add tests alongside shouldRescoreAllVulnerabilities for the null-CVE and fetchFeeds exception branches in FeedSyncService.syncFeeds: verify null-CVE entities skip feedService.fetchFeeds and retain unchanged fields, and verify fetch failures still call saveAll while preserving original values and allowing subsequent entities to process. Also provide a non-null OsvResponse summary in the happy-path test to exercise title updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/apps/api/src/main/java/dev/cleat/api/CleatApiApplication.java`:
- Line 20: Add a TaskScheduler bean in CleatApiApplication alongside
`@EnableScheduling`, using ThreadPoolTaskScheduler with a pool size of 2 and the
“feed-sync-” thread-name prefix, so scheduled tasks can execute concurrently
without changing FeedSyncService.syncFeeds().
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/EpssClient.java`:
- Around line 17-24: Update fetchScore in EpssClient to construct the request
through RestTemplate URI-variable expansion or UriComponentsBuilder, passing cve
as an encoded path/query value instead of concatenating it directly with URL.
Preserve the existing response validation and score extraction behavior.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java`:
- Around line 18-24: Update KevClient.isKev and the FeedSyncService sync flow so
the CISA feed is fetched once per sync cycle or cached with an appropriate TTL,
then reuse a parsed vulnerability ID Set for membership checks instead of
calling restTemplate.getForObject for every CVE. Preserve false results for
missing or empty feed data and ensure the cache refreshes when it expires or a
new sync cycle begins.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.java`:
- Around line 13-15: Update the shared RestTemplate bean in RestTemplateConfig
to configure explicit connection and read timeouts, ensuring
OsvClient.postForObject calls cannot block indefinitely. Preserve the existing
bean reuse by enrichment clients and choose appropriate finite timeout values.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/config/RestTemplateConfig.java`:
- Around line 10-13: Update the restTemplate() bean in RestTemplateConfig to
construct the RestTemplate with finite connection and read timeouts using the
project’s established HTTP request factory or timeout configuration. Ensure the
configured timeouts apply to calls made by EpssClient, KevClient, and OsvClient
while preserving the existing bean contract.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/KevVulnerability.java`:
- Line 8: Update the cveId field in KevVulnerability with an explicit Jackson
property mapping for the KEV feed’s exact cveID name, preserving the existing
field and ensuring isKev() can match deserialized entries.
In
`@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.java`:
- Around line 36-63: Remove the broad transaction boundary from syncFeeds and
ensure feedService.fetchFeeds is invoked outside any transaction spanning the
full vulnerability loop. Persist updates through separate transaction
boundaries, such as a dedicated transactional update method per vulnerability or
batch, while preserving the existing skip, error handling, and priority
calculation behavior.
- Line 40: Update the vulnerability loading flow in FeedSyncService to replace
vulnerabilityRepository.findAll() with paginated retrieval using
findAll(Pageable). Process each page or batch incrementally, preserving the
existing synchronization behavior while avoiding loading the full vulnerability
dataset into memory.
- Around line 46-63: Update the per-vulnerability processing in FeedSyncService
so vulnerabilityRepository.saveAll only receives entities whose complete
enrichment, including priorityCalculator.calculate and setPriority, succeeds.
Track successfully enriched vulnerabilities separately and exclude failed
entities from persistence; do not save partially updated state from the catch
path.
---
Nitpick comments:
In `@backend/libs/domain/src/main/java/dev/cleat/domain/PriorityCalculator.java`:
- Around line 16-17: Update the condition in PriorityCalculator to add explicit
parentheses around the combined CVSS threshold and reachability checks,
preserving the existing logic that KEV vulnerabilities or high-CVSS reachable
vulnerabilities return Priority.URGENT.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.java`:
- Around line 17-24: Externalize the hardcoded OSV endpoint in OsvClient by
injecting the URL through application configuration, using the existing Spring
configuration pattern such as `@Value` or a configuration-properties class. Update
query to use the injected/configured value instead of the static URL constant,
while preserving the current request and response behavior.
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/service/FeedService.java`:
- Around line 39-51: Update FeedService.fetchFeeds to isolate kevClient.isKev,
epssClient.fetchScore, and osvClient.query into separate failure-handling paths,
allowing each successful feed value to be retained while assigning the failed
feed’s result as null. Return a FeedResult with these partial values and avoid
rethrowing one feed’s exception as a FeedSyncException that discards the other
enrichments.
In
`@backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java`:
- Around line 40-70: Add tests alongside shouldRescoreAllVulnerabilities for the
null-CVE and fetchFeeds exception branches in FeedSyncService.syncFeeds: verify
null-CVE entities skip feedService.fetchFeeds and retain unchanged fields, and
verify fetch failures still call saveAll while preserving original values and
allowing subsequent entities to process. Also provide a non-null OsvResponse
summary in the happy-path test to exercise title updates.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bdc05b54-70e7-46e0-a9e0-1a3a0cf5befb
📒 Files selected for processing (29)
backend/apps/api/build.gradle.ktsbackend/apps/api/src/main/java/dev/cleat/api/CleatApiApplication.javabackend/libs/common/src/main/java/dev/cleat/common/dto/request/VulnerabilityRequestDto.javabackend/libs/common/src/main/java/dev/cleat/common/dto/response/VulnerabilityResponseDto.javabackend/libs/common/src/main/java/dev/cleat/common/exception/FeedSyncException.javabackend/libs/domain/src/main/java/dev/cleat/domain/PriorityCalculator.javabackend/libs/domain/src/main/java/dev/cleat/domain/model/Vulnerability.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/EpssClient.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/config/RestTemplateConfig.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/EpssData.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/EpssResponse.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/FeedResult.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/KevResponse.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/KevVulnerability.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/OsvPackage.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/OsvRequest.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/OsvResponse.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/service/FeedService.javabackend/libs/persistence/src/main/java/dev/cleat/persistence/entity/VulnerabilityEntity.javabackend/libs/persistence/src/main/java/dev/cleat/persistence/mapper/VulnerabilityMapper.javabackend/libs/persistence/src/main/resources/db/migration/V6__alter_vulnerability_table.sqlbackend/libs/scanning/build.gradle.ktsbackend/libs/scanning/src/main/java/dev/cleat/scanning/VulnerabilityScanner.javabackend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.javabackend/libs/scanning/src/main/resources/application.ymlbackend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.javabackend/libs/scanning/src/test/java/dev/cleat/scanning/VulnerabilityScannerTest.java
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/apps/api/src/main/java/dev/cleat/api/config/SchedulingConfig.java`:
- Around line 8-17: Move the taskScheduler bean from SchedulingConfig into a
package scanned by CleatWorkerApplication, or define it directly in that
application’s configuration. Preserve the existing ThreadPoolTaskScheduler
settings, including pool size 4 and the "scheduler-" thread prefix, and remove
the unused API-side bean.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: db4c7f11-ee19-4b4b-8a22-3c071b3c3012
📒 Files selected for processing (5)
backend/apps/api/src/main/java/dev/cleat/api/config/SchedulingConfig.javabackend/apps/api/src/main/resources/application.ymlbackend/apps/worker/src/main/java/dev/cleat/worker/CleatWorkerApplication.javabackend/apps/worker/src/main/resources/application.ymlbackend/libs/enrichment/src/main/java/dev/cleat/enrichment/config/RestTemplateConfig.java
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/libs/enrichment/src/main/java/dev/cleat/enrichment/config/RestTemplateConfig.java
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java (1)
24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueEncapsulate cache: make
getKevCache()private and return an unmodifiable set.
getKevCache()is only called internally byisKev(); exposing it publicly leaks a mutableHashSet(fromCollectors.toSet()) that callers could modify, corrupting the cache. Make the methodprivateand wrap the result inCollections.unmodifiableSetor useSet.copyOf.♻️ Proposed refactor
- public Set<String> getKevCache() { + private Set<String> getKevCache() { if (kevCache == null || System.currentTimeMillis() - cacheTimestamp > CACHE_TTL_MS) { KevResponse response = restTemplate.getForObject(URL, KevResponse.class); kevCache = (response == null || response.getVulnerabilities() == null) ? Set.of() : response.getVulnerabilities().stream() .map(KevVulnerability::getCveId) - .collect(Collectors.toSet()); + .collect(Collectors.toUnmodifiableSet()); cacheTimestamp = System.currentTimeMillis(); } return kevCache; }Also applies to: 28-32
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java` at line 24, Update getKevCache() to be private and return an unmodifiable set, using Collections.unmodifiableSet or Set.copyOf around the collected cache before returning it. Preserve isKev()’s internal use of the cache and ensure callers cannot mutate the underlying HashSet.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java`:
- Around line 24-36: Make getKevCache() synchronized so reads and refreshes of
the shared kevCache and cacheTimestamp state are atomic across threads. Preserve
the existing TTL check, feed refresh, and cached return behavior while ensuring
concurrent callers cannot observe partially updated state or trigger redundant
refreshes.
---
Nitpick comments:
In
`@backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java`:
- Line 24: Update getKevCache() to be private and return an unmodifiable set,
using Collections.unmodifiableSet or Set.copyOf around the collected cache
before returning it. Preserve isKev()’s internal use of the cache and ensure
callers cannot mutate the underlying HashSet.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 69d7a66c-f2b9-4987-a4d3-c1f3a33efeba
📒 Files selected for processing (3)
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/EpssClient.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.javabackend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/KevVulnerability.java
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/libs/enrichment/src/main/java/dev/cleat/enrichment/dto/KevVulnerability.java
- backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/EpssClient.java
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
backend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.java (1)
31-49: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick winDelegation fix resolves prior transactional/partial-enrichment issues, but unpaginated
findAll()remains.Moving persistence into per-entity
vulnerabilityUpdateService.update(v, feed)calls correctly resolves the earlier long-running-transaction and partial-enrichment-persisted issues. However, Line 34'svulnerabilityRepository.findAll()still loads the entire vulnerability table into memory, which was previously flagged as a major issue and has not been addressed.♻️ Suggested pagination approach
- List<VulnerabilityEntity> vulnerabilities = vulnerabilityRepository.findAll(); - for (VulnerabilityEntity v : vulnerabilities) { - ... - } + Pageable pageable = PageRequest.of(0, BATCH_SIZE); + Page<VulnerabilityEntity> page; + do { + page = vulnerabilityRepository.findAll(pageable); + for (VulnerabilityEntity v : page.getContent()) { + ... + } + pageable = pageable.next(); + } while (page.hasNext());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.java` around lines 31 - 49, Replace the unbounded vulnerabilityRepository.findAll() call in syncFeeds() with paginated retrieval and process one page or batch at a time. Continue applying the existing per-entity CVE validation, feed fetching, and vulnerabilityUpdateService.update() flow, and stop when no further pages remain without loading the entire table into memory.
🧹 Nitpick comments (2)
backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java (1)
39-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider testing the skip and error-continuation branches.
The refactored test only covers the happy path where a valid CVE resolves and
update()succeeds. It doesn't coverv.getCve() == null(skip branch, Line 36-39 ofFeedSyncService) orvulnerabilityUpdateService.update()throwing (should log and continue to the next entity, Line 44-46). Given these are the resiliency paths this refactor is meant to preserve, dedicated tests would guard against regressions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java` around lines 39 - 70, Extend FeedSyncServiceTest with dedicated tests for the skip and error-continuation paths in feedSyncService.syncFeeds(). Verify entities with a null CVE are skipped without fetching feeds or updating, and verify an update() exception is logged while processing continues to the next vulnerability entity.backend/libs/scanning/src/main/java/dev/cleat/scanning/service/VulnerabilityUpdateService.java (1)
24-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNo dedicated unit test for
VulnerabilityUpdateService.This class contains the real business logic (field mutation, priority recalculation, persistence), but only
FeedSyncServiceTestmocks it out; no test in the provided files exercisesupdate()directly (e.g., null-epss handling, title-from-OSV branch, priority thresholds).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/VulnerabilityUpdateService.java` around lines 24 - 35, The VulnerabilityUpdateService.update method lacks direct unit coverage for its mutation, recalculation, and persistence behavior. Add focused tests for update() covering null EPSS input, the OSV-summary title update branch, and priority threshold outcomes, while verifying the updated entity is saved and the priority calculator receives the expected Vulnerability values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/VulnerabilityUpdateService.java`:
- Around line 24-35: Prevent lost updates in VulnerabilityUpdateService.update
by adding optimistic locking to VulnerabilityEntity with an appropriate `@Version`
field, or re-reading the current entity within the update transaction before
applying feed changes. Ensure concurrent modifications to unrelated
vulnerability columns are detected or preserved before
vulnerabilityRepository.save persists the update.
---
Duplicate comments:
In
`@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.java`:
- Around line 31-49: Replace the unbounded vulnerabilityRepository.findAll()
call in syncFeeds() with paginated retrieval and process one page or batch at a
time. Continue applying the existing per-entity CVE validation, feed fetching,
and vulnerabilityUpdateService.update() flow, and stop when no further pages
remain without loading the entire table into memory.
---
Nitpick comments:
In
`@backend/libs/scanning/src/main/java/dev/cleat/scanning/service/VulnerabilityUpdateService.java`:
- Around line 24-35: The VulnerabilityUpdateService.update method lacks direct
unit coverage for its mutation, recalculation, and persistence behavior. Add
focused tests for update() covering null EPSS input, the OSV-summary title
update branch, and priority threshold outcomes, while verifying the updated
entity is saved and the priority calculator receives the expected Vulnerability
values.
In
`@backend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java`:
- Around line 39-70: Extend FeedSyncServiceTest with dedicated tests for the
skip and error-continuation paths in feedSyncService.syncFeeds(). Verify
entities with a null CVE are skipped without fetching feeds or updating, and
verify an update() exception is logged while processing continues to the next
vulnerability entity.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c6d89357-e0fe-4dd8-8397-878c9f4c9d91
📒 Files selected for processing (3)
backend/libs/scanning/src/main/java/dev/cleat/scanning/service/FeedSyncService.javabackend/libs/scanning/src/main/java/dev/cleat/scanning/service/VulnerabilityUpdateService.javabackend/libs/scanning/src/test/java/dev/cleat/scanning/FeedSyncServiceTest.java
|
Hi, @martian56 !I've addressed all of the CodeRabbit review comments and completed the requested changes.The PR now passed the CodeRabbit review.When you have time could you please take a look and review it?Thanks! |
What does this change?
This PR adds vulnerability feed enrichment and auto re-scoring
Related issue
Closes #9
Area
Screenshots
If this touches the UI, drop before and after screenshots here.
Checklist
bun run typecheck && bun run buildinapps/web(for frontend changes)Summary by CodeRabbit
New Features
Bug Fixes