Skip to content

Bounded Contexts

Target Architecture — Final-State Design

This page describes the final-state bounded-context decomposition of the Integration Platform. Contexts are designed for independent evolution, single ownership of aggregates, and explicit, governed interactions through the canonical event envelope.

The Integration Platform follows Clean Architecture + Domain-Driven Design. Its capabilities decompose into eight bounded contexts, each owning a coherent set of aggregate roots and exposing behaviour through well-defined APIs and events. Contexts never share a database; they integrate through events and explicit service contracts, which keeps connection ownership clear and the platform horizontally scalable across the multi-tenant estate. The Webhooks and Vendor Registry contexts are cross-cutting: every other context registers providers in the Vendor Registry and may both emit and consume webhooks.

Context Map

flowchart TB
    Vendor["Vendor Registry"] -.provider catalog.-> SCM["Source Control Integration"]
    Vendor -.provider catalog.-> Model["Model Providers"]
    Vendor -.provider catalog.-> Cloud["Cloud Provider"]
    Vendor -.provider catalog.-> Comm["Communication"]
    Vendor -.provider catalog.-> Commerce["Commerce"]
    Vendor -.provider catalog.-> Biz["Business Systems"]

    SCM --> Hooks["Webhooks"]
    Model --> Hooks
    Cloud --> Hooks
    Comm --> Hooks
    Commerce --> Hooks
    Biz --> Hooks

    Hooks -->|"normalized events"| Bus["Azure Service Bus"]
    SCM --> Bus
    Model --> Bus
Hold "Alt" / "Option" to enable pan & zoom

The map reads as a hub-and-spoke around two cross-cutting authorities. Vendor Registry is the upstream supplier of provider definitions and reusable API clients that every integration context consumes. The six domain contexts (Source Control, Model Providers, Cloud Provider, Communication, Commerce, Business Systems) each own connections, credentials, and runs for their vendor family. Webhooks is the shared ingress/egress boundary through which inbound callbacks are normalised and outbound deliveries are dispatched; all normalised traffic lands on Azure Service Bus in the canonical envelope.

Contexts, Aggregates, and Responsibilities

Bounded Context Owning Services (ConnectSoft.Factory.Integration.*) Aggregate Roots Primary Responsibility
Source Control Integration AzureDevOpsIntegrationService, GitHubIntegrationService IntegrationConnection, IntegrationCredential, IntegrationRun Drive repo, branch, PR, pipeline, and check operations on Azure DevOps and GitHub.
Model Providers OpenAIIntegrationService, AzureOpenAIIntegrationService, OllamaIntegrationService, McpConnectorService IntegrationConnection, IntegrationCredential, IntegrationRun Front LLM providers and MCP tool servers for the Agent Mesh with governed, audited access.
Cloud Provider CloudProviderAdapterService IntegrationConnection, IntegrationRun Normalise cloud control-plane operations behind a provider-agnostic adapter.
Communication EmailIntegrationService, SmsIntegrationService IntegrationConnection, IntegrationCredential, IntegrationRun Send email and SMS through provider-abstracted gateways (Twilio / Israel019 / ACS).
Commerce PaymentIntegrationService IntegrationConnection, IntegrationCredential, IntegrationRun, IntegrationFailure Integrate payment processors and reconcile commerce callbacks.
Business Systems CrmIntegrationService, SupportIntegrationService IntegrationConnection, IntegrationCredential, IntegrationRun Integrate CRM and support/ticketing systems for business workflows.
Vendor Registry VendorApiClientRegistryService IntegrationProvider, ExternalApiClient Catalogue supported providers, their capabilities and auth models, and versioned reusable API clients.
Webhooks WebhookGatewayService WebhookSubscription, WebhookDelivery, IntegrationFailure Verify, normalise, and dispatch inbound webhooks; deliver signed factory events outward with retry.

All aggregates carry the cross-cutting metadata fields (tenantId, projectId, moduleId, traceId, correlationId, causationId, environment, version, createdAt, updatedAt, status), which is what lets any connection, run, delivery, or failure be correlated back to the lifecycle that produced it. The full per-aggregate breakdown is in Aggregate Roots.

Context Interaction Principles

  • Single ownership. Each aggregate instance is owned by exactly one context and persisted in exactly one store. No cross-context database joins.
  • Events over coupling. Contexts publish domain events (NounVerbPastTense) and react to integration events; they never call into each other's persistence.
  • Vendor Registry is the source of truth for providers. A connection cannot be established against a provider that is not registered, capability-described, and assigned a versioned ExternalApiClient.
  • Webhooks is the only ingress. All inbound external callbacks enter through WebhookGatewayService, which guarantees signature verification, tenancy resolution, idempotency, and normalisation before fan-out.
  • Credentials are never owned by the domain. IntegrationCredential aggregates hold only Key Vault references and rotation metadata; secret material is custodied in Azure Key Vault.

Inbound Normalisation Pipeline

Every inbound webhook enters through the Webhooks context, which runs a multi-stage pipeline before the callback becomes a canonical factory event.

flowchart LR
    Ext["External Vendor Callback"] --> GW["WebhookGatewayService"]
    GW --> Verify["Verify signature<br/>+ resolve tenant"]
    Verify --> Dedup["Deduplicate<br/>(deliveryId / contentHash)"]
    Dedup --> Persist["Persist raw payload<br/>(Azure Blob)"]
    Persist --> Normalize["Normalize to<br/>canonical envelope"]
    Normalize --> Record["Create WebhookDelivery"]
    Record --> Publish["Publish event<br/>(Azure Service Bus)"]
    Publish --> Bus[("Azure Service Bus")]
Hold "Alt" / "Option" to enable pan & zoom

Stages: verify the vendor signature and resolve the owning tenantId; deduplicate on the vendor delivery id or content hash to enforce idempotency; persist the raw body to Azure Blob for replay and audit; normalize to the canonical envelope; record a WebhookDelivery carrying full metadata and lineage; and publish the normalised event. Each stage emits an event (WebhookDelivered, IntegrationFailed on rejection), so inbound processing is fully traceable and replayable. See Workflows and Events.