Skip to main content
Version: Latest

2. Architecture

2.1 Layer Model

2.2 The Three-Line Wiring

The entire integration point between the ERP host and the E-Invoicing SDK is three lines, in Shumoul.Infrastructure/Extensions/ServiceCollectionExtensions.cs:214-216:

services.AddEInvoicingSDK(config)
.UseAppSettings<AppSettingService>()
.IncludeApi();
  • AddEInvoicingSDK(config) — binds and validates EGSConfigSettings/ZatcaPortalSettings from appsettings.json, registers localization, the SDK's own DI auto-registration, MediatR (scoped to the Framework's own assembly), and AutoMapper. Throws at startup if the required config sections are missing.
  • .UseAppSettings<AppSettingService>() — registers the ERP's own AppSettingService class as the concrete implementation of the SDK's IEInvoicingAppSettingService abstraction. This is the only integration surface between the SDK and the ERP's own persistence/tenant model.
  • .IncludeApi() — loads the compiled Shumoul.Framework.EInvoicing.Api assembly as an ASP.NET Core MVC Application Part. This is how the SDK's controllers become live, routable endpoints in the same host process — no controller code is duplicated into Shumoul.Api, and no ERP-specific controller wraps or gates these endpoints.

2.3 Two-Layer Model — SDK + Thin API, Not SDK + ERP Integration Layer

Unlike the WhatsApp Integration Library (a stateless protocol client consumed by ERP-owned business services that add tenant/business logic on top), E-Invoicing's "Api" layer is not an ERP integration layer — it's a second, generic layer shipped by the same Framework package, exposing the SDK's own capabilities almost 1:1 as HTTP endpoints. There is no ERP-owned service comparable to TenantWhatsAppSender between Shumoul.Api's business logic and the E-Invoicing SDK.

2.4 Dependency Direction — Clean From the SDK's Side

  • Shumoul.Framework.EInvoicing / .Tenancy each reference only the Framework's own generic Shumoul.Framework.Application / Shumoul.Framework.Infrastructure base libraries — zero reference to ERP-internal Shumoul.Application / Shumoul.Infrastructure / Shumoul.Domain.
  • Shumoul.Framework.EInvoicing.Api references Shumoul.Framework.EInvoicing; Shumoul.Framework.EInvoicing.TenancyApi references Shumoul.Framework.EInvoicing.Tenancy.
  • Shumoul.BackEnd.sln contains zero direct project references to any EInvoicing project — the ERP consumes only the compiled NuGet package, consistent with the platform's Dependency Law.
  • Shumoul.Framework.MultiTenancy.Api.csproj (in Shumoul.MultiTenancyApi) references Shumoul.Framework.EInvoicing.TenancyApi the same way.

2.5 The Tenancy Fork — Duplication, Not Adapter

Shumoul.Framework.EInvoicing.Tenancy is a byte-for-byte copy of the core SDK's namespace and class structure — not a thin adapter reusing shared core logic with a different persistence backend. Every future behavior change (a ZATCA rule update, a bug fix) must be made twice, in two places, to keep both variants in sync. The fork's own DI bootstrap (AddEInvoicingTenancySDK) is entirely commented out — dead code.

2.6 What's Missing Compared to the Platform's Certified Frameworks

CharacteristicNotification / Background Jobs / WhatsAppE-Invoicing
Standalone repositoryYes, all threeNo — lives inside Shumoul.Framework
ERP-owned business integration layerYes (e.g. WhatsAppOtpMessageService)No — SDK's own generic controllers are the only entry point
Wired into a real ERP workflowYesNot found — no Sales/Purchase invoice service calls it
Background/retry integrationYes (Notification Framework retry pipeline)None
ADR documenting the boundary decisionYes (WhatsApp's ADR-001)None found
Golden Reference certificationNotification + Background Jobs are certifiedNot applicable yet

2.7 Boundary Verdict

E-Invoicing sits in a hybrid state: too generic and too directly exposed to be safely called "ERP code," but missing the Host Adapter layer, the ADR, the retry/notification integration, and the tenant-aware security posture that would let it stand as a peer to the platform's certified Frameworks. It has the packaging shape of a Framework (versioned NuGet packages, dependency-clean from ERP internals, its own test project) but not the integration shape every certified Framework has.