...
| Adapter | Status | Notes |
|---|---|---|
| CST | ✅ Production | Full account operations, invoices, measurements, locations, agreements, users, features |
| Xellent | ✅ Production | OAuth2/Azure AD; full account operations, invoices, measurements, locations, agreements, users |
| ProBill | ✅ Production | Full account operations, invoices, measurements (4 resolutions), costs, locations, agreements |
| SonWin | 🔨 In Progress | OAuth2/Azure AD; account, locations, products, agreements, invoices (list), measurements & costs (4 resolutions), patch user |
| Zynergy | ⚠️ Partial | SSN search only; dynamic field mapping |
| Gasell | ⚠️ Minimal | SSN search only; no internal service layer |
...
┌─────────────────────────────────────────────────────┐
│ Bright App │
└─────────────────────┬───────────────────────────────┘
│ HTTPS + JWT Bearer
┌─────────────────────▼───────────────────────────────┐
│ EGU Common API │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ API Layer (WebApp) │ │
│ │ │ │
│ │ AccountsApi BankIdApi AuthApi EventsApi │ │
│ │ SystemApi WebViewApi │ │
│ └──────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────┐ │
│ │ Orchestration Layer │ │
│ │ │ │
│ │ AccountApiService BankIdApiService │ │
│ │ AuthenticationApiService EventsApiService │ │
│ └──────────┬─────────────────┬─────────────────┘ │
│ │ │ │
│ ┌──────────▼──────┐ ┌──────▼──────────────────┐ │
│ │ Shared Services │ │ Adapter Factory │ │
│ │ │ │ │ │
│ │ InvoiceArchive │ │ Resolves adapter by │ │
│ │ - EDB │ │ AdapterType from │ │
│ │ - IData │ │ SubscriptionSetting │ │
│ │ - Stralfors │ └──────────┬──────────────┘ │
│ │ - TietoEvry │ │ │
│ │ - Url │ ┌──────────▼──────────────┐ │
│ │ │ │ Adapter Layer │ │
│ │ ZignSec BankID │ │ │ │
│ │ - V5 client │◄─┤ CST Xellent Zynergy │ │
│ │ │ │ Gasell SonWin ProBill │ │
│ └─────────────────┘ └──────────┬──────────────┘ │
│ │ │
└───────────────────────────────────┼─────────────────┘
│
Backend Systems (External APIs) │
┌───────────┬──────────┬────────┴───┬──────────┬──────────────┐
│ │ │ │ │ │
┌─────▼────┐ ┌───▼────┐ ┌──▼──────┐ ┌─▼──────┐ ┌──▼──────┐ ┌──▼──────┐
│ CST API │ │Xellent │ │ Zynergy │ │ Gasell │ │ SonWin │ │ ProBill │
│ │ │ API │ │ API │ │ API │ │ API │ │Bright AP│
└──────────┘ └────────┘ └─────────┘ └────────┘ └────────┘ └─────────┘
...
3. Request Flow
1. Client sends request to:
POST /subscriptions/{subscriptionId}/accounts/search
2. API endpoint (AccountsApi) receives the request
└── extracts subscriptionId from route
3. AccountFactoryService is called
└── ISubscriptionSettingService looks up the subscription
└── reads AdapterType from configuration (e.g. AdapterType.CST)
└── returns the matching IAccountAdapterService instance
4. Adapter executes the operation
└── calls InternalServices for business logic
└── InternalServices call ApiCallServices for HTTP communication
└── maps backend response to standard Bright Kit DTO
5. Unified response returned to client
4. Layer Breakdown
Project Structure
EGU.CommonAPI.sln
├── src/
│ ├── App/
│ │ └── EGU.CommonAPI.WebApp # ASP.NET Core Minimal API host
│ │ ├── Apis/ # Endpoint definitions
│ │ └── Adapters/
│ │ ├── Factories/ # Adapter factory services
│ │ └── Services/ # Orchestration (API → adapter)
│ │
│ ├── Domain/
│ │ ├── EGU.CommonAPI.Domain.Contracts # Interfaces, DTOs, enums, settings
│ │ ├── EGU.CommonAPI.Domain.Core # Base classes, shared utilities
│ │ └── EGU.CommonAPI.Domain.InvoiceArchive # Invoice PDF infrastructure
│ │
│ └── Adapters/
│ ├── EGU.CommonAPI.Adapters.CST
│ ├── EGU.CommonAPI.Adapters.Xellent
│ ├── EGU.CommonAPI.Adapters.Zynergy
│ ├── EGU.CommonAPI.Adapters.Gasell
│ ├── EGU.CommonAPI.Adapters.SonWin
│ └── EGU.CommonAPI.Adapters.ProBill
│
└── test/
└── EGU.CommonAPI.UnitTests # MSTest + NSubstitute
...
| Endpoint | Operation |
|---|---|
GET /search?customer_soc_id={SSN} | Search account by SSN |
...
ProBill
| Endpoint | Operation |
|---|---|
GET brightAccounts?ssn={ssn} | Search by SSN |
GET brightAccounts?CustomerID={id} | Search/get by customer ID |
GET brightAccounts?email={email} | Search by email |
GET brightAgreements?customerId={id}&placementId={id} | Get agreements |
GET brightInvoices?customerId={id}[&DateFrom&DateTo&limit] | Get invoices |
GET brightLocations?customerId={id}&limit={n} | Get locations |
GET brightProducts?customerId={id}&placementId={id}[&DateFrom&DateTo] | Get products |
GET brightMeasurements?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Monthly measurements |
GET brightMeasurementDays?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Daily measurements |
GET brightMeasurementHours?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Hourly measurements |
GET brightMeasurementQuarters?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | 15-min measurements |
GET brightCosts?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Monthly costs |
GET brightCostDays?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Daily costs |
GET brightCostHours?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | Hourly costs |
GET brightCostQuarters?CustomerID={id}&PlacementID={id}[&DateFrom&DateTo] | 15-min costs |
PATCH v2/customers | Update customer (email, phone) |
...
SonWin
Dates are sent as
yyyy-MM-ddTHH:mm:ssusing the UTC components of the value, with noZsuffix (SonWin's validator rejects aZ/offset-bearing value).
...