# Relationships in Connect

Connect keeps one canonical human — a **Person** — and hangs everything else off it: the identities they answer on, the company they belong to, their lifecycle stage, their deals, cases and follow-ups, and one timeline that shows the lot. `relationship_console` answers a question about one relationship for the Owner and for a customer out of the same body of code; only the words on the screen differ.

- **Status:** Available
- **Audience:** both
- **In the app:** #/relationships, #/companies, #/timeline
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/relationships/

## Three records, and why they are three

**Person** — The canonical human. One row per human, no matter how many addresses they write from or ring from.
**Identity** — One address on one channel — an email address, a phone number, a WhatsApp handle — stored as its own row and keyed by `value_key(kind, value)`. A person may hold many.
**Company** — The organisation. Several people attach to one company, and a company carries what belongs to the organisation rather than to any individual.

Collapsing those three into one row is the mistake this model exists to avoid. A human who writes from work, replies from a personal address and then rings from a mobile is one relationship with three identities; a design that keys off the address gives you three strangers and no history. Keeping identities as rows also means adding a channel adds rows rather than columns — see [one person across phone, email and WhatsApp](/docs/relationships/cross-channel-identity/).

## One body, two doors

`relationship_console` is a single module with a thin router in front of it on each side. The Owner reaches it through the operator API; a customer reaches it through `/api/customer/ui/…` after `tenantAdapt` rewrites the path. There is no second implementation and no reduced customer view — what changes is vocabulary.

| Owner | Customer | What it answers |
|---|---|---|
| `relationships` | `people` | The same records, through the same code |
| `listing` | `listing` | The bounded list, with search and paging done in SQL |
| `detail` | `detail` | One person with their identities, stage and open work |
| `story` | `story` | The written summary, with names scrubbed on the way out |
| `by_handle` | `by_handle` | Resolution from one channel address to the person |

That rename is recorded rather than remembered: `ALIASES` in the audience parity suite carries it, which is how a capability that exists on one surface and not the other is caught as a defect instead of shipping. [Relationships for the Owner and for a customer](/docs/relationships/relationship-owner-tenant/) covers that seam in full.

## What each page here answers

- [People](/docs/relationships/people/) — the person record, and how much of it is derived rather than typed.
- [Identities](/docs/relationships/identities/) — why one address on one channel is a row of its own.
- [Companies](/docs/relationships/companies/) — what belongs to an organisation rather than to a human.
- [Customer 360](/docs/relationships/customer-360/) and [the timeline](/docs/relationships/timeline/) — the assembled views, and where each part of them comes from.
- [Duplicate detection](/docs/relationships/duplicates/), [merging](/docs/relationships/merging/) and [what a merge preserves](/docs/relationships/merge-safety/) — a proposal, a human decision, and the record that survives it.
- [Lifecycle stages](/docs/relationships/lifecycle-stages/) and [stage normalisation](/docs/relationships/stage-normalisation/) — progression, and what happens to a stage nobody recognises.

## A list is a query, not a loop

Relationship screens are lists, and lists here have a measured history. The Owner's customer list once fetched the user, the workspace and the entitlement for every membership one at a time: 1,857 accounts cost 5,574 statements. Three inner joins say the same thing in three. The unit that matters is statements rather than seconds, because a threshold in seconds measures the machine you happened to run it on.

> **Note** Cost that grows with the number of rows on screen is the shape to watch for. Every fix in this area replaced per-row work with set-based work, so the cost stopped tracking the page size — the detail is on [finding a person or company](/docs/relationships/relationship-search/) and [the customer timeline](/docs/relationships/timeline/).

## Everything in this section

16 pages, each with its own status and the date it was last checked against the running system.

| Page | What it covers |
|---|---|
| [Companies](/docs/relationships/companies/) | The company record, how several people attach to one organisation, what belongs to the company rather than to a human, and when not to create one. |
| [Customer 360](/docs/relationships/customer-360/) | One person's whole history in a single view: what is assembled into it, which service each part comes from, and what it deliberately leaves out. |
| [Duplicate detection](/docs/relationships/duplicates/) | How two records come to describe one human, what a duplicate proposal is and is not, and why nothing is ever joined without a person saying so. |
| [Finding a person or company](/docs/relationships/relationship-search/) | Finding a person or company: what is matched, why counting and paging happen in SQL, and how a per cent sign typed in the box is treated as a character. |
| [Identities](/docs/relationships/identities/) | One address on one channel is its own row: how identities attach to a person, how they are keyed, and what happens when one is attached to the wrong human. |
| [Lifecycle stages](/docs/relationships/lifecycle-stages/) | The six stages a relationship moves through, what may move it, why becoming a client needs a person, and where the history of every move is kept. |
| [Merging two records](/docs/relationships/merging/) | Merging two records is a human decision: who makes it, what happens at the moment it runs, what changes for every channel, and what cannot be undone. |
| [Normalising a stage](/docs/relationships/stage-normalisation/) | Why one column holds three vocabularies, how an unfamiliar stage word is read, and the message that went unanswered when a lookup raised instead. |
| [One person across phone, email and WhatsApp](/docs/relationships/cross-channel-identity/) | How the same human is recognised when they arrive on a second channel, what counts as evidence, and why a likeness is a proposal rather than a match. |
| [People](/docs/relationships/people/) | The person record: what you type, what Connect derives, what attaches from other services, and why blocking somebody is not a field on it. |
| [Relationships for the Owner and for a customer](/docs/relationships/relationship-owner-tenant/) | The Owner calls them relationships and a customer calls them people: the same records, the same code, and the rewrite that makes one path serve both. |
| [The contact brief](/docs/relationships/contact-brief/) | The short block about a person that a channel is given before it answers: what is in it, the character budgets, and why every line has to earn its place. |
| [The customer timeline](/docs/relationships/timeline/) | What appears on a person's timeline, where each entry comes from, the ordering rule, and the query cost that once made this screen expensive. |
| [The relationship summary](/docs/relationships/relationship-story/) | The written relationship summary: what it is assembled from, why it is not a stored document, and the name guard that rewrites it on the way out. |
| [What a merge preserves](/docs/relationships/merge-safety/) | The itemised guarantee: identities, stages, follow-ups, deals, demos, cases and onboarding all survive a merge, and what happens when both sides hold one. |
| [What Connect remembers about a person](/docs/relationships/person-memory/) | The contact tier of memory: what Connect knows about one human, how a fact gets there, how it is read into an answer, and how anyone removes it. |

## Questions

### Is a prospect the same thing as a person?

No. A prospect is an organisation or person discovered by research and not yet a relationship; a Person is a human the workspace actually deals with. Prospecting has its own section at [/docs/prospects/](/docs/prospects/), and a prospect who starts a conversation becomes a person through the same first-contact path as anybody else.

### Does a customer see fewer relationship features than the Owner?

No. Every capability here runs for both audiences over one implementation. The only differences are commercial — a customer's use is bounded by their plan's allowances — and lexical, where the customer surface says `people` for what the Owner calls `relationships`.

### Where do deals and support cases live?

On the person, but documented in their own sections: [support](/docs/support/cases/) for cases and onboarding, [sales](/docs/sales/opportunities/) for opportunities and demos. A merge carries all of them, which is why [merge safety](/docs/relationships/merge-safety/) names each one.

## Related

- [People](https://connectbyjbrh.com/docs/relationships/people/)
- [Identities](https://connectbyjbrh.com/docs/relationships/identities/)
- [Customer 360](https://connectbyjbrh.com/docs/relationships/customer-360/)
- [The customer timeline](https://connectbyjbrh.com/docs/relationships/timeline/)
- [Sales in Connect](https://connectbyjbrh.com/docs/sales/)
- [Support cases](https://connectbyjbrh.com/docs/support/cases/)

## What this page is based on

- `docs-source/sources/CHANNELS.md` §5 — relationships and CRM
- `docs-source/sources/GENERAL.md` §1 and §3 — the two audiences and the data model
- Connect capability registry (docs-source/facts.py)
