Skip to content

Code Reference — jbw-sam

High-level, per-Lambda guide.

All paths relative to st-integration/jbw-sam/. Function names deploy as ${Environment}_<logicalId> (e.g. prod_jbwalldealerlist).

Every Node function carries its own copy of util/index.js (canonical copy at src/util/index.js) exporting:

  • sendResponse(statusCode, body) — CORS JSON response wrapper
  • validateInput(...) — request validation
  • mysqlConnection() — mysql2 connection through RDS Proxy using an IAM auth token (AWS.RDS.Signer, mysql_clear_password plugin, ssl.rejectUnauthorized=false)
  • some functions also use mySqlCon — promise-based, transaction-capable variant

Most handlers are thin: validate input → run SQL against the jbwst schema → sendResponse. SQL is largely string-interpolated (see caveats in the module doc).

Complete method + path → function map from template.yaml (each cell: endpoint, then its Lambda):

MethodRoute / FunctionNotes
GET/dealer
jbwalldealerlist
dealer search/list (?key=&type=)
PATCH/dealer/{id}
jbwdealerstatusregisterupdate
dealer status update
GET/dealer/{id}/verify
jbwdealerverification
dealer existence check
GET/dealer/{id}/onboard
jbwonboarddetails
onboarding record
GET/dealer/{id}/cardsdata
jbwdealerdetailscardsdata
dealer dashboard KPIs
GET/dealer/{id}/gettenantinfo
getTenantInfo
reads Active tenants (tblTenant+tblTransmissionDetails) and enqueues one SQS message per tenant to JBWSQSURL — the trigger hand-off to the extraction Lambda
GET/dealer/{id}/transmissiondetails
jbwtransmissiondetailsbydealer
latest sync audit
GET/dealer/{id}/transmissiondetailshistory
jbwtransmissiondetailshistorybydealer
sync audit history
GET/dealer/nononboardedlist
jbwnononboardeddealerlist
dealers not yet onboarded
GET/dealer/latestonboardeddealers
jbwgetfivelatestdealeronboardlist
admin dashboard widget
POST/newdealeronboard
jbwnewonboarding
persists onboarding, then invokes jbwagreementsdatamatch for the initial sync
GET/dealeronboard
jbwdealeronboardedlist
onboarded dealer list
POST/dealerregister/add
jbwdealerregistercreate
registration record
GET/dealerregister
jbwdealerregistrationlist
registration list
GET/dealerregister/{id}/dealerverify
jbwdealerregistrationverify
(timeout 900 s)
PUT/dealerregister/userstatus
jbwuseractivestatus
Cognito enable/disable + SES; invokes jbwdealerregistrationsetactivestatus
PATCH/dealerregister/{id}/updatereleasenotestatus
jbwupdatereleasenotesstatus
release-notes seen flag
POST/signup
jbwusersignup
Cognito signup; invokes jbwdealerregistercreate + jbwemailservice
POST/changepassword
jbwchangePassword
Cognito + SES
POST/resetpassword
jbwuserresetpassword
Cognito + SES; invokes jbwdealerregistrationuserverify
GET/tenant/{tenantid}
jbwtenantidverification
tenant check
PATCH/tenant/{tenantid}
jbwtenantclientidupdate
update ST creds for tenant
GET/tenant/dealer/{dealerid}
jbwtenantslistbydealer
tenants per dealer
POST/jbwservicetitan
JBWClientServiceTitanVerification
verifies ST OAuth creds; optionally checks required tag-types, job custom fields, location custom fields exist (see below)
GET/workiz/accountverify
jbwworkizaccountverify
verifies Workiz account via job/all/
GET/agreements/dealer/{dealerid}
jbwdealeragreementlist
agreement grid
GET/agreements/{id}/equipments
jbwagreementequipmentsbyagreementid
equipment rows
POST/agreements/{id}/equipments
jbwagreementequipmentadd
add equipment
PATCH/agreements/{id}/equipments
jbwdeleteagreementbyid
⚠ route collides with add/get; part of the mis-indented template block
PUT/agreements/{id}/equipmentsync
jbwservicetitansagreementspull
creates the agreement in JBW: builds payload from tblAgreement/tblAgreementEquipments/tblBusinessUnit (max 5 equipments), POSTs to JBW_AGREEMENTS_URL, writes back jbwAgreementId/pdfUrl/warranty dates/status SAVED; handles renewals
GET/agreements/{id}/agreementdetails
jbwagreementwithequipmentsdetails
agreement + equipment detail
POST/agreements/{id}/duplicateagreement
jbwcreateduplicateagreementwithequipments
clone agreement
GET/agreements/dealer/{dealerid}/invoicesearch
jbwinvoicejobsearch
ST invoice lookup (accounting/v2 + installed-equipment)
POST/agreements/dealer/{dealerid}/newinvoiceagreement
jbwcreateagreementfrominvoice
agreement from invoice
GET/agreements/dealer/{dealerid}/stequipments
jbwgetstequipmentsfortenant
ST installed-equipment by location ids
GET/jbwagreements/agreement/{jbwagreementId}
jbwagreementdetailswithjbwagreementid
lookup by JBW agreement id
GET/agreementsync/{id}
jbwagreementsyncdatalist
match-grid data (paged, tab-typed)
GET/agreementsync/{id}/spcall
jbwstdatasyncspcall
sync trigger: per tenant of the dealer, invokes jbwagreementsdatamatch (RequestResponse)
PUT/agreementsync/approve
jbwagreementapproveprocess
approve matched agreements
PUT/agreementsync/{id}/location
jbwagreementmatchingdatalocationupdate
manual location match
GET/claims/{dealerId}
jbwclaimslist
claims grid
PATCH/claims/stupdate
jbwclaimsstupdate
JBW → DB claim sync: fetches JB360ClaimStatus SQL view from the JBW public API (single/bulk/last-day modes), matches to tblClaims, updates status and sets isReadyForST=1, isSentToST=0 for the ST push done by extraction
PATCH/claims/reject/{claimid}
jbwclaimsrejectclaimstatus
reject claim
PATCH/claims/claimidupdate/{id}
jbwclaimsclaimidupdate
attach JBW claim id
GET/invoices/invoicedetails/{invoiceid}
jbwinvoicedetailsbyinvoiceid
invoice detail
GET/tblproducts/search
jbwtblproductssearch
product SKU search
GET/stlocations/search/{dealerid}
jbwstlocationsearch
staged ST location search
GET/customdata
jbwgetcustomdata
reference data
GET/admindashboard/cardsdata
jbwadmindashboardcardsdata
admin KPIs
GET/emailnotifications
jbwemailnotificationlist
notification inbox
PATCH/emailnotifications/{id}
jbwemailnotificationviewedupdate
mark viewed
FunctionRole
jbwagreementsdatamatchThe core sync engine (timeout 300 s). Per dealer: pulls JBW agreements (GET public-api.jbwarranties.com/v1/dealers/{id}/agreements, paged 500) into tblJBWAgreementData; pulls ST locations (crm/v2, pageSize 5000) into tblSTLocationData or Workiz job-locations into tblWorkizLocationData; then CALL jbw_st_dataSync(dealerId, crmSystem) to match locations ↔ agreements. Invoked by jbwstdatasyncspcall and jbwnewonboarding.
jbwagreementslocationsstupload(timeout 900 s) Writes JBW agreement references back into ServiceTitan: PATCH crm/v2 locations/{id} + POST locations/{id}/notes.
jbwequipmentsyncstoredpro, jbwpendingclaimstoredproc(timeout 900 s) Stored-procedure runners.
jbwpendingagreementsnotification, jbwdealerpendingagreementsclaimsnotification, jbwemailserviceSES notification emails (pending agreements/claims; general email service). ⚠ the claims-notification function references a misnamed function (...claimlist vs dir ...claimslist).
jbwworkizjobsdatafetch / jbwworkizjobsdatasavePull completed Workiz jobs (job/all/?status=done) and persist them.
jbwdealerregistrationsetactivestatus, jbwdealerregistrationuserverifyCognito/registration helpers invoked by the auth-flow functions.

44 source dirs under src/ are not wired into template.yaml — deployed or invoked manually (console), or WIP. (107 dirs total, 63 templated.) The July 2026 release added 13 and templated none. The important ones:

DirRole
cognitoclienttokenauthorizer/API Gateway Lambda authorizer — verifies Cognito JWTs (jsonwebtoken + jwks-rsa), stage→pool map, requires scope https://jb360api.jbwarranties.com/apivendor, returns IAM Allow/Deny.
jbwapiauthorizerupdate/ (ESM)Post-deploy utility that walks all API Gateway methods and attaches the Cognito authorizer (OPTIONS → NONE). Must be run after every API redeploy.
jbwdatapullfromJB/ (Python 3.12)Reverse sync JBW → DB: fetches recently modified agreements from a JBW API and updates tblAgreement status/dates/comments by jbwAgreementId (handles cancelled/deleted). Vendored pymssql/pymysql deps; RDS IAM auth.
jbwagreementreferenceremovalfromst/Removes JBW references (notes, custom fields, equipment data) from ServiceTitan locations.
jbwremoveduplicatelocationnotesfromst/Dedupes agreement-link notes on ST locations.
jbwcreatepotentialclaim/Inserts a tblClaims row with status “Potential Claim Created”.
jbwautoprocessagreementsstatus/Toggles tblTenant.autoProcessAgreements.
jbwdbconnection/Standalone MSSQL connectivity test (not part of the app).

Others (same DB-CRUD pattern): jbwagreementdismiss, jbwagreementsearch, jbwagreementslocationsfetch, jbwagreementsyncfileupload, jbwagreementsyncuploadcsvdata, jbwclaimsadmintoolsupdate, jbwclaimsdownloadadmintools, jbwclaimsearch, jbwcreateupdateemailtemplate, jbwdealeradmintoolsupdate, jbwgetagreementdetailsbyjbwagreementid, jbwgetequipmenttypes, jbwgetstinstalledequipments, jbwinvoiceitemskuupdate, jbwinvoicelookup, jbwinvoicesummarylist, jbwsendagreementemail, jbwstlocationdatawithagreement, jbwupdateagreementcontactinfo, jbwupdateagreementsynclocation, jbwusersignupemail.

  • JBWClientServiceTitanVerification — body {clientId, secretId, tenantId, tagsList, jobId, fieldsList}. Gets an ST OAuth token; with jobId it additionally checks tenant tag-types (settings/v2), job custom fields (jpm/v2/jobs?number=), and location custom fields (crm/v2/locations/{id}) and reports which required tags/fields are missing.
  • getTenantInfo — the bridge to extraction: each SQS message carries tenantId, dealerId, ST clientId/clientSecret, batchId, syncStartDate. Has an EventBridge Scheduler IAM policy, so it can be (and likely is) invoked on a schedule.
  • jbwclaimsstupdate — matches JBW claims to local rows by jbwClaimId, or by job number + dealer + agreement (FIND_IN_SET) as fallback.

Tables: tblTenant, tblDealerOnboard, tblDealerRegister, tblTransmissionDetails(+History), tblAgreement, tblAgreementEquipments, tblJBWAgreementData, tblSTLocationData, tblWorkizLocationData, tblWorkizAccounts, tblClaims, tblBusinessUnit, tblProducts, tblInvoice, tblInvoiceItem. Views: vwOnboardedDealers, plus JBW-side JB360ClaimStatus (remote, via public API). Stored procedures: jbw_st_dataSync and 9 others — documented from the live DB in aws/database.md. (Code references to a jbw_workiz_dataSync notwithstanding, the live prod DB has no such procedure — Workiz is a _platform='Workiz' branch inside jbw_st_dataSync.)