Skip to content

Commit e334025

Browse files
Maffoochclaude
andcommitted
feat(vuln-id): retain legacy Vulnerability_Id model+table for a transition
Defer the destructive drop. Instead of the entity-only cutover dropping dojo_vulnerability_id in the same release, keep the legacy Vulnerability_Id model and table for a transition period and remove them together in a future release, once the entity store has proven itself in production. - Restore the Vulnerability_Id model (unused: no code path reads or writes it; entity references are the source of truth) + its dojo.models re-export. - Delete migration 0288 (no drop, no SeparateDatabaseAndState state/DB split, which complicated other tooling). The model stays in Django state, matching code — makemigrations --check + manage.py check are clean. - The physical DROP TABLE moves to a future release; guard it there with the invariant (abort if legacy has rows while the reference table is empty). Validated: fresh migrate from zero through 0287 keeps both table sets; merge, search, and vulnerability-id suites green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d59681b commit e334025

5 files changed

Lines changed: 46 additions & 54 deletions

File tree

dojo/db_migrations/0288_delete_vulnerability_id.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

dojo/finding/models.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
from dojo.base_models.base import BaseModel
2727
from dojo.finding.cwe import cwe_label, finding_cwe_labels
28+
from dojo.finding.vulnerability_id import resolve_vulnerability_id_type
2829

2930
# get_current_date/tomorrow/copy_model_util are defined early in dojo.models, before the
3031
# re-export that loads this module — so this resolves despite the partial circular load, and
@@ -1438,9 +1439,44 @@ def set_hash_code(self, dedupe_option):
14381439
deduplicationLogger.debug("Hash_code computed for finding: %s: %s", finding_id, self.hash_code)
14391440

14401441

1441-
# The legacy Vulnerability_Id model was removed in the entity-only cutover; vulnerability ids now
1442-
# live in the Vulnerability entity + FindingVulnerabilityReference through-table (dojo/vulnerability/).
1443-
# The dojo_vulnerability_id table is dropped by migration 0287.
1442+
# Legacy vulnerability-id store. As of the entity-only cutover, vulnerability ids live in the
1443+
# Vulnerability entity + FindingVulnerabilityReference through-table (dojo/vulnerability/), and this
1444+
# model is NO LONGER READ OR WRITTEN by any code path. It (and its dojo_vulnerability_id table) are
1445+
# intentionally RETAINED for a transition period as a frozen pre-cutover snapshot, and removed
1446+
# together in a future release. Do not add new usages.
1447+
class Vulnerability_Id(models.Model):
1448+
finding = models.ForeignKey("dojo.Finding", editable=False, on_delete=models.CASCADE)
1449+
vulnerability_id = models.TextField(max_length=50, blank=False, null=False)
1450+
# Autodetected from the id prefix (CVE, GHSA, ...); NULL when there is no non-numeric
1451+
# prefix. Denormalized/indexed so type-scoped queries (e.g. GROUP BY type) stay cheap.
1452+
vulnerability_id_type = models.CharField(max_length=20, null=True, blank=True, editable=False, db_index=True)
1453+
1454+
class Meta:
1455+
constraints = [
1456+
models.UniqueConstraint(fields=["finding", "vulnerability_id"], name="unique_finding_vulnerability_id"),
1457+
]
1458+
indexes = [
1459+
# Leading on vulnerability_id (the unique constraint's index leads on finding), for the
1460+
# vulnerability-id Explorer's GROUP BY vulnerability_id / lookups by exact id.
1461+
models.Index(fields=["vulnerability_id"], name="dojo_vuln_id_lookup_idx"),
1462+
# Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match.
1463+
GinIndex(
1464+
SearchVector("vulnerability_id", weight="A", config="english"),
1465+
name="dojo_vulnerability_id_fts_gin",
1466+
),
1467+
GinIndex(fields=["vulnerability_id"], opclasses=["gin_trgm_ops"], name="dojo_vuln_id_trgm"),
1468+
]
1469+
1470+
def __str__(self):
1471+
return self.vulnerability_id
1472+
1473+
def save(self, *args, **kwargs):
1474+
# bulk_create paths set the type at construction; this covers save()/get_or_create.
1475+
self.vulnerability_id_type = resolve_vulnerability_id_type(self.vulnerability_id)
1476+
super().save(*args, **kwargs)
1477+
1478+
def get_absolute_url(self):
1479+
return reverse("view_finding", args=[str(self.finding.id)])
14441480

14451481

14461482
class Finding_CWE(models.Model):

dojo/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ class Meta:
405405
Finding_CWE, # noqa: F401 -- re-export
406406
Finding_Group, # noqa: F401 -- re-export
407407
Finding_Template,
408+
Vulnerability_Id, # noqa: F401 -- re-export (legacy; retained for a transition period, see model)
408409
)
409410
from dojo.vulnerability.models import ( # noqa: E402 -- re-export; FKs reference dojo.Finding / dojo.Vulnerability by string
410411
FindingVulnerabilityReference, # noqa: F401 -- re-export

dojo/vulnerability/manager.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Write seam for vulnerability ids: the ``Vulnerability`` entity + ``FindingVulnerabilityReference``
33
rows are the single source of truth. Every writer persists them through this one module.
44
5-
The legacy ``Vulnerability_Id`` store is gone: this entity-only cutover stops writing it and drops
6-
its table in the same change (migration 0288, after the 0287 backfill).
5+
The legacy ``Vulnerability_Id`` store is no longer written or read after this entity-only cutover.
6+
Its model and ``dojo_vulnerability_id`` table are retained (unused) for a transition period as a
7+
frozen pre-cutover snapshot, and removed together in a future release.
78
CWE buffering (store_cwes/pending_cwes/reconcile_cwes) is deliberately NOT owned here — it keeps
89
riding the importer flush boundary exactly as before.
910
"""

dojo/vulnerability/queries.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ def get_auth_filter(key):
1818
# ---------------------------------------------------------------------------
1919
# Read helpers over the entity/reference store — the single source of truth.
2020
# (The legacy Vulnerability_Id read path + V3_FEATURE_VULNERABILITY_IDS flag were
21-
# removed in the entity-only cutover; the legacy table is dropped by migration 0288
22-
# in the same change, after the 0287 backfill.)
21+
# removed in the entity-only cutover; the legacy Vulnerability_Id model + table are
22+
# retained unused for a transition period after the 0287 backfill and removed
23+
# together in a future release.)
2324
# ---------------------------------------------------------------------------
2425

2526

0 commit comments

Comments
 (0)