Skip to main content
Phone is a shared atomic resource representing a single telephone number stored in its canonical decomposed form: ITU-T country-calling-code, national-number string, and the derived E.164 number. It is linked to People and Company records through pivot entities (PersonPhone, CompanyPhone) that carry relationship-level metadata such as primary/verified status and a label. A Phone always belongs to a workspace via a nullable integer FK (workspace_pk) added in Migration20260119180000 and is soft-deletable. It is exposed as a records root named “phones” in the data-views pipeline with composite columns resolving linked companies and people.

API operations

Data model

Attributes

Relationships

System-computed

  • phone_id is generated by gen_random_uuid() at the database level on INSERT and carries a UNIQUE constraint. It is the public API identifier; the internal pk (serial int) is never exposed.
  • created_at is set via MikroORM onCreate lifecycle hook (new Date()) and is immutable thereafter.
  • updated_at is set on both INSERT (onCreate) and every UPDATE (onUpdate) via lifecycle hooks.
  • deleted_at is null by default. Setting it to a non-null timestamp performs a soft-delete. All reads must include a deleted_at IS NULL predicate. Hard-deletes are not used for Phone rows.
  • workspace FK column in the DB is workspace_pk (int, nullable FK → core_api.workspaces.pk, ON DELETE SET NULL), added by Migration20260119180000. Pre-migration rows have workspace_pk = NULL. The entity declares the relation nullable: true. There is no UUID workspace_id column on the phones table.
  • The PersonPhone pivot enforces a partial unique index (uniq_person_phones_primary_person) so that at most one PersonPhone per person_pk has is_primary = TRUE while deleted_at IS NULL.
  • The CompanyPhone pivot enforces a parallel partial unique index (uniq_company_phones_primary_company) so that at most one CompanyPhone per company_pk has is_primary = TRUE while deleted_at IS NULL.
  • In the data-views pipeline, the phones root exposes two composite columns: composite_companies_list (display_type: relation_list, source_fields: company_phones.company.company_id + company_phones.company.name) and composite_people_list (display_type: relation_list, source_fields: person_phones.people.person_id + person_phones.people.full_name). These are defined in composites.yml under the phones root.
  • On company and person records roots, composite_phones_list composites surface linked phone numbers (source_fields: .phone.phone_id + .phone.e164_number) for display in the records table.

Example

Source: apps/api/src/database/entities/Phone.ts · domain: financial-graph · tier: Supporting