CompanyEmail

CompanyEmail is a soft-deletable pivot (bridge) entity that links a Company to an Email address within the same workspace. Each row carries three metadata flags โ€” is_primary, is_verify, and label โ€” that characterize how the email relates to its parent company. The entity enforces a partial-unique constraint: at most one non-deleted row per company can carry is_primary = TRUE, preventing multiple primary emails on the same company. It has no public UUID of its own; it is accessed via the parent company's relationship graph, not as a first-class API resource.

NamingValue
ObjectCompanyEmail
Resource type (JSON:API type)company_email
Collection / records rootโ€” (not a records root)
REST base/v1/company-emails
Entity classCompanyEmail

Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.

API operations

OperationMethod & pathStatus
ListGET /v1/company-emails๐ŸŸก Planned
RetrieveGET /v1/company-emails/{id}๐ŸŸก Planned
CreatePOST /v1/company-emails๐ŸŸก Planned
UpdatePATCH /v1/company-emails/{id}๐ŸŸก Planned
DeleteDELETE /v1/company-emails/{id}๐ŸŸก Planned

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
is_primarybooleanโœ… YesPartial-unique index uniq_company_emails_primary_company: only one row per company_pk may have is_primary = TRUE WHERE deleted_at IS NULLtrue | falseDesignates this as the primary email address for the company. At most one non-deleted record per company can be primary. Used by computed fields and by enrichment to surface the canonical contact email.
is_verifybooleanโœ… YesNOT NULL (varchar(255) in raw DDL maps to boolean not null)true | falseIndicates whether this email address has been verified (e.g. by an enrichment pass or user confirmation). Does not affect tenant access control.
labelstringโœ… Yesvarchar(255) NOT NULLFree text; common values: 'billing', 'support', 'general', 'sales', 'contact'Semantic tag describing the purpose of this email address for the company (e.g. billing, support). Stored as free text; no enum enforced at the DB layer.
created_at๐Ÿ”’ system โ€” Dateโœ… Yestimestamptz NOT NULL; set once via MikroORM onCreate hookโ€”Timestamp when this company-email association was created. Set automatically at insert; never updated.
deleted_atDate | nullโšช Notimestamptz NULL; soft-delete sentinel โ€” all live queries must filter WHERE deleted_at IS NULLโ€”Soft-delete timestamp. NULL means the record is active. When set, the row is logically removed: the partial-unique primary-email index ignores it, and Hasura RLS / repository queries filter it out.

Relationships

NameTypeRequiredDescription
companyto-one (ManyToOne)โœ… YesThe Company this email belongs to. FK company_pk โ†’ core_api.companies.pk. Indexed together with deleted_at via idx_company_emails_company_deleted for Hasura array-relationship traversals.
emailto-one (ManyToOne)โœ… YesThe Email address record (atomic entity storing the email string). FK email_pk โ†’ core_api.emails.pk. Indexed via idx_company_emails_email. The actual address string is on the Email entity, not on this pivot.

System-computed

  • created_at โ€” set once by MikroORM onCreate: () => new Date(); never updated afterward (note: no updated_at column on this entity).
  • deleted_at โ€” written by soft-delete cascades when the parent Company is soft-deleted; also written by service-layer cleanup when an Email association is explicitly removed.
  • Partial-unique index uniq_company_emails_primary_company is maintained by the database engine; enforcement is automatic on INSERT/UPDATE WHERE deleted_at IS NULL AND is_primary IS TRUE.
  • The entity has no public UUID (*_id column). It is not directly addressable via the public API; access is always through the parent company's array relationship (e.g. company_emails on the Company resource).
  • Provenance (source_workspace_connector_pk) is not tracked on this entity; rows are written by the enrichment pipeline, connector sync (via reconciliation persister), and direct service-layer mutations โ€” the source is inferred from the parent Company's sourceWorkspaceConnector if needed.

Example

{
  "data": {
    "type": "company_email",
    "attributes": {
      "is_primary": true,
      "is_verify": true,
      "label": "billing",
      "created_at": "2025-09-14T10:22:00.000Z",
      "deleted_at": null
    },
    "relationships": {
      "company": {
        "data": { "type": "company", "id": "a3f1bc2d-0001-4e88-9c1d-000000000001" }
      },
      "email": {
        "data": { "type": "email", "id": "7e9d2a1c-0002-4b77-ab2e-000000000002" }
      }
    }
  }
}
Source: apps/api/src/database/entities/CompanyEmail.ts ยท domain: financial-graph ยท tier: Supporting