Documentation Index
Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt
Use this file to discover all available pages before exploring further.
PersonPhone is a pivot entity that links a People record to a Phone record within a workspace, carrying metadata about the association. It implements the canonical pivot pattern with is_primary, is_verify, and label fields so a single person can hold multiple phone numbers under different categories. Records are written by the connector sync pipeline and by user-facing People mutations (add/remove phone); there is no standalone PATCH surface for individual person_phones rows. Soft-delete semantics via deleted_at are enforced, and partial unique indexes guarantee at most one primary phone per person at any time.
| Naming | Value |
|---|
| Object | PersonPhone |
Resource type (JSON:API type) | person_phone |
| Collection / records root | β (not a records root) |
| REST base | /v1/person-phones |
| Entity class | PersonPhone |
Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.
API operations
| Operation | Method & path | Status |
|---|
| List | GET /v1/person-phones | π‘ Planned |
| Retrieve | GET /v1/person-phones/{id} | π‘ Planned |
| Create | POST /v1/person-phones | π‘ Planned |
| Update | PATCH /v1/person-phones/{id} | π‘ Planned |
| Delete | DELETE /v1/person-phones/{id} | π‘ Planned |
Data model
Attributes
| Field | Type | Required | Constraints | Allowed values | Description |
|---|
| is_primary | boolean | βͺ No | DEFAULT false; partial unique index uniq_person_phones_primary_person enforces at most one row per person_pk WHERE deleted_at IS NULL AND is_primary IS TRUE | true / false | Marks this phone number as the personβs primary contact number. At most one active PersonPhone per person may have is_primary = true at a time (enforced by partial unique index). |
| is_verify | boolean | βͺ No | DEFAULT false | true / false | Indicates whether the phone number has been verified (e.g., via OTP or connector confirmation). |
| label | π system enum β person_phone_label_enum (native PostgreSQL enum) | β
Yes | DEFAULT βotherβ; stored as native enum core_api.person_phone_label_enum; values are the enum VALUE strings (lowercase) | mobile | work | personal | other | Categorises the nature or context of the phone number. Stored in a native PostgreSQL enum; the persisted value is the lowercase string (e.g. "mobile", not the TypeScript key MOBILE). |
| created_at | π system datetime | β
Yes | Set automatically on INSERT via onCreate hook; timestamptz NOT NULL | β | Timestamp when the pivot record was created. Set by the MikroORM onCreate lifecycle hook; never updated afterward. |
| deleted_at | π system datetime | null | βͺ No | Nullable timestamptz; all active-record queries must filter deleted_at IS NULL | β | Soft-delete timestamp. When set, the link between the person and phone is logically removed but the row is retained for audit. The partial indexes on person_pk and the primary-phone uniqueness constraint both scope themselves to deleted_at IS NULL. |
Relationships
| Name | Type | Required | Description |
|---|
| person | to-one (ManyToOne) | β
Yes | The People record this phone number is associated with. Foreign key person_pk β core_api.people.pk. Indexed via partial index idx_person_phones_person (person_pk WHERE deleted_at IS NULL) for forward traversal, plus partial unique index for primary-phone uniqueness. |
| phone | to-one (ManyToOne) | β
Yes | The atomic Phone record containing the actual phone number value (e.g. e164_number). Foreign key phone_pk β core_api.phones.pk. Indexed via idx_person_phones_phone (phone_pk) for reverse traversal (phones β person_phones array relationship). |
System-computed
- pk β auto-increment serial, internal join key only; never exposed in the public API
- created_at β set on INSERT by MikroORM
onCreate: () => new Date() hook; no onUpdate hook exists on this entity (no updated_at column)
- deleted_at β soft-delete field; set to current timestamp when the phone association is removed via People mutation or connector sync; null on active records
- label default β ORM default
PersonPhoneLabelEnum.OTHER (βotherβ) applied on entity construction; also enforced as DEFAULT 'other' in PostgreSQL via the native enum column
- is_primary default β ORM default
false; also DEFAULT false in PostgreSQL
- is_verify default β ORM default
false; also DEFAULT false in PostgreSQL
- Partial unique index
uniq_person_phones_primary_person β system-enforced constraint preventing more than one primary phone per person among non-deleted rows; managed at DB level, not ORM level
Example
{
"data": {
"type": "person_phone",
"attributes": {
"is_primary": true,
"is_verify": false,
"label": "mobile",
"created_at": "2025-11-14T09:23:17.000Z",
"deleted_at": null
},
"relationships": {
"person": {
"data": { "type": "people", "id": "d3a1c9e7-4f02-4b88-9c11-2e5f7a83bc40" }
},
"phone": {
"data": { "type": "phone", "id": "a7b2e451-0c3d-4e6f-8110-9d4f2c1b5e78" }
}
}
}
}
Source: apps/api/src/database/entities/PersonPhone.ts Β· domain: financial-graph Β· tier: Supporting