Integration Enhancements
This page focuses on extension points used to integrate Open Saasframe with external systems.
Payment and shipping gateways
- Register custom providers with
registerPaymentProviderandregisterShippingProvider. - 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.tsto define workflow-specific messages. - Extend
message-objects.tsto 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, andafterSuccesscallbacks - Command interceptors (UMES M):
commands/interceptors.ts—beforeExecute/afterExecutehooks for execute and undo flows - Event-driven side effects:
subscribers/*.ts(supportssync: truemetadata 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/integrationsandGET /api/integrations/:idnow support response enrichers targetingintegrations.integrationGET /api/integrations/logssupports response enrichers targetingintegrations.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
afterinterceptors
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[]withid,label, optionalfields, optionalvalidate, and optionalcustomComponent - Step validation returns
{ ok, message?, fieldErrors? }to block progression onCompletecallback receives accumulated data from all steps- Supports
Escapeto 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) statusLoaderis called on mount and atpollInterval(default 60 s)- Optional
hrefmakes 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.widgetSpotIdin theIntegrationDefinition - Map widgets to that spot in
widgets/injection-table.ts - Use
placement.kind: 'tab'for extra tabs,placement.kind: 'group'for card sections, andplacement.kind: 'stack'for inline sections above the built-in tabs - Built-in detail actions (credentials save, state toggle, version change, health check) run through
useGuardedMutationbound to the same spot, so widgetonBeforeSaveandonAfterSavehooks 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.widgetSpotIdis omitted, the integrations page falls back to the legacyintegrations.detail:tabsspot - Existing providers that inject into
integrations.detail:tabskeep 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):
- Query-level enrichers and sync query lifecycle events — see Query engine extensibility