Project analysis / platform architecture
EBSH Trade: a B2B portal integrated with BAS/1C
An energy supplier's website brings a customer in; its portal supports the ongoing relationship. We developed both parts for EBSH Trade. This analysis explains the boundaries between the public website, B2B platform and accounting system, and how those boundaries affect data and access.
Three systems with different responsibilities
The multilingual Next.js website explains services, provides documents and accepts inquiries. A separate React and Vite portal handles company profiles, contracts, finance and consumption. Administrative screens let the supplier's team manage consumers, users and synchronisation.
The NestJS backend stores data in PostgreSQL through Prisma. A background worker handles BAS/1C integration through OData, with Redis and BullMQ organising the work. The simplified diagram below represents implemented responsibilities without exposing infrastructure addresses, customer data or credentials.
text
Next.js website → server-side inquiry form
React portal → NestJS API → PostgreSQL
↑
BAS/1C OData → background worker┘
↑
Redis / BullMQ
Simplified EBSH Trade component diagram.Accounting and portal data have different owners
The browser does not connect directly to BAS. The integration reads accounting data on the server; a local portal edit does not imply a write back to BAS. Access control, import and presentation can therefore be managed separately.
Some company profile values support local CRM corrections over imported values. A subsequent sync must preserve those corrections. Consumption, EIC codes and uploaded portal documents are local data with their own lifecycle.
| Data | Source and behaviour |
|---|---|
| Accounting finance figures | Agreed BAS snapshots and imports, read on the server |
| Local CRM corrections | Stored separately from imported fields |
| Consumption and EIC codes | Local records; consumption is entered by administrators |
| Contract and appendix files | Uploaded and archived within the portal |
Period finance is not a sum of closing balances
The portal provides a period selector, opening balance, accrued amounts, payments and closing debt or overpayment. A range needs the first month's opening position, the selected months' turnover and the final month's closing position. Adding every monthly closing balance would calculate something different.
For illustration, an opening debt of 100, accruals of 300 and a payment of 250 produce closing debt of 150 when there are no other operations. These are educational numbers, not EBSH or customer financial results. Accounting details must be agreed with the people responsible for BAS.
One customer account can represent several companies
A consumer account can be assigned to several companies. The portal's switcher chooses the active company, and the API checks that it belongs to the user's allowed set. A browser selection does not replace server-side authorisation.
The same boundary must apply to contracts, documents, finance and consumption. Access outside an assigned company must be rejected even if the user changes an identifier in a request. The implementation includes selected-consumer and role checks.
Imports run in the background with observable status
An HTTP handler can enqueue synchronisation while a worker performs BAS operations separately from the interface response. Run states and errors help an administrator understand what completed and what needs investigation.
The import uses stable source keys, checkpoints and Redis locking for concurrent runs. Editable names and local CRM corrections do not identify an imported object. Presentation changes are separated from the process that matches source records.
Documents and consumption have their own lifecycle
The portal supports local file uploads, primarily contracts and appendices, with archiving. It is not an archive of every BAS document: the availability of each file category is part of the agreed scope.
Energy volumes are stored in MWh. Administrators enter consumption records, with filters for the period, company and contract. This should not be presented as automatic meter-reading collection or consumption imported from BAS.
What carries over to another B2B product
Before building an integration, identify the owner of each field, period rules, access boundaries and the behaviour when a source is unavailable. The API, interface and synchronisation process can then be agreed as parts of one workflow.
This analysis was prepared from the EBSH Trade implementation and delivered scope. It does not report traffic capacity, time savings or commercial results. Platform screenshots in the case study use clearly labelled demonstration data.
- Map BAS data, local fields and derived figures first.
- Check finance periods and company selection against concrete scenarios.
- Provide a synchronisation history and a way to investigate errors.
- Expose only the functions and data included in the agreed scope.
Sources and context
Working through a similar problem?
Tell us about your product, current constraints and intended outcome. We will identify a concrete next step.