Objective
- Fix the inspection Integrations → HubSpot accordion so the collapsed summary accurately reflects whether a HubSpot deal is linked.
- Stop CSRs from seeing “No deal linked” when opening the panel shows a valid deal (name, stage, Deal ID) — especially on quote-converted jobs in brands such as AJF and TLC.
Background
- On the workorder integrations tab, the HubSpot row header can show “No deal linked” while the expanded body shows deal details (e.g. Inspection Completed, Deal ID
60334164530, deal nameAJF - ATK - 1008594063). - Reported examples:
- 1008594063
- 1008593282
- 1008594723
- Root cause in code: the header only checks
inspection._hubspotDealId, whileGET /hubspot/deal/:inspectionIdresolvesinspection._hubspotDealId || linkedQuote._hubspotDealId(quote where_finalInspectionIdmatches the inspection). - Common path: deal created on the quote during pending quote sync (
upsertHsDeal); inspection sync later updates that deal via the quote’s id (upsertHsDealFromInspectionpreferslinkedQuote._hubspotDealId) but only writes_hubspotDealIdonto the inspection when creating a new deal — not when updating an existing quote-linked deal. - HubSpot stage sync may be correct for these jobs; this is a display / data consistency problem, not missing HubSpot completion (see related work on published → completed sync).
Scope
Frontend
- Accordion header in
attik-frontend/src/app/tools/inspections/[id]/components/integrations/HubSpot.tsx(getHubSpotData):rightSideComponentuses onlyinspection._hubspotDealIdfor “No deal linked” vs “Deal ID: …”. - Expanded body in
HubSpotContentloadshubspot/deal/${inspectionId}only when accordion is expanded (isExpanded) — header does not use that API today. - Decision needed: Resolve deal id for the header the same way as the backend (inspection + linked quote), or show a lightweight summary from the same endpoint when integrations mount.
Backend
- Deal lookup:
attik-backend/src/routes/hubspot.ts(GET /deal/:inspectionId) —dealId = inspection._hubspotDealId || linkedQuote?._hubspotDealId. - Sync:
attik-backend/src/util/functions/hubspot/upsertHsDealFromInspection.ts—existingDealId = linkedQuote?._hubspotDealId || inspection._hubspotDealId; inspection_hubspotDealIdset on create only. - Quote deal creation:
attik-backend/src/util/functions/hubspot/upsertHsDeal.tsstores_hubspotDealIdon the quote. - Decision needed: Whether to backfill
inspection._hubspotDealIdafter successful sync when the deal id came from the linked quote (keeps header and API aligned for other consumers).
Out of scope unless expanded
- HubSpot deal stage mapping (
published→ Inspection Completed) — tracked separately. - Mold assessment multi-select fuzzy match on HubSpot deals.
References
- Example: https://www.attik.ai/inspections/1008594063?tab=integrations
- Frontend:
attik-frontend/src/app/tools/inspections/[id]/components/integrations/HubSpot.tsx - Backend deal GET:
attik-backend/src/routes/hubspot.ts - Inspection sync:
attik-backend/src/util/functions/hubspot/upsertHsDealFromInspection.ts