Connect by JBRH Open Connect

Operator and customer, as a design idea

Connect runs one implementation for two audiences. The operator's workspace runs the platform; a customer workspace uses it. They share the code, the data model and the isolation, and differ only in which routes each may call and what a plan allows. The design decision is that a capability has one body and two doors — never two implementations that drift apart.

Status
Available What this means
Audience
both
Last verified
Product version
6.3.2

The two audiences, precisely#

Operator workspaceCustomer workspace
What it is forRunning the platform itselfRunning a business with Connect
Plan and allowanceNone — it is not a customer of itselfThe plan decides the allowance
Feature setThe same features, plus the ones that exist to run the platformThe same features
IsolationA workspace like any other, under the same rulesA workspace like any other, under the same rules
Route accessMay call operator routesMay call the routes the tenant facade allows, and no others

That last row is the whole mechanism. A customer session is not trusted to call anything an operator session can; it reaches a facade that permits the routes it is meant to have and refuses the rest. The refusal is the default state — a route nobody has deliberately opened is closed, which is the right way round for a boundary that separates businesses.

One body, two doors#

The rule the codebase is held to is that new behaviour lives in a module both routers call, and each router adds only a route. A capability therefore has one implementation, one set of rules and one place to fix a defect. What differs between the audiences is which door is open, not what is behind it.

  1. A shared module holds the behaviour, whatever it is — mailbox management, voice configuration, the approvals queue.
  2. Each router exposes it under its own path, for its own audience.
  3. The tenant facade decides whether a customer session may reach that path at all.
  4. A parity check fails when a new capability exists for one audience and not the other without a written reason.

The alternative — a customer version of a screen that renders a subset, written separately — is what the rule exists to prevent. Two implementations of the same idea do not stay the same. One gets the bug fix, the other keeps the bug, and nobody notices until a customer reports behaviour that the operator cannot reproduce.

What the pattern costs#

It is not free, and pretending otherwise would misrepresent the trade. Every change to a screen or a route costs more than it would in a single-audience product.

Two verifications per change
A change is checked as the operator and as a customer, in a browser, because a difference in what each sees is invisible in the source.
A rewrite rule for every new path
An operator path that a customer should also reach needs its customer equivalent declared, or an explicit written reason why not.
A slower first implementation
Putting behaviour in a shared module takes longer than putting it in the screen that needs it today.
Discipline about subsets
A view that shows a customer less has to be a deliberate, recorded decision rather than a shortcut somebody took once.

What is deliberately operator-only#

A small set of capabilities exist to run the platform rather than to run a business on it, and they carry the status available_owner rather than available. Verifying a payment, setting commercial terms and handling enquiries that arrive from the public website are the examples. They are not missing from a customer workspace; they would be meaningless in one.

  • available — running in production and reachable by both audiences.
  • available_owner — running in production, deliberately for the operator only.
  • Neither is a promise about the other. A capability being operator-only says nothing about whether a customer version is intended.

The distinction matters when you are reading this documentation and deciding what you can use. A page marked operator-only is describing how the platform is run, and reading it tells you something true about Connect that you cannot do yourself.

Questions#

Does the operator's workspace see customer data?

It is a workspace like any other and sits under the same isolation: the tenant facade in the middleware, the workspace kernel in the data layer, and row-level security in PostgreSQL. Being the operator is about which routes a session may call, not about a wider view of other people's records.

If a feature works for me and not for a colleague, is that this?

Usually it is permissions inside one workspace rather than the audience split. The audience split explains a difference between an operator session and a customer session; a difference between two people in the same workspace is about what each of them is allowed to do there.

Why not simply build two products?

Because they would be two products, with two sets of defects and two sets of behaviour to document. The operator running its own business on the same implementation is also the strongest daily test of it — a capability that is awkward for a customer is awkward for the operator first.