Objective
- Stop false-failed PriorityLab / Breeze appointment syncs when the vendor returns success-shaped JSON but no usable property identifier for Attik to persist.
- Reduce confusion for ops and support: work orders can still show a PriorityLab property ID from an earlier sync while
priorityLab.lastErrorreports a failure—behavior should be understandable or self-healing where product agrees. - Improve observability so engineering can tell vendor contract drift from transient responses without guessing.
Background
- Sync uses PriorityLab
CreateUpdateAppointment(json: true). Attik treats a top-level or nestedresponse.confirmationstring as the property id returned by the vendor. - After JSON parse, if there is no PriorityLab
errorspayload to throw on, butconfirmationis missing or not a string, the client raisesPriorityLabError: messageMissing confirmation in PriorityLab response, codemissing_confirmation, retryable. syncPriorityLabAppointmentonly persists_priorityLabPropertyIdaftercreateOrUpdateAppointmentreturns a property id; on failure it recordspriorityLab.lastErrorand does not clear an existing stored id—so the Integrations tab can still show a property id from a prior successful run while the latest attempt failed.- Root cause for a given failure is not determined in code alone: the vendor may omit
confirmation, return a different shape, or use a non-string value; Decision needed whether to widen parsing, treat no-op updates differently, or escalate to PriorityLab with captured payloads.
Scope
Backend
attik-backend/src/util/functions/priorityLab/priorityLabApi.ts—parseVendorResponse,createOrUpdateAppointment, andPriorityLabErrorconstruction; todayconfirmationmust be a string or the error fires.attik-backend/src/util/functions/priorityLab/syncPriorityLabAppointment.ts— upsert path callscreateOrUpdateAppointmentviatryUpsert; success clearslastErrorand writes_priorityLabPropertyId; failure recordslastErroronly.attik-backend/src/util/functions/priorityLab/buildPriorityLabPayload.ts— payload sent on create vs update (existingpropertyIdpassed through when present); relevant if product wants idempotent behavior when response omits confirmation.attik-backend/src/routes/inspection.ts— enqueuesqueuePriorityLabJobafter qualifying inspection saves (see import from../events/bullmq/priorityLabQueues.js).attik-backend/src/events/bullmq/priorityLabQueues.ts—priorityLabAppointmentBullMQ queue/worker wiring, retry/backoff defaults, and invocation ofsyncPriorityLabAppointment; relevant if logging or failure classification should change at the job boundary.- Decision needed: log sanitized raw response text (or structured fields) on
missing_confirmationfor support; Decision needed whether retry should differ from otherPriorityLabErrorcodes.
Product / partner
- Align with PriorityLab / Breeze on whether
confirmationis always returned on success for create and update paths, and whether alternate keys exist in production.
References
attik-backend/src/util/functions/priorityLab/priorityLabApi.tsattik-backend/src/util/functions/priorityLab/syncPriorityLabAppointment.tsattik-backend/src/util/functions/priorityLab/buildPriorityLabPayload.tsattik-backend/src/routes/inspection.tsattik-backend/src/events/bullmq/priorityLabQueues.ts