Skip to main content
Version: Latest

2. Architecture

2.1 Two-Layer Model

2.2 Standalone Library Boundary

The library exposes exactly three public interfaces (Abstractions package) and never reaches upward into ERP concepts. It has no DbContext, no TenantId, no permission checks, and no knowledge of "conversations" or "customers" — only "messages," "templates," and "webhooks" in Meta's own vocabulary.

2.3 ERP Host Boundary

Shumoul.Saas.Api is the only consumer of this library. It owns all persistence (WhatsAppConversation, WhatsAppMessage, WhatsAppConversationNote, WhatsAppConversationTag, WhatsAppSavedReply, etc.), all tenant resolution, all permission checks ([MustHavePermission]), and the entire controller/DTO surface documented in §6 API Reference.

2.4 Why There Is Exactly One Meta Client

Prior to the Phase 1 Runtime Consolidation, two independent Graph API HTTP clients existed: WhatsAppCloudApiClient (this library) for most flows, and a hand-rolled HttpClient inside the ERP's TenantWhatsAppSender hardcoded to Graph API v19.0. As of Phase 1, TenantWhatsAppSender constructs a WhatsAppCloudApiClient instance per call — merging the tenant's own credentials (WhatsAppOperationalSettings.AccessToken/PhoneNumberId/BusinessAccountId) with the platform's central BaseUrl/GraphApiVersion — instead of re-implementing the HTTP call. This required zero changes to the library's public API, because WhatsAppCloudApiClient's constructor and WhatsAppCloudApiOptions were already fully public. There is now exactly one Meta Graph API client class in the entire solution.

The one remaining direct-HTTP call outside this client is TenantWhatsAppSender.TestConnectionAsync, a business-account lookup (GET {BaseUrl}/{GraphApiVersion}/{BusinessAccountId}?fields=id,name) with no equivalent method on IWhatsAppService — not a duplicate, just a narrow diagnostic call that now also reads BaseUrl/GraphApiVersion from the same central configuration.

2.5 Dependency Graph

2.6 Package Graph

2.7 Runtime Ownership Map

ConcernOwner
Meta Cloud API HTTP clientLibrary (WhatsAppCloudApiClient) — the only one in the solution
Signature validationLibrary (WhatsAppSignatureValidator)
Webhook parsingLibrary (WhatsAppWebhookParser)
Provider DTOs / Meta-specific modelsLibrary (Contracts)
Inbox / Conversations / Notes / Tags / Saved Replies / Timeline / PresenceERP
SignalR real-time layer (WhatsAppHub)ERP
Communication module (tenant document sends)ERP
OTP / Activation business messagesERP
Phone number normalizationERP (WhatsAppPhoneHelper) — deliberately never moved into the library
Controllers, permissions, routes, database schemaERP

2.8 Compliance With Platform Architecture Standards

  • Dependency Law: the ERP consumes the library only via PackageReference, never ProjectReference.
  • Adapter Standard: the Notification Framework's bridge from its generic channel contract to IWhatsAppService (WhatsAppChannelProviderAdapterMetaWhatsAppProvider) is a Host Adapter, not a library concern.
  • ADR-001: the boundary decision recorded in the library's own repository — see §1.4.