This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
@sipgate/integration-bridge — a shared Express-based framework that bridges sipgate to external CRMs and contact management systems. Individual bridges (e.g., sipgate-integration-bridge, hubspot-integration-bridge) depend on this package and implement the Adapter interface.
Published to npm as @sipgate/integration-bridge. Version bumps auto-publish. There is no staging or development environment — changes merged to main go live immediately.
npm test # Run all Jest tests
npm test -- src/util/error.test.ts # Run single test file
npm test -- --testNamePattern="name" # Run tests matching pattern
npm run build # Test + clean + compile (for publishing)
npm run compile # TypeScript compilation only
npm run lint # ESLint
npm run format # Prettier
npm run dev # Build + npm link + watch (for local bridge development)start(adapter, customRouters?, customRoutes?) in src/index.ts — creates an Express server, registers middleware and routes, and wires the adapter into all controller endpoints.
Bridges implement this interface. All methods are optional. Key groups:
- Contacts:
getContacts,createContact,updateContact,deleteContact,streamContacts(async generator for PubSub streaming) - Auth:
getToken(refresh OAuth token),isValidToken,handleOAuth2Callback - Entities:
getEntity,getEntitiesForContact(deals, companies, tickets, etc.) - Call Logging:
createOrUpdateCallLogForEntities,createCallLogForPhoneNumber - Tasks:
getTask,createFollowUp
extractHeaderMiddlewareextractsConfigfrom headers (x-user-id,x-provider-key,x-provider-url,x-provider-locale)- Controller calls the adapter method
- Errors go through
throwAndDelegateError()or are caught in controllers errorHandlerMiddlewaresends the response
throwAndDelegateError()maps HTTP status codes toIntegrationErrorTypeenum values- Status
452(DELEGATE_TO_FRONTEND_CODE) signals semantic errors to the frontend IntegrationErrorTypeenum insrc/models/integration-error.model.tsdefines error codes likeintegration/refresh-error,integration/error/unavailable, etc.- Controllers suppress logging for
INTEGRATION_REFRESH_ERROR(handled upstream by platypus)
Uses Google Cloud PubSub. The adapter's streamContacts() returns an AsyncGenerator<Contact[]>. The controller publishes batches with ordering keys (${userId}:${timestamp}) and state messages (IN_PROGRESS, COMPLETE, FAILED).
getFreshAccessToken() caches tokens (Redis or in-memory LRU) with a default TTL of 59 minutes. Token updates are propagated via PubSub topic PUBSUB_TOPIC_NAME_UPDATE_PROVIDER_KEY.
Contact cache with Redis or memory storage. Background refresh (non-blocking) with configurable interval via CACHE_REFRESH_INTERVAL env var. Falls back to in-memory LRUCache if REDIS_URL is not set.
Zod schemas validate contacts (required: id, phoneNumbers) and other inputs. Contact scopes: PRIVATE, SHARED, INTERNAL.
Config—{ userId, apiKey, apiUrl, locale }extracted from request headersContact— contact with phone numbers, email, organization, related entitiesServerError— extendsErrorwithstatusfieldIntegrationEntity—{ id, type, source }for CRM objects (deals, companies, etc.)CallEvent/CallEventWithIntegrationEntities— call log data
# In this repo:
npm run dev # builds, links, and watches
# In a bridge repo:
npm link @sipgate/integration-bridge
# Update tsconfig.json paths to point to: node_modules/@sipgate/integration-bridge/src