From a065857e48f099512a54aa0a1abcaf30e3fdea41 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Wed, 8 Jul 2026 16:06:41 +0000 Subject: [PATCH] more detailed logging --- etl/hubspot/hubspot_deal_differ.py | 92 ++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 16 deletions(-) diff --git a/etl/hubspot/hubspot_deal_differ.py b/etl/hubspot/hubspot_deal_differ.py index ac68bf642..5107fb8a6 100644 --- a/etl/hubspot/hubspot_deal_differ.py +++ b/etl/hubspot/hubspot_deal_differ.py @@ -202,22 +202,36 @@ class HubspotDealDiffer: new_deal.get("project_code"), new_project["project_id"] if new_project is not None else None, ) + amend_job = HubspotDealDiffer.check_for_abri_job_amendment( + new_deal=new_deal, new_project=new_project, old_deal=old_deal + ) + log_job = HubspotDealDiffer.check_for_abri_job_logging( + new_deal=new_deal, new_project=new_project, old_deal=old_deal + ) + sync_tenant_data = HubspotDealDiffer.check_for_abri_tenant_data_fetch( + new_deal=new_deal, new_project=new_project, old_deal=old_deal + ) + abandon_job = HubspotDealDiffer.check_for_abri_deal_abandonment( + new_deal=new_deal, new_project=new_project, old_deal=old_deal + ) + logger.info( + "Abri trigger results for HubSpot deal %s: " + "amend_job=%s log_job=%s sync_tenant_data=%s abandon_job=%s", + hubspot_deal_id, + amend_job, + log_job, + sync_tenant_data, + abandon_job, + ) + flows: List[str] = [] - if HubspotDealDiffer.check_for_abri_job_amendment( - new_deal=new_deal, new_project=new_project, old_deal=old_deal - ): + if amend_job: flows.append("amend_job") - if HubspotDealDiffer.check_for_abri_job_logging( - new_deal=new_deal, new_project=new_project, old_deal=old_deal - ): + if log_job: flows.append("log_job") - if HubspotDealDiffer.check_for_abri_tenant_data_fetch( - new_deal=new_deal, new_project=new_project, old_deal=old_deal - ): + if sync_tenant_data: flows.append("sync_tenant_data") - if HubspotDealDiffer.check_for_abri_deal_abandonment( - new_deal=new_deal, new_project=new_project, old_deal=old_deal - ): + if abandon_job: flows.append("abandon_job") if not flows: @@ -233,7 +247,7 @@ class HubspotDealDiffer: confirmed_survey_date = parse_hs_date(new_deal.get("confirmed_survey_date")) last_submission_date = parse_hs_date(new_deal.get("last_submission_date")) listing = new_listing or {} - return { + message: Dict[str, Any] = { "hubspot_deal_id": hubspot_deal_id, "flows": flows, "place_ref": listing.get("owner_property_id"), @@ -255,6 +269,12 @@ class HubspotDealDiffer: # the other flows, which ignore it. "outcome": new_deal.get("outcome"), } + logger.info( + "Constructed Abri message for HubSpot deal %s: %s", + hubspot_deal_id, + message, + ) + return message @staticmethod def check_for_abri_job_logging( @@ -288,6 +308,18 @@ class HubspotDealDiffer: if not HubspotDealDiffer._is_abri_condition_deal(new_deal, new_project): return False + new_survey_date = parse_hs_date(new_deal.get("confirmed_survey_date")) + new_survey_time = new_deal.get("confirmed_survey_time") + logger.info( + "Abri job-amendment check: " + "old_confirmed_survey_date=%s new_confirmed_survey_date=%s " + "old_confirmed_survey_time=%s new_confirmed_survey_time=%s", + old_deal.confirmed_survey_date, + new_survey_date, + old_deal.confirmed_survey_time, + new_survey_time, + ) + # A first-time survey date logs a new job, not an amendment. if old_deal.confirmed_survey_date is None: return False @@ -296,11 +328,10 @@ class HubspotDealDiffer: # check, but the amendoptiappt route cannot express a cancellation. # Cancellation semantics (the "delete" action / canceljob route) need # a deliberate decision before this trigger is wired to a consumer. - new_survey_date = parse_hs_date(new_deal.get("confirmed_survey_date")) if old_deal.confirmed_survey_date != new_survey_date: return True - return old_deal.confirmed_survey_time != new_deal.get("confirmed_survey_time") + return old_deal.confirmed_survey_time != new_survey_time @staticmethod def check_for_abri_tenant_data_fetch( @@ -336,6 +367,19 @@ class HubspotDealDiffer: if not HubspotDealDiffer._is_abri_condition_deal(new_deal, new_project): return False + logger.info( + "Abri deal-abandonment check: " + "old_number_of_attempts=%s old_outcome=%r " + "new_number_of_attempts=%s new_outcome=%r " + "attempts_threshold=%s", + old_deal.number_of_attempts, + old_deal.outcome, + new_deal.get("number_of_attempts"), + new_deal.get("outcome"), + HubspotDealDiffer.ABANDONMENT_ATTEMPTS_THRESHOLD, + ) + + # Already abandoned before this change — nothing new to fire. if HubspotDealDiffer._is_abandoned( old_deal.number_of_attempts, old_deal.outcome ): @@ -362,9 +406,25 @@ class HubspotDealDiffer: attempts is None or attempts < HubspotDealDiffer.ABANDONMENT_ATTEMPTS_THRESHOLD ): + logger.info( + "Abri _is_abandoned=False (attempts gate): " + "raw_attempts=%r parsed_attempts=%s threshold=%s", + number_of_attempts, + attempts, + HubspotDealDiffer.ABANDONMENT_ATTEMPTS_THRESHOLD, + ) return False - return (outcome or "").lower() in UNSUCCESSFUL_OUTCOMES + outcome_is_unsuccessful = (outcome or "").lower() in UNSUCCESSFUL_OUTCOMES + logger.info( + "Abri _is_abandoned=%s (outcome gate): " + "parsed_attempts=%s outcome=%r outcome_is_unsuccessful=%s", + outcome_is_unsuccessful, + attempts, + outcome, + outcome_is_unsuccessful, + ) + return outcome_is_unsuccessful @staticmethod def _is_abri_condition_deal(