The deal row names the job number client_booking_reference, matching HubSpot and the schema 🟪

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-07 12:43:40 +00:00
parent 5286e2a2a2
commit a3985389ab
8 changed files with 39 additions and 35 deletions

View file

@ -2,7 +2,7 @@ import uuid
from sqlmodel import SQLModel, Field, Column, text
from datetime import datetime
from typing import Optional
from sqlalchemy import DateTime, String
from sqlalchemy import DateTime
from sqlalchemy.sql import func
@ -71,13 +71,10 @@ class HubspotDealData(SQLModel, table=True):
confirmed_survey_time: Optional[str] = Field(default=None)
surveyed_date: Optional[datetime] = Field(default=None)
design_type: Optional[str] = Field(default=None)
# OpenHousing job number; stored under the same name as the HubSpot
# property that carries it (client_booking_reference) — the column is
# created by the frontend repo's drizzle migration. Only the domain
# calls it job_no.
job_no: Optional[str] = Field(
default=None, sa_column=Column("client_booking_reference", String)
)
# The OpenHousing job number, named after the HubSpot property that
# carries it (matching the column the frontend repo's drizzle migration
# created). Only the domain calls it job_no.
client_booking_reference: Optional[str] = Field(default=None)
survey_type: Optional[str] = Field(default=None)
measures_for_pibi_ordered: Optional[str] = Field(default=None)

View file

@ -274,7 +274,7 @@ class HubspotDataToDb:
deal_data.get("confirmed_survey_date")
),
"confirmed_survey_time": deal_data.get("confirmed_survey_time"),
"job_no": deal_data.get("client_booking_reference"),
"client_booking_reference": deal_data.get("client_booking_reference"),
"surveyed_date": parse_hs_date(deal_data.get("surveyed_date")),
"design_type": deal_data.get("design_type"),
"survey_type": deal_data.get("survey_type"),
@ -383,7 +383,7 @@ class HubspotDataToDb:
surveyor=deal_data.get("surveyor"),
confirmed_survey_date=parse_hs_date(deal_data.get("confirmed_survey_date")),
confirmed_survey_time=deal_data.get("confirmed_survey_time"),
job_no=deal_data.get("client_booking_reference"),
client_booking_reference=deal_data.get("client_booking_reference"),
surveyed_date=parse_hs_date(deal_data.get("surveyed_date")),
design_type=deal_data.get("design_type"),
survey_type=deal_data.get("survey_type"),

View file

@ -103,7 +103,7 @@ class HubspotDealDiffer:
"design_type": "design_type",
"surveyor": "surveyor",
"confirmed_survey_time": "confirmed_survey_time",
"client_booking_reference": "job_no",
"client_booking_reference": "client_booking_reference",
"survey_type": "survey_type",
"measures_for_pibi_ordered": "measures_for_pibi_ordered",
"property_halted_reason": "property_halted_reason",

View file

@ -88,7 +88,7 @@ def test_update_existing_deal__no_project__clears_project_id() -> None:
def test_update_existing_deal__client_booking_reference_maps_to_job_no() -> None:
existing = HubspotDealData(deal_id="MOCK_DEAL_ID", job_no=None)
existing = HubspotDealData(deal_id="MOCK_DEAL_ID", client_booking_reference=None)
deal_data = {"client_booking_reference": "AD0226519"}
_make_instance()._update_existing_deal(
@ -98,11 +98,13 @@ def test_update_existing_deal__client_booking_reference_maps_to_job_no() -> None
company=None,
)
assert existing.job_no == "AD0226519"
assert existing.client_booking_reference == "AD0226519"
def test_update_existing_deal__client_booking_reference_cleared__nulls_job_no() -> None:
existing = HubspotDealData(deal_id="MOCK_DEAL_ID", job_no="AD0226519")
existing = HubspotDealData(
deal_id="MOCK_DEAL_ID", client_booking_reference="AD0226519"
)
deal_data = {}
_make_instance()._update_existing_deal(
@ -112,7 +114,7 @@ def test_update_existing_deal__client_booking_reference_cleared__nulls_job_no()
company=None,
)
assert existing.job_no is None
assert existing.client_booking_reference is None
def test_build_new_deal__client_booking_reference_maps_to_job_no() -> None:
@ -124,4 +126,4 @@ def test_build_new_deal__client_booking_reference_maps_to_job_no() -> None:
project=None,
)
assert new_deal.job_no == "AD0226519"
assert new_deal.client_booking_reference == "AD0226519"

View file

@ -1267,7 +1267,7 @@ def test_db_update_trigger__client_booking_reference_changed__returns_true() ->
# Arrange
old_deal = make_old_deal(
id=deal_id,
job_no=None,
client_booking_reference=None,
)
new_deal = make_new_deal(
deal_id,
@ -1293,7 +1293,7 @@ def test_db_update_trigger__client_booking_reference_unchanged__returns_false()
# Arrange
old_deal = make_old_deal(
id=deal_id,
job_no="AD0226519",
client_booking_reference="AD0226519",
)
new_deal = make_new_deal(
deal_id,

View file

@ -21,13 +21,13 @@ class DealDatabasePostgresGateway:
deal = self._find_deal(deal_id)
if deal is None:
raise ValueError(f"HubSpot deal {deal_id} not found")
deal.job_no = job_no
deal.client_booking_reference = job_no
self._session.add(deal)
self._session.commit()
def job_no_for_deal(self, deal_id: str) -> Optional[str]:
deal = self._find_deal(deal_id)
return deal.job_no if deal is not None else None
return deal.client_booking_reference if deal is not None else None
def _find_deal(self, deal_id: str) -> Optional[HubspotDealData]:
statement = select(HubspotDealData).where(HubspotDealData.deal_id == deal_id)

View file

@ -10,8 +10,8 @@ canned LogJob success carrying a fake job_no. Concretely, the script
3. runs the real differ predicates via build_abri_trigger_message,
4. validates the real message contract (AbriTriggerRequest),
5. runs the real dispatch through the real AbriOrchestrator, so the fake
job_no is written to the deal's client_booking_reference in HubSpot
first, then to the job_no column in the database,
job_no is written to the deal's client_booking_reference property in
HubSpot first, then to the same-named column in the database,
6. reads both back and prints them.
NOTE: the LogJob trigger fires when the CONFIRMED SURVEY DATE is first set
@ -164,7 +164,7 @@ def main() -> None:
deal_properties.write_deal_property(
deal_id=DEAL_ID, property_name=JOB_NO_DEAL_PROPERTY, value=""
)
deal_row.job_no = None
deal_row.client_booking_reference = None
session.add(deal_row)
session.commit()
print(
@ -175,15 +175,16 @@ def main() -> None:
if RESET_DB_ROW_FIRST:
deal_row.confirmed_survey_date = None
deal_row.job_no = None
deal_row.client_booking_reference = None
session.add(deal_row)
session.commit()
session.refresh(deal_row)
print("Reset DB row: confirmed_survey_date and job_no nulled.")
print(f"Fetching deal {DEAL_ID} from HubSpot...")
hubspot_deal, _company, listing, project = HubspotClient(
).get_deal_and_company_and_listing_and_project(DEAL_ID)
hubspot_deal, _company, listing, project = (
HubspotClient().get_deal_and_company_and_listing_and_project(DEAL_ID)
)
print(
f" dealname={hubspot_deal.get('dealname')!r} "
f"project_code={hubspot_deal.get('project_code')!r} "
@ -192,7 +193,7 @@ def main() -> None:
)
print(
f" DB row: confirmed_survey_date={deal_row.confirmed_survey_date} "
f"job_no={deal_row.job_no}"
f"job_no={deal_row.client_booking_reference}"
)
message = build_abri_trigger_message(

View file

@ -36,7 +36,7 @@ def test_record_job_no_persists_the_job_no_on_the_deal_row(session: Session) ->
# Assert
session.refresh(deal)
assert deal.job_no == "AD0226519"
assert deal.client_booking_reference == "AD0226519"
def test_record_job_no_for_an_unknown_deal_raises(session: Session) -> None:
@ -63,13 +63,17 @@ def test_the_job_no_is_stored_in_the_client_booking_reference_column(
gateway.record_job_no(deal_id=DEAL_ID, job_no="AD0226519")
# Assert
stored = session.connection().execute(
text(
"select client_booking_reference from hubspot_deal_data "
"where deal_id = :deal_id"
),
{"deal_id": DEAL_ID},
).one()
stored = (
session.connection()
.execute(
text(
"select client_booking_reference from hubspot_deal_data "
"where deal_id = :deal_id"
),
{"deal_id": DEAL_ID},
)
.one()
)
assert stored[0] == "AD0226519"