Skip to main content

Integration Enhancements

This page focuses on extension points used to integrate Open Saasframe with external systems.

Payment and shipping gateways

  • Register custom providers with registerPaymentProvider and registerShippingProvider.
  • Providers can declare UI settings fields, validation schema, and runtime adjustment calculators.
  • Provider settings are persisted and reused in totals calculation.

Start with: Shipping & payment providers

Messaging as an integration boundary

  • Extend message-types.ts to define workflow-specific messages.
  • Extend message-objects.ts to attach domain records (customers, orders, staff, etc.).
  • Combine with message actions to trigger commands or links.

Start with: Messages system

Notifications and inbox delivery

  • Add notification definitions in notifications.ts.
  • Add client renderers in notifications.client.ts.
  • Emit domain events and subscribe to produce user-facing notifications.

Start with: Notifications, Events overview

Search and vector integrations

  • Fulltext integration: implement a compatible fulltext driver.
  • Vector integration: configure vector entities and choose vector driver/backend.
  • Embedding provider integration supports OpenAI/Google/Mistral/Cohere/Bedrock/Ollama.

Start with: Hybrid search

Workflow and scheduler integration patterns

  • Use workflow activities/signals for external system orchestration.
  • Use scheduler jobs for recurring pull/sync integrations.
  • Use progress events for UI status during long-running sync jobs.

Start with: Workflows extending, Scheduler, Progress

API-level integration hooks

  • Route-level interception: api/interceptors.ts
  • Response composition: data/enrichers.ts
  • Mutation guards (UMES M): data/guards.ts — register guards with priority ordering, payload modification, and afterSuccess callbacks
  • Command interceptors (UMES M): commands/interceptors.tsbeforeExecute/afterExecute hooks for execute and undo flows
  • Event-driven side effects: subscribers/*.ts (supports sync: true metadata for in-pipeline lifecycle events — UMES M)
  • Long-running processing: workers/*.ts

Start with: API extension guide, Queue workers

For the integrations marketplace specifically:

  • GET /api/integrations and GET /api/integrations/:id now support response enrichers targeting integrations.integration
  • GET /api/integrations/logs supports response enrichers targeting integrations.log
  • These read routes also execute API interceptors
  • Safety rule: marketplace read routes preserve built-in response fields and only allow additive fields from enrichers and after interceptors

Integration extension widgets (UMES Phase L)

Phase L adds first-class UI widgets and data primitives for building integration modules.

InjectionWizard

Multi-step wizard widget for integration onboarding (OAuth flows, API credential entry, scope configuration). Renders a numbered step indicator with navigation and per-step validation.

  • Define steps as InjectionWizardStep[] with id, label, optional fields, optional validate, and optional customComponent
  • Step validation returns { ok, message?, fieldErrors? } to block progression
  • onComplete callback receives accumulated data from all steps
  • Supports Escape to cancel

Import: import { InjectionWizard } from '@saasframe/ui/backend/injection/InjectionWizard'

StatusBadgeRenderer

Status badge widget with pollable status loaders. Displays a color-coded dot, label, optional count badge, and optional tooltip.

  • Statuses: healthy (green), warning (yellow), error (red), unknown (gray)
  • statusLoader is called on mount and at pollInterval (default 60 s)
  • Optional href makes the badge a link

Import: import { StatusBadgeRenderer } from '@saasframe/ui/backend/injection/StatusBadgeRenderer'

ExternalIdsWidget

Injection widget for displaying external system ID mappings. Reads the _integrations namespace from enriched API responses and renders a row per integration with provider name, external ID code badge, sync status dot, and optional external link.

  • Sync statuses: synced, pending, error, not_synced
  • Provider name resolved via getIntegrationTitle() from the integration registry

Widget: packages/core/src/modules/integrations/widgets/injection/external-ids/widget.client.tsx

Integration registry

Register integration definitions at module bootstrap so the platform can discover metadata and build deep links.

import {
buildIntegrationDetailWidgetSpotId,
registerIntegration,
getAllIntegrations,
getIntegrationTitle,
} from '@saasframe/shared/modules/integrations/types'

registerIntegration({
id: 'sync_shopify',
title: 'Shopify',
icon: 'shopify',
detailPage: {
widgetSpotId: buildIntegrationDetailWidgetSpotId('sync_shopify'),
},
buildExternalUrl: (externalId) => `https://admin.shopify.com/store/demo/products/${externalId}`,
})

getAllIntegrations() // returns all registered IntegrationDefinition[]
getIntegrationTitle('sync_shopify') // 'Shopify'
getIntegrationTitle('unknown') // 'unknown' (falls back to ID)

Provider-scoped integration detail widgets

Integration providers can now extend their own marketplace detail pages directly from integration.ts.

  • Declare detailPage.widgetSpotId in the IntegrationDefinition
  • Map widgets to that spot in widgets/injection-table.ts
  • Use placement.kind: 'tab' for extra tabs, placement.kind: 'group' for card sections, and placement.kind: 'stack' for inline sections above the built-in tabs
  • Built-in detail actions (credentials save, state toggle, version change, health check) run through useGuardedMutation bound to the same spot, so widget onBeforeSave and onAfterSave hooks can participate in those flows
import { buildIntegrationDetailWidgetSpotId } from '@saasframe/shared/modules/integrations/types'

export const integration = {
id: 'gateway_example',
title: 'Example Gateway',
detailPage: {
widgetSpotId: buildIntegrationDetailWidgetSpotId('gateway_example'),
},
}

export const injectionTable = {
[buildIntegrationDetailWidgetSpotId('gateway_example')]: [
{
widgetId: 'gateway_example.injection.tools',
kind: 'tab',
groupLabel: 'gateway_example.tabs.tools',
priority: 100,
},
],
}

Backward compatibility:

  • If detailPage.widgetSpotId is omitted, the integrations page falls back to the legacy integrations.detail:tabs spot
  • Existing providers that inject into integrations.detail:tabs keep working, but new providers should prefer the provider-scoped spot to avoid collisions between unrelated integrations

Start with: Widget injection, Data extensibility

Data integration and entity mapping today

Currently available:

  • Custom entities and custom fields for schema-level adaptation
  • Message object type mapping for cross-module record linking
  • Query index and search indexing for downstream lookup/search use cases
  • External ID mapping enricher and ExternalIdsWidget (UMES Phase L — see above)

Now available (UMES Phase N):