# Customer Records (CRM)

## Contacts as Source of Truth

The **contact record** is the highest-level directory for every customer relationship. Its phone number and name are the canonical identifiers — all user-scoped data (memory profiles, conversations, documents, events) hangs off the contact via the phone number.

| Concept | What it is | Storage |
|---------|-----------|---------|
| **Contact record** | Structured directory entry (phone, name, pipeline status, address) | Neo4j graph via `contact_*` tools |
| **User memory** | Freeform narrative, conversation history, media, documents | `memory/users/{phone}/` via `memory_*` tools |

The contact record determines the relationship. User memory provides the detail. A memory profile without a contact record is orphaned data. A contact record without memory is a directory entry awaiting context.

## Tools

| Tool | Access | Purpose |
|------|--------|---------|
| `contact_create` | Admin only | Create a new contact record (phone + name + optional fields) |
| `contact_lookup` | All agents | Search by phone number or name. Use before every customer interaction |
| `contact_update` | Admin only | Update record fields or rename a contact. Use after every meaningful event |
| `contact_delete` | Admin only | Remove a contact record. Does not delete user memory |
| `contact_is_bot` | All agents | Check whether a phone number belongs to a registered bot. Returns `is_bot`, and when true, the owner's name and phone |

### Creating a Contact Record vs Creating User Memory

These are distinct operations:

- **`contact_create`** — Creates a structured directory entry in the secure records store. Use when you have a name and phone number for a new customer.
- **`memory_write` to `memory/users/{phone}/profile.md`** — Creates or updates the freeform narrative profile. Use to store context, personality, preferences, and history.

On first meaningful interaction, do **both**: create the contact record, then write an initial memory profile.

## When to Create a Record

Create a contact record on the **first meaningful interaction** with a new customer — when you have at least a name and phone number. Do not create records for:
- Spam or wrong numbers
- One-off enquiries that go nowhere (unless the business owner asks you to)

## Inbound Enquiries Also Arrive via the Site Form → D1

Not every new contact comes in by phone or WhatsApp. The business's **published-site contact form** is a primary inbound-enquiry channel, and its submissions land as rows in a Cloudflare **D1** database, not as messages — nothing surfaces them automatically. When the owner asks about new sign-ups, contacts, or enquiries, read D1 first, then turn each new row into a contact record here. See `references/site-lead-intake.md` for the read-first-from-D1, dedupe, create-or-update, sweep-after-write capability.

A new site lead is routed to the install's **recorded front-line owner** — and that ownership is **operator data** (recorded on the graph, or asked of the operator if not yet recorded), never a guessed name and never baked into a reference. Routing a lead to whoever seems plausible is the mistake; route to the recorded owner.

## When to Update a Record

Update the contact record after every event that changes the customer's status or adds useful information:
- New job booked → update `status` to `booked`, add `lastContact`
- Quote sent → update `status` to `quoted`
- Job completed → update `status` to `completed`, update `lastJob`
- Invoice sent → update `status` to `invoiced`
- Payment received → update `status` to `paid`
- New address or contact details provided
- Notable preferences discovered ("prefers mornings", "dog in garden")

## Standard Fields

| Field | Description | Example |
|-------|-------------|---------|
| `name` | Full name (set via `contact_create`, update via `contact_update` with field `name`) | `Mrs Sarah Jenkins` |
| `status` | Pipeline stage | `enquiry`, `quoted`, `booked`, `completed`, `invoiced`, `paid`, `archived` |
| `address` | Full postal address | `42 Oak Lane, Stansted, CM23 4AB` |
| `postcode` | Extracted postcode (for geographic clustering) | `CM23 4AB` |
| `source` | How they found the business | `referral`, `Google`, `WhatsApp`, `repeat customer` |
| `notes` | Brief context | `Elderly, prefers mornings. Has a dog.` |
| `lastJob` | Date and description of most recent job | `2026-02-20 Boiler service` |
| `lastContact` | Date of most recent interaction | `2026-02-24` |
| `bot_number` | Phone number of a bot owned by this customer (E.164) | `+447700900099` |
| `bot_number_N` | Additional bot numbers (`bot_number_1`, `bot_number_2`, etc.) | `+447700900100` |

## Pipeline Stages

```
enquiry → quoted → booked → completed → invoiced → paid
                                                     ↓
                                                  archived
```

- **enquiry** — Customer has made contact, no quote or booking yet
- **quoted** — Quote sent, awaiting response
- **booked** — Job scheduled
- **completed** — Job done, not yet invoiced
- **invoiced** — Invoice sent, awaiting payment
- **paid** — Payment received
- **archived** — Customer is inactive (no contact for 6+ months, or explicitly closed)

Update the status at each transition. This enables the business owner to see their pipeline at a glance.

## Bot Number Registration

Customers who operate their own bots (e.g. an automated service) can have those bot phone numbers registered on their contact record. This enables inbound bot detection — when a message arrives from a registered bot number, the system identifies it as automated rather than human.

**Registering a bot number:** Use `contact_update` to set a `bot_number` field on the customer's contact record. The value is the bot's phone number in E.164 format. If a customer has multiple bots, use `bot_number_1`, `bot_number_2`, etc.

**Checking inbound messages:** `contact_is_bot` takes a phone number and returns whether it belongs to a registered bot. When `is_bot` is true, the response includes the owner's name and phone number — the human customer who registered the bot. Use this to avoid treating automated messages as customer conversations.

## Contact Records vs User Memory

Contact records and memory serve different purposes. Use both.

| | Contact Records | User Memory |
|---|---|---|
| **Store** | `contact_create` / `contact_update` / `contact_lookup` | `memory/users/{phone}/profile.md` |
| **Structure** | Key-value fields (name, status, address, etc.) | Freeform narrative |
| **Purpose** | Directory entry, pipeline tracking, structured queries | Context, personality, history |
| **Example** | `status: invoiced`, `postcode: CM23 4AB` | "Mrs Jenkins is elderly, lives alone, prefers morning appointments. She had a boiler service last month and was very happy with the work." |

When searching for a customer, check **both**: `contact_lookup` for structured data, `memory_search` for context.

## Document Linking

Customer documents are filed at `memory/users/{phone}/documents/`. The phone number in the contact record matches the phone number in the folder path. See `references/document-management.md` for the full filing system.

When creating documents for a customer, always:
1. Verify the contact record exists (`contact_lookup`)
2. Create the record if needed (`contact_create`) or update it (`contact_update`)
3. File the document in the correct path
4. Update the contact record status
