← All work

07 / Enterprise panels

Tenancy and Org Structure

The backbone services every other service relies on

Client
ERP platform services
Role
Senior engineer, design and build

Product work for banks and enterprises. Client and product names are not disclosed.

The challenge

Services needed one trustworthy tenant boundary, separate from user accounts and from permissions. The panel listed identity provider accounts instead of real people holding real positions, and history was overwritten whenever the organisation changed.

How it fits together

org chart as of a dateIdentity providerverified sessionsTenant servicelifecycle · domainsAuthorizationpermissionsParty modelpeople · orgs · positionsPostgreSQLtriggers · views · historyERP servicesone tenant boundary
Identity, tenancy and permissions each have one owner; the party model keeps its history and its invariants in PostgreSQL.

The approach

  1. 01

    Clear ownership

    Tenants, identities and permissions each have one owner. The tenant service never stores users and never decides access, and it says so in its contract.

  2. 02

    A lifecycle that cannot surprise

    Pending, active, suspended and archived, each with its own endpoint. Status history is written in the same transaction as the change, and a dependency check explains why a tenant cannot be deleted yet.

  3. 03

    One party model

    People and organisations share one identity root. Positions, people, assignments and employment are separate concepts, so a vacant position or a matrix reporting line is modelled, not hacked.

  4. 04

    Invariants in the database

    Triggers reject cycles even under concurrent requests, allow one active parent per period and keep employment consistent with its organisation. The tree is computed as of a chosen date from SQL views.

  5. 05

    Predictable APIs

    Optimistic concurrency with ETag and If-Match, one error format with field details and a trace id, paginated envelopes, per item results for batch validation and redacted audit events.

Results

4

tenant lifecycle states, each with its own endpoint

As of

any date: history is never overwritten

0

cycles possible, enforced in the database

Stack

PostgreSQL, REST, Keycloak, TypeScript, React Query

Next project ↗

Settlement Reports

One place for RTGS, ACH and instant payment settlements