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).
Shared Code Pattern
Section titled “Shared Code Pattern”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 wrappervalidateInput(...)— request validationmysqlConnection()— mysql2 connection through RDS Proxy using an IAM auth token (AWS.RDS.Signer,mysql_clear_passwordplugin,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).
API Routes
Section titled “API Routes”Complete method + path → function map from template.yaml (each cell: endpoint, then its Lambda):
| Method | Route / Function | Notes |
|---|---|---|
| GET | /dealerjbwalldealerlist | dealer search/list (?key=&type=) |
| PATCH | /dealer/{id}jbwdealerstatusregisterupdate | dealer status update |
| GET | /dealer/{id}/verifyjbwdealerverification | dealer existence check |
| GET | /dealer/{id}/onboardjbwonboarddetails | onboarding record |
| GET | /dealer/{id}/cardsdatajbwdealerdetailscardsdata | dealer dashboard KPIs |
| GET | /dealer/{id}/gettenantinfogetTenantInfo | 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}/transmissiondetailsjbwtransmissiondetailsbydealer | latest sync audit |
| GET | /dealer/{id}/transmissiondetailshistoryjbwtransmissiondetailshistorybydealer | sync audit history |
| GET | /dealer/nononboardedlistjbwnononboardeddealerlist | dealers not yet onboarded |
| GET | /dealer/latestonboardeddealersjbwgetfivelatestdealeronboardlist | admin dashboard widget |
| POST | /newdealeronboardjbwnewonboarding | persists onboarding, then invokes jbwagreementsdatamatch for the initial sync |
| GET | /dealeronboardjbwdealeronboardedlist | onboarded dealer list |
| POST | /dealerregister/addjbwdealerregistercreate | registration record |
| GET | /dealerregisterjbwdealerregistrationlist | registration list |
| GET | /dealerregister/{id}/dealerverifyjbwdealerregistrationverify | (timeout 900 s) |
| PUT | /dealerregister/userstatusjbwuseractivestatus | Cognito enable/disable + SES; invokes jbwdealerregistrationsetactivestatus |
| PATCH | /dealerregister/{id}/updatereleasenotestatusjbwupdatereleasenotesstatus | release-notes seen flag |
| POST | /signupjbwusersignup | Cognito signup; invokes jbwdealerregistercreate + jbwemailservice |
| POST | /changepasswordjbwchangePassword | Cognito + SES |
| POST | /resetpasswordjbwuserresetpassword | 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 | /jbwservicetitanJBWClientServiceTitanVerification | verifies ST OAuth creds; optionally checks required tag-types, job custom fields, location custom fields exist (see below) |
| GET | /workiz/accountverifyjbwworkizaccountverify | verifies Workiz account via job/all/ |
| GET | /agreements/dealer/{dealerid}jbwdealeragreementlist | agreement grid |
| GET | /agreements/{id}/equipmentsjbwagreementequipmentsbyagreementid | equipment rows |
| POST | /agreements/{id}/equipmentsjbwagreementequipmentadd | add equipment |
| PATCH | /agreements/{id}/equipmentsjbwdeleteagreementbyid | ⚠ route collides with add/get; part of the mis-indented template block |
| PUT | /agreements/{id}/equipmentsyncjbwservicetitansagreementspull | 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}/agreementdetailsjbwagreementwithequipmentsdetails | agreement + equipment detail |
| POST | /agreements/{id}/duplicateagreementjbwcreateduplicateagreementwithequipments | clone agreement |
| GET | /agreements/dealer/{dealerid}/invoicesearchjbwinvoicejobsearch | ST invoice lookup (accounting/v2 + installed-equipment) |
| POST | /agreements/dealer/{dealerid}/newinvoiceagreementjbwcreateagreementfrominvoice | agreement from invoice |
| GET | /agreements/dealer/{dealerid}/stequipmentsjbwgetstequipmentsfortenant | 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}/spcalljbwstdatasyncspcall | sync trigger: per tenant of the dealer, invokes jbwagreementsdatamatch (RequestResponse) |
| PUT | /agreementsync/approvejbwagreementapproveprocess | approve matched agreements |
| PUT | /agreementsync/{id}/locationjbwagreementmatchingdatalocationupdate | manual location match |
| GET | /claims/{dealerId}jbwclaimslist | claims grid |
| PATCH | /claims/stupdatejbwclaimsstupdate | 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/searchjbwtblproductssearch | product SKU search |
| GET | /stlocations/search/{dealerid}jbwstlocationsearch | staged ST location search |
| GET | /customdatajbwgetcustomdata | reference data |
| GET | /admindashboard/cardsdatajbwadmindashboardcardsdata | admin KPIs |
| GET | /emailnotificationsjbwemailnotificationlist | notification inbox |
| PATCH | /emailnotifications/{id}jbwemailnotificationviewedupdate | mark viewed |
Key Non-API Functions (in the template)
Section titled “Key Non-API Functions (in the template)”| Function | Role |
|---|---|
jbwagreementsdatamatch | The 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, jbwemailservice | SES notification emails (pending agreements/claims; general email service). ⚠ the claims-notification function references a misnamed function (...claimlist vs dir ...claimslist). |
jbwworkizjobsdatafetch / jbwworkizjobsdatasave | Pull completed Workiz jobs (job/all/?status=done) and persist them. |
jbwdealerregistrationsetactivestatus, jbwdealerregistrationuserverify | Cognito/registration helpers invoked by the auth-flow functions. |
Functions NOT in the Template
Section titled “Functions NOT in the Template”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:
| Dir | Role |
|---|---|
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.
Notable Handler Details
Section titled “Notable Handler Details”JBWClientServiceTitanVerification— body{clientId, secretId, tenantId, tagsList, jobId, fieldsList}. Gets an ST OAuth token; withjobIdit 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 toextraction: each SQS message carriestenantId,dealerId, STclientId/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 byjbwClaimId, or by job number + dealer + agreement (FIND_IN_SET) as fallback.
Database Objects Referenced
Section titled “Database Objects Referenced”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.)