CompanyPerson

CompanyPerson is a soft-deletable pivot entity that links a Company to a People record within the financial graph, capturing the nature of the relationship between the two (contact, employee, owner, or other). It is written exclusively by connector sync and enrichment pipelines โ€” no public resource PATCH route exists. Because Company is workspace-scoped, every CompanyPerson row is implicitly tenant-isolated through its company foreign key. The entity carries no UUID public identifier of its own; callers reference it only through its parent associations.

NamingValue
ObjectCompanyPerson
Resource type (JSON:API type)company_person
Collection / records rootโ€” (not a records root)
REST base/v1/company-people
Entity classCompanyPerson

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

API operations

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

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
relationship_typeenum (relationship_type_enum โ€” PostgreSQL native enum)โœ… YesDEFAULT 'other'; native enum stored in core_api schema; NOT NULLcontact | employee | owner | otherDescribes how the person is related to the company. Stored as the enum value string ('contact', 'employee', 'owner', 'other') in the database via the native PostgreSQL enum relationship_type_enum. Defaults to 'other' when the connector does not provide a more specific classification.
created_at๐Ÿ”’ system โ€” timestamptzโœ… YesNOT NULL; set by MikroORM onCreate hook; never updatedโ€”Timestamp recording when this company-person link was first persisted. Set automatically on insertion; never modified.
deleted_attimestamptz | nullโšช NoNullable; NULL means active; non-NULL means soft-deletedโ€”Soft-delete timestamp. All queries must include a WHERE deleted_at IS NULL predicate. The partial indexes idx_company_people_person and idx_company_people_company both filter on deleted_at IS NULL, so deleted rows are excluded from indexed lookups automatically.

Relationships

NameTypeRequiredDescription
companyto-one (ManyToOne โ†’ Company)Yes โ€” NOT NULL FKThe Company this person is associated with. Foreign key company_pk references core_api.companies.pk ON UPDATE CASCADE. A partial index idx_company_people_company on company_pk WHERE deleted_at IS NULL ensures efficient lookups of all active contacts/employees for a given company.
personto-one (ManyToOne โ†’ People)Yes โ€” NOT NULL FKThe People record this company link targets. Foreign key person_pk references core_api.peoples.pk ON UPDATE CASCADE. A partial index idx_company_people_person on person_pk WHERE deleted_at IS NULL enables fast enumeration of all active company memberships for a given person.

System-computed

  • created_at โ€” set by MikroORM onCreate: () => new Date() hook; written once on insertion, never updated by the application layer.
  • deleted_at โ€” set to the current timestamp by the soft-delete logic; never hard-deleted in normal operation. Cascades from parent soft-delete (Company or People) are handled at the service layer, not via database CASCADE.
  • company_pk (FK) โ€” resolved from the company relation by MikroORM before flush; not exposed as a standalone API attribute.
  • person_pk (FK) โ€” resolved from the person relation by MikroORM before flush; not exposed as a standalone API attribute.
  • pk โ€” auto-increment serial primary key; internal join key only, never exposed in API responses.
  • Partial indexes โ€” idx_company_people_company and idx_company_people_person are defined on the entity class via @Index({ expression: 'CREATE INDEX ... WHERE deleted_at IS NULL' }) decorators; they are owned by the migration layer, not runtime logic.
  • No updated_at column โ€” CompanyPerson is insert-and-soft-delete only; there is no updated_at hook or column on this entity.

Example

{
  "data": {
    "type": "company_person",
    "attributes": {
      "relationship_type": "employee",
      "created_at": "2025-09-14T10:22:00.000Z",
      "deleted_at": null
    },
    "relationships": {
      "company": {
        "data": { "type": "company", "id": "b3f2a1c4-8d47-4e2b-9f35-1a2b3c4d5e6f" }
      },
      "person": {
        "data": { "type": "people", "id": "e7a0f912-3b56-41dc-a8f1-0c1d2e3f4a5b" }
      }
    }
  }
}
Source: apps/api/src/database/entities/CompanyPerson.ts ยท domain: financial-graph ยท tier: Supporting