Skip to content

feat(core-api,console): add new vulnerability notifications - #541

Merged
l1ttps merged 4 commits into
mainfrom
feat/new-vul-detect-notification
Jul 15, 2026
Merged

feat(core-api,console): add new vulnerability notifications#541
l1ttps merged 4 commits into
mainfrom
feat/new-vul-detect-notification

Conversation

@l1ttps

@l1ttps l1ttps commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added integration editing with schema-driven fields (including toggles, arrays, and secure handling for sensitive values), with Cancel/Save and validation.
    • Introduced PATCH /integrations/:id to update integration name, description, and configuration.
    • Added notifications for newly found vulnerabilities (including counts) targeting the affected asset.
  • Bug Fixes
    • Updated vulnerability alerting to prevent duplicate notifications by notifying only for truly newly discovered vulnerabilities.
  • Documentation
    • Updated notification wording and routing for the new “new vulnerabilities found” event.

l1ttps added 2 commits July 14, 2026 14:16
…point

Add PATCH /integrations/:id endpoint for updating name, description, or config with JSON Schema validation and field encryption. Implement inline edit mode in integration detail sheet with dynamic form fields (text, password, boolean, array, textarea) and save/cancel flow.
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f59fc922-5e91-453f-929a-ab813ca1b155

📥 Commits

Reviewing files that changed from the base of the PR and between 8674322 and 6578b7e.

📒 Files selected for processing (1)
  • core-api/src/modules/data-adapter/data-adapter.service.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • core-api/src/modules/data-adapter/data-adapter.service.ts

📝 Walkthrough

Walkthrough

Integration configurations can now be edited through schema-driven controls and persisted through a workspace-scoped PATCH API. Vulnerability processing now sends localized group notifications for newly discovered vulnerabilities.

Changes

Integration update workflow

Layer / File(s) Summary
Integration update API contract and persistence
core-api/src/modules/integrations/dto/update-integration.dto.ts, core-api/src/modules/integrations/integrations.controller.ts, core-api/src/modules/integrations/integrations.service.ts
Adds validated integration updates for name, description, and configuration, including configuration validation and sensitive-field encryption.
Schema-driven integration editing
console/src/pages/integrations/components/integration-detail-sheet.tsx
Adds schema-based controls, array inputs, form state, save/cancel handling, mutation feedback, and conditional edit/view controls.

Vulnerability notifications

Layer / File(s) Summary
Notification type and routing contracts
core-api/src/common/enums/enum.ts, core-api/src/i18n/en/notification.json, core-api/src/i18n/routers/notification.json
Adds the new vulnerability notification type, localized message, and target route.
Vulnerability notification dispatch
core-api/src/modules/data-adapter/data-adapter.service.ts, core-api/src/modules/data-adapter/data-adapter.service.spec.ts
Identifies newly discovered vulnerabilities, resolves workspace recipients, creates group notifications, and tests the notification paths.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant IntegrationDetailSheet
  participant IntegrationsController
  participant IntegrationsService
  User->>IntegrationDetailSheet: Edit integration fields
  IntegrationDetailSheet->>IntegrationsController: PATCH integration
  IntegrationsController->>IntegrationsService: Validate and save update
  IntegrationsService-->>IntegrationDetailSheet: Updated integration
  IntegrationDetailSheet-->>User: Show success and view mode
Loading
sequenceDiagram
  participant DataAdapterService
  participant WorkspacesService
  participant NotificationsService
  participant NotificationRouter
  DataAdapterService->>WorkspacesService: Resolve job workspace members
  WorkspacesService-->>DataAdapterService: Return recipients
  DataAdapterService->>NotificationsService: Create vulnerability notification
  NotificationsService->>NotificationRouter: Resolve target route
Loading

Possibly related PRs

  • oasm-platform/open-asm#522: Modifies the same integration detail sheet’s configuration rendering, grouping, and editing/test flows.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main backend change adding new vulnerability notifications, though it omits the unrelated console integration editor work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/new-vul-detect-notification

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
core-api/src/modules/data-adapter/data-adapter.service.spec.ts (1)

63-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exercise the new notification branch.

The empty-members default bypasses all new behavior. Add a test with workspace members asserting recipients, scope, type, metadata, and workspace ID, plus a repeat-scan test ensuring existing vulnerabilities are not announced again.

Also applies to: 96-101

🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.spec.ts` at line 63,
Extend the data-adapter service tests around getMemberOfWorkspaceByJobId to
return workspace members and exercise the notification path, asserting
recipients, scope, type, metadata, and workspace ID; add a repeat-scan case
confirming existing vulnerabilities are not notified again. Retain the
empty-members coverage separately.
core-api/src/modules/data-adapter/data-adapter.service.ts (1)

8-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use core-api alias imports consistently.

  • core-api/src/modules/data-adapter/data-adapter.service.ts#L8-L13: import enums from @/common/enums/enum.
  • core-api/src/modules/data-adapter/data-adapter.service.ts#L20-L20: import NotificationsService through @/modules/....
  • core-api/src/modules/data-adapter/data-adapter.service.spec.ts#L11-L11: use the same alias for the test import.

As per coding guidelines, “Use @/ alias for imports in core-api.”

🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.ts` around lines 8 -
13, Replace the relative enum import in data-adapter.service.ts (lines 8-13)
with the `@/common/enums/enum` alias, and update the NotificationsService import
in data-adapter.service.ts (line 20) to use the `@/modules/`... alias. Apply the
same alias convention to the test import in data-adapter.service.spec.ts (line
11).

Source: Coding guidelines

core-api/src/modules/integrations/integrations.controller.ts (1)

27-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required core-api import alias.

  • core-api/src/modules/integrations/integrations.controller.ts#L27-L27: import the DTO from @/modules/integrations/dto/update-integration.dto.
  • core-api/src/modules/integrations/integrations.service.ts#L20-L20: use the same aliased path for the type import.

As per coding guidelines, “Use @/ alias for imports in core-api (maps to src/ directory).”

🤖 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 `@core-api/src/modules/integrations/integrations.controller.ts` at line 27,
Replace the relative UpdateIntegrationDto import in integrations.controller.ts
with the `@/modules/integrations/dto/update-integration.dto` alias, and apply the
same aliased type import in integrations.service.ts.

Source: Coding guidelines

🤖 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 `@console/src/pages/integrations/components/integration-detail-sheet.tsx`:
- Around line 253-258: Update the default-value initialization around
SchemaProperty so missing array fields are not assigned ['']; only materialize
explicitly defined defaults, and let ArrayField render an empty row without
mutating values. Preserve initialization behavior for non-array properties and
arrays with a declared default.
- Around line 189-199: Update the numeric-field branch in the integration detail
component so existing number and integer values are rendered instead of blank,
while converting edited input values back to numbers before invoking onChange.
Preserve empty input handling appropriately and ensure the resulting value
satisfies number/integer schema validation.

In `@core-api/src/modules/data-adapter/data-adapter.service.ts`:
- Around line 292-302: Move the createNotification call out of the database
transaction in the surrounding data-adapter flow, ensuring the vulnerability
transaction commits before enqueueing the notification. Preserve the existing
notification payload and workspace scope, and make the post-commit enqueue
idempotent or route it through the established transactional-outbox mechanism.
- Around line 283-295: Update the vulnerability persistence flow that builds
vulsForAlert to distinguish rows inserted by the scan from rows returned after
an ON CONFLICT update, excluding conflict-updated vulnerabilities before
notification recipients are constructed in the workspace notification block.
Preserve alerts for genuinely new fingerprints, and add a regression test
covering a repeat scan that verifies NEW_VULNERABILITY_FOUND is not sent again.

In `@core-api/src/modules/integrations/integrations.service.ts`:
- Around line 236-244: Preserve existing sensitive credentials when updating
integration configuration: in integrations.service.ts (236-244), merge masked or
omitted secret fields from the decrypted stored config before
validateConfigOrThrow and encryptSensitiveConfigFields. In
integration-detail-sheet.tsx (249-251), prevent masked placeholders from being
treated as editable secret values; at (351-356), omit unchanged secret fields or
use the explicit unchanged-secret contract when submitting.

---

Nitpick comments:
In `@core-api/src/modules/data-adapter/data-adapter.service.spec.ts`:
- Line 63: Extend the data-adapter service tests around
getMemberOfWorkspaceByJobId to return workspace members and exercise the
notification path, asserting recipients, scope, type, metadata, and workspace
ID; add a repeat-scan case confirming existing vulnerabilities are not notified
again. Retain the empty-members coverage separately.

In `@core-api/src/modules/data-adapter/data-adapter.service.ts`:
- Around line 8-13: Replace the relative enum import in data-adapter.service.ts
(lines 8-13) with the `@/common/enums/enum` alias, and update the
NotificationsService import in data-adapter.service.ts (line 20) to use the
`@/modules/`... alias. Apply the same alias convention to the test import in
data-adapter.service.spec.ts (line 11).

In `@core-api/src/modules/integrations/integrations.controller.ts`:
- Line 27: Replace the relative UpdateIntegrationDto import in
integrations.controller.ts with the
`@/modules/integrations/dto/update-integration.dto` alias, and apply the same
aliased type import in integrations.service.ts.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 35f5ea5b-b16a-44f5-be0e-11119538ddda

📥 Commits

Reviewing files that changed from the base of the PR and between ca26528 and 12cf792.

⛔ Files ignored due to path filters (1)
  • console/src/services/apis/gen/queries.ts is excluded by !**/gen/**
📒 Files selected for processing (9)
  • console/src/pages/integrations/components/integration-detail-sheet.tsx
  • core-api/src/common/enums/enum.ts
  • core-api/src/i18n/en/notification.json
  • core-api/src/i18n/routers/notification.json
  • core-api/src/modules/data-adapter/data-adapter.service.spec.ts
  • core-api/src/modules/data-adapter/data-adapter.service.ts
  • core-api/src/modules/integrations/dto/update-integration.dto.ts
  • core-api/src/modules/integrations/integrations.controller.ts
  • core-api/src/modules/integrations/integrations.service.ts

Comment on lines +189 to +199
if (prop.type === 'number' || prop.type === 'integer') {
return (
<Input
type="number"
name={key}
id={key}
autoComplete={autoComplete}
placeholder={placeholder}
value={typeof value === 'string' ? value : ''}
onChange={(e) => onChange(e.target.value)}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep numeric fields numeric.

Existing numbers render blank, while edited values become strings and fail number/integer schema validation.

Proposed fix
-        value={typeof value === 'string' ? value : ''}
-        onChange={(e) => onChange(e.target.value)}
+        value={
+          typeof value === 'number' || typeof value === 'string' ? value : ''
+        }
+        onChange={(e) => {
+          const rawValue = e.target.value;
+          onChange(rawValue === '' ? '' : Number(rawValue));
+        }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (prop.type === 'number' || prop.type === 'integer') {
return (
<Input
type="number"
name={key}
id={key}
autoComplete={autoComplete}
placeholder={placeholder}
value={typeof value === 'string' ? value : ''}
onChange={(e) => onChange(e.target.value)}
/>
if (prop.type === 'number' || prop.type === 'integer') {
return (
<Input
type="number"
name={key}
id={key}
autoComplete={autoComplete}
placeholder={placeholder}
value={
typeof value === 'number' || typeof value === 'string' ? value : ''
}
onChange={(e) => {
const rawValue = e.target.value;
onChange(rawValue === '' ? '' : Number(rawValue));
}}
/>
🤖 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 `@console/src/pages/integrations/components/integration-detail-sheet.tsx`
around lines 189 - 199, Update the numeric-field branch in the integration
detail component so existing number and integer values are rendered instead of
blank, while converting edited input values back to numbers before invoking
onChange. Preserve empty input handling appropriately and ensure the resulting
value satisfies number/integer schema validation.

Comment on lines +253 to +258
const typedProp = prop as SchemaProperty;
if (typedProp.default !== undefined) {
values[key] = typedProp.default;
} else if (typedProp.type === 'array') {
values[key] = [''];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not materialize absent arrays as [''].

Entering edit mode mutates every missing array field, so an unrelated save can persist a blank entry or fail schema validation. ArrayField already renders an empty row without storing it.

Proposed fix
           if (typedProp.default !== undefined) {
             values[key] = typedProp.default;
-          } else if (typedProp.type === 'array') {
-            values[key] = [''];
           }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const typedProp = prop as SchemaProperty;
if (typedProp.default !== undefined) {
values[key] = typedProp.default;
} else if (typedProp.type === 'array') {
values[key] = [''];
}
const typedProp = prop as SchemaProperty;
if (typedProp.default !== undefined) {
values[key] = typedProp.default;
}
🤖 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 `@console/src/pages/integrations/components/integration-detail-sheet.tsx`
around lines 253 - 258, Update the default-value initialization around
SchemaProperty so missing array fields are not assigned ['']; only materialize
explicitly defined defaults, and let ArrayField render an empty row without
mutating values. Preserve initialization behavior for non-array properties and
arrays with a declared default.

Comment thread core-api/src/modules/data-adapter/data-adapter.service.ts
Comment on lines +292 to +302
await this.notificationsService.createNotification({
recipients: recipientIds,
scope: NotificationScope.GROUP,
type: NotificationType.NEW_VULNERABILITY_FOUND,
metadata: {
count: String(vulsForAlert.length),
assetValue: job.asset.value,
targetId: job.asset.target.id,
},
workspaceId,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the file and inspect the relevant section with line numbers.
sed -n '240,340p' core-api/src/modules/data-adapter/data-adapter.service.ts

# Find the notification service implementation and its persistence/queue behavior.
rg -n "class .*NotificationsService|createNotification\(" core-api/src -g '*.ts'

Repository: oasm-platform/open-asm

Length of output: 3580


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== data-adapter.service.ts around transaction wrapper =="
sed -n '220,320p' core-api/src/modules/data-adapter/data-adapter.service.ts

echo
echo "== notifications.service.ts =="
sed -n '1,220p' core-api/src/modules/notifications/notifications.service.ts

echo
echo "== vulnerability-analysis.processor.ts =="
sed -n '1,120p' core-api/src/modules/vulnerabilities/processors/vulnerability-analysis.processor.ts

Repository: oasm-platform/open-asm

Length of output: 8254


Move notification enqueueing out of the transaction
createNotification() enqueues a separate BullMQ job before the DB transaction commits. If the commit fails, users can get a notification for rolled-back vulnerabilities; if the queue add fails, the whole transaction is aborted. Commit first, then enqueue idempotently, or use a transactional outbox.

🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.ts` around lines 292 -
302, Move the createNotification call out of the database transaction in the
surrounding data-adapter flow, ensuring the vulnerability transaction commits
before enqueueing the notification. Preserve the existing notification payload
and workspace scope, and make the post-commit enqueue idempotent or route it
through the established transactional-outbox mechanism.

Comment on lines +236 to +244
if (dto.config !== undefined) {
validateConfigOrThrow({
appType: integration.appType,
category: integration.category,
config: dto.config,
});

integration.config = encryptSensitiveConfigFields(dto.config);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Preserve existing secrets when saving masked configuration.

Responses contain masked sensitive values, but the console submits those placeholders as the complete config and the service encrypts them as replacements. Any ordinary edit therefore destroys unchanged credentials.

  • core-api/src/modules/integrations/integrations.service.ts#L236-L244: merge masked or omitted secret fields from the decrypted stored config before validation and encryption.
  • console/src/pages/integrations/components/integration-detail-sheet.tsx#L249-L251: do not treat masked placeholders as editable secret values.
  • console/src/pages/integrations/components/integration-detail-sheet.tsx#L351-L356: omit unchanged secret fields or use an explicit unchanged-secret contract.
📍 Affects 2 files
  • core-api/src/modules/integrations/integrations.service.ts#L236-L244 (this comment)
  • console/src/pages/integrations/components/integration-detail-sheet.tsx#L249-L251
  • console/src/pages/integrations/components/integration-detail-sheet.tsx#L351-L356
🤖 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 `@core-api/src/modules/integrations/integrations.service.ts` around lines 236 -
244, Preserve existing sensitive credentials when updating integration
configuration: in integrations.service.ts (236-244), merge masked or omitted
secret fields from the decrypted stored config before validateConfigOrThrow and
encryptSensitiveConfigFields. In integration-detail-sheet.tsx (249-251), prevent
masked placeholders from being treated as editable secret values; at (351-356),
omit unchanged secret fields or use the explicit unchanged-secret contract when
submitting.

- Add fingerprint pre-check in vulnerabilities() to skip notifications
  for existing vulns (no duplicate notifications on re-scan)
- Remove severity filter: all new vulns (critical→low) now trigger
  notification
- Add debug logging to trace notification pipeline failures
- Add tests: new vuln notification, existing vuln skip, low severity notify

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.spec.ts`:
- Around line 5-9: Update the import of NotificationType, Severity, and
ToolCategory in the data-adapter service spec to use the configured `@/` alias
mapped to core-api/src instead of the relative ../../common path.

In `@core-api/src/modules/data-adapter/data-adapter.service.ts`:
- Around line 256-270: Replace the pre-check using existingRows and
existingFingerprints with atomic classification from the vulnerability
write/upsert operation, deriving only rows actually inserted by that operation
for notification decisions. Preserve fingerprint uniqueness enforcement and
ensure concurrent scans cannot both classify the same fingerprint as new. Add a
regression test that runs concurrent scans with the same fingerprint and
verifies only one notification is produced.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3be88ee8-fbd7-4a10-a03a-6d84a12bf901

📥 Commits

Reviewing files that changed from the base of the PR and between 12cf792 and 8674322.

📒 Files selected for processing (3)
  • core-api/src/i18n/routers/notification.json
  • core-api/src/modules/data-adapter/data-adapter.service.spec.ts
  • core-api/src/modules/data-adapter/data-adapter.service.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • core-api/src/i18n/routers/notification.json

Comment on lines +5 to +9
import {
NotificationType,
Severity,
ToolCategory,
} from '../../common/enums/enum';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use the configured @/ import alias.

Proposed fix
 import {
   NotificationType,
   Severity,
   ToolCategory,
-} from '../../common/enums/enum';
+} from '`@/common/enums/enum`';

As per coding guidelines, "core-api/src/**/*.{ts,tsx}: Use @/ alias for imports in core-api (maps to src/ directory)."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
NotificationType,
Severity,
ToolCategory,
} from '../../common/enums/enum';
import {
NotificationType,
Severity,
ToolCategory,
} from '`@/common/enums/enum`';
🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.spec.ts` around lines
5 - 9, Update the import of NotificationType, Severity, and ToolCategory in the
data-adapter service spec to use the configured `@/` alias mapped to core-api/src
instead of the relative ../../common path.

Source: Coding guidelines

Comment on lines +256 to +270
// Pre-check: find which fingerprints already exist
// to avoid sending notifications for updated vulns
const existingRows = await manager
.createQueryBuilder()
.select('v.fingerprint', 'fingerprint')
.from(Vulnerability, 'v')
.where('v.fingerprint IN (:...fingerprints)', {
fingerprints: uniqueValues.map((v) => v.fingerprint),
})
.getRawMany();

const existingFingerprints = new Set<string>(
(existingRows as { fingerprint: string }[]).map((r) => r.fingerprint),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make new-vulnerability classification atomic.

Concurrent scans can both read a fingerprint as absent before either upsert completes, causing both transactions to send the same notification. Derive inserted rows atomically from the write operation and add a concurrent-scan regression test.

#!/bin/bash
# Verify database configuration and fingerprint uniqueness constraints.
rg -n -C3 \
  "type:\s*'postgres'|fingerprint|conflict_target.*fingerprint|`@Index`" \
  core-api -g '*.ts'

Also applies to: 285-292

🤖 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 `@core-api/src/modules/data-adapter/data-adapter.service.ts` around lines 256 -
270, Replace the pre-check using existingRows and existingFingerprints with
atomic classification from the vulnerability write/upsert operation, deriving
only rows actually inserted by that operation for notification decisions.
Preserve fingerprint uniqueness enforcement and ensure concurrent scans cannot
both classify the same fingerprint as new. Add a regression test that runs
concurrent scans with the same fingerprint and verifies only one notification is
produced.

@l1ttps
l1ttps merged commit a4758a2 into main Jul 15, 2026
18 checks passed
@l1ttps
l1ttps deleted the feat/new-vul-detect-notification branch July 15, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant