CompanyLocation

CompanyLocation is a pivot (bridge) entity that links a Company to a Location with junction-level metadata. It records whether a given address is the company's primary address (is_primary), whether it is the registered legal address (is_legal), and a human-readable label (e.g. "Headquarters", "Billing"). A partial unique index enforces at most one primary location per company at any given time (scoped to non-deleted rows). The entity carries no public UUID of its own; in JSON:API responses the id is borrowed from the linked Location record.

NamingValue
ObjectCompanyLocation
Resource type (JSON:API type)location
Collection / records rootβ€” (not a records root)
REST base/v1/company-locations
Entity classCompanyLocation

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

API operations

OperationMethod & pathStatus
ListGET /v1/company-locations🟑 Planned
RetrieveGET /v1/company-locations/{id}🟑 Planned
CreatePOST /v1/company-locations🟑 Planned
UpdatePATCH /v1/company-locations/{id}🟑 Planned
DeleteDELETE /v1/company-locations/{id}🟑 Planned

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
is_primarybooleanβœ… YesPartial unique index: at most one row per company_pk WHERE deleted_at IS NULL AND is_primary IS TRUEtrue / falseMarks this address as the company's primary location. Enforced unique per company among non-deleted rows.
is_legalbooleanβœ… YesNo uniqueness constraint; multiple legal addresses allowed.true / falseMarks this address as the company's registered legal address. Does not enforce uniqueness.
labelstringβœ… Yesvarchar(255)β€”Free-text label describing the address role (e.g. "Headquarters", "Billing", "Warehouse").
created_atπŸ”’ system β€” Dateβœ… YesSet on insert via MikroORM onCreate hook; never updated.β€”Timestamp when this company–location pivot row was created.
deleted_atDate | nullβšͺ NoNullable; null = active row. Soft-delete pattern β€” hard deletes are not performed.ISO 8601 timestamp or nullSoft-delete timestamp. When set, the pivot is considered removed and filtered from all active queries. Drives the partial unique index on is_primary.

Relationships

NameTypeRequiredDescription
companyto-one (ManyToOne)βœ… YesThe Company that owns this address. FK: company_pk β†’ core_api.companies.pk. Indexed via idx_company_locations_company_deleted (company_pk, deleted_at).
locationto-one (ManyToOne)βœ… YesThe Location (atomic address record) this pivot points to. FK: location_pk β†’ core_api.locations.pk. Indexed via idx_company_locations_location (location_pk). The Location's public location_id UUID is used as the JSON:API id for this pivot resource.

System-computed

  • created_at β€” set on INSERT via MikroORM @Property({ onCreate: () => new Date() }); no updated_at on this entity.
  • deleted_at β€” written by soft-delete logic (never hard-deleted); filters the partial unique index for is_primary enforcement.
  • Partial unique index uniq_company_locations_primary_company β€” enforced by the database: CREATE UNIQUE INDEX ... ON core_api.company_locations (company_pk) WHERE deleted_at IS NULL AND is_primary IS TRUE. Prevents duplicate primary addresses at the DB level.
  • No public UUID on the pivot itself β€” JSON:API id in responses is the linked Location's location_id (gen_random_uuid on Location, not CompanyLocation).
  • Pivot rows are written by the connector sync pipeline (enrichment / reconciliation) and via the POST /v1/workspaces/:workspace_id/companies/:company_id/locations endpoint. The is_legal flag is set by the pipeline; users cannot toggle it.
  • Composite index idx_company_locations_company_deleted (company_pk, deleted_at) added in Migration20260416100000 to cover array-relationship traversal (companies β†’ company_locations) after sequential-scan regressions.

Example

{
  "data": {
    "type": "location",
    "id": "a3f7c281-9e4b-4d02-b1e5-6c8d2f3a0b12",
    "attributes": {
      "full_address": "15 Rue de la Paix, 75001 Paris, France",
      "address_line1": "15 Rue de la Paix",
      "address_line2": null,
      "city": "Paris",
      "region": "Île-de-France",
      "postal_code": "75001",
      "country": "FR",
      "is_primary": true,
      "is_legal": true,
      "label": "Headquarters",
      "created_at": "2025-11-03T14:22:00.000Z",
      "deleted_at": null
    }
  }
}
Source: apps/api/src/database/entities/CompanyLocation.ts Β· domain: financial-graph Β· tier: Supporting