Sales for the Owner and for a customer
There is no operator edition of the pipeline. The same sales.py serves the Owner's workspace and every customer workspace, over the same stage rules and the same refusal to invent terms. A plan bounds how much a workspace may do, never which screens exist. Two commercial surfaces are operator-only because they are about running the platform.
One body, two doors#
A customer session reaches the pipeline through the tenant facade: tenantAdapt rewrites the Owner path to its customer equivalent, and anything the facade does not recognise becomes a blocked call rather than a guess. Behind both doors the same service answers, which is why a behaviour that differs between the two audiences is almost always the facade or the allowlist rather than the feature.
| Concern | Owner | Customer |
|---|---|---|
| Pipeline, stages, stage rules | The same service | The same service, reached through the facade |
| Deal values in minor units | Identical | Identical |
| Refusal to invent terms | Identical | Identical |
| Volume | No plan, no allowance | Bounded by the plan's allowances |
| Naming | relationships | people — the customer surface renames it |
The two operator-only screens#
Both are about operating the platform rather than selling with Connect, which is the only reason a surface is ever restricted to one audience.
- Verifying customer payments
platform_payments.py. Confirming that a workspace has paid for its plan is JBRH's own billing operation. A customer verifying their own payment would be checking their own homework.- JBRH's own pricing
commercial.py. What Connect itself costs is the operator's commercial data, not a feature of the product a customer uses to sell their own goods.
Website enquiries addressed to JBRH sit in the same category for a different reason: connect_inquiries is a control-plane table outside every workspace by design. A customer asking why an enquiry is not in their workspace is seeing isolation working.
How parity is kept honest#
Parity here is enumerated rather than asserted. A suite reads the flattened route table out of the running application and compares every Owner capability against every customer one.
- A new capability that exists for one audience only fails the suite, so the gap has to be deliberate and written down.
KNOWN_GAPSlists what a customer still cannot reach, each entry with a reason. It may shrink and must never grow.- Closing a gap without removing its entry also fails, so the list cannot quietly become fiction.
- Isolation is enforced three times regardless: the allowlist in the middleware, the workspace kernel in the ORM, and row-level security in the database.
What a plan actually bounds#
Allowances are about volume and cost, not capability. A customer workspace whose daily allowance is spent still has the pipeline, the stage rules, the escalation queue and the documents — what it does not have is another send today. The Owner's workspace has no plan, which makes it a poor place to notice an allowance problem and a good place to reproduce one deliberately.
Questions#
Do customers get a cut-down pipeline?
No. There is no operator-only sales feature and no customer-only one. The difference is commercial: a plan decides allowances, and the operator's workspace has none.
Why can I not see who has paid for their plan?
Because that is JBRH operating the platform rather than a workspace using Connect. Your own plan and usage are visible to you on #/billing; other workspaces' payments are not part of the product you are using.
Is my pipeline visible to the operator?
Your workspace's records are isolated three times over — allowlist, ORM kernel, and row-level security in the database. A row without your workspace stamp is invisible rather than merely filtered out of a view.