Tenant vulnerabilities are recorded on the tenant's own contact 🟩

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-06 13:31:00 +00:00
parent d4bdbf2e2f
commit 64d397e6b4
2 changed files with 22 additions and 1 deletions

View file

@ -254,7 +254,11 @@ class AbriClient:
mobile=numbers.mobile,
telephone=numbers.telephone,
secondary_number=numbers.secondary,
vulnerabilities=(),
vulnerabilities=tuple(
text
for vulnerability in element.findall("Vulnerability")
if (text := (vulnerability.text or "").strip())
),
)
@staticmethod

View file

@ -6,6 +6,22 @@ from etl.hubspot.deal_contacts_client import HubspotDealContactsClient
from infrastructure.abri.abri_client import AbriClient
def _vulnerability_description(tenant: Tenant) -> Optional[str]:
"""The tenant's distinct vulnerabilities, verbatim and newline-joined.
Case-insensitively distinct within the tenant, keeping the first-seen
casing and document order.
"""
distinct: List[str] = []
seen: set[str] = set()
for vulnerability in tenant.vulnerabilities:
if vulnerability.lower() in seen:
continue
seen.add(vulnerability.lower())
distinct.append(vulnerability)
return "\n".join(distinct) if distinct else None
def _contact_properties(tenant: Tenant) -> Dict[str, str]:
candidates: Dict[str, Optional[str]] = {
"firstname": tenant.forenames,
@ -13,6 +29,7 @@ def _contact_properties(tenant: Tenant) -> Dict[str, str]:
"mobilephone": tenant.mobile,
"phone": tenant.telephone,
"secondary_phone_number": tenant.secondary_number,
"vulnerability_description": _vulnerability_description(tenant),
}
properties = {name: value for name, value in candidates.items() if value}
# Always written, so "not vulnerable" is distinguishable from "not synced".