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:
| Method | Path | Function | Notes |
|---|---|---|---|
| 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 |
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”~30 source dirs under src/ are not wired into template.yaml — deployed or invoked manually (console), or WIP. 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.)