Add primary contact for multi-contact workorders

Objective

  1. Let teams designate a single primary contact on a workorder when multiple clients or agents (or other roles) are attached, so CRM attribution, reporting, and day-to-day ops have a clear main point of contact.
  2. Define and document how the system chooses a default primary contact when multiple people are on the job (including creation, imports, and any fallbacks), and expose a way for internal staff to change that primary when the default is wrong—without relying on workarounds.
  3. Keep downstream behavior (payments, integrations, exports) aligned with whatever “primary” means once defaults and overrides exist.

Background

  • When multiple agents or clients are attached to a workorder, teams need one contact marked as primary. That supports CRM attribution, reporting, and operational clarity for who the main point of contact is.
  • SE request (original intake note on the ticket).
  • Today the primary flag exists on embedded people rows and is set in some flows (e.g. job creation from selected contacts), but defaulting when there are several contacts—and staff control to fix it—are not fully productized: internal users need an explicit rule for “who counts first” plus a manual path to override.
  • Related theme: Another ticket in Linear is linked as related around invoice / “invoice to” identity when multiple people exist—worth coordinating so primary contact, invoice recipient (_invoiceContactId), and display heuristics stay coherent.

Scope

Backend

  • attik-backend/src/models/peopleSchema.ts — Each people row includes primary (boolean); same idea on quotes in attik-backend/src/models/quoteSchema.ts.
  • attik-backend/src/util/functions/inspection/createInspection.ts — Sets primary from selectedContacts when creating an inspection (primary: contact.primary || false).
  • attik-backend/src/routes/inspection.tsPATCH assigns b.people wholesale; defaulting and uniqueness rules for primary, if any, live in whatever validation or normalization exists around that payload (worth tracing when defining defaults and staff edits).
  • attik-backend/src/util/functions/priorityLab/buildPriorityLabPayload.ts — Uses people.find((p) => p.primary && p._contactId) before other fallbacks—integrations already assume primary can be meaningful.
  • attik-backend/src/config/exportFieldDefinitions.ts — People export exposes primary as “Primary on job” (peopleFields).

Frontend — defaults vs manual change

  • attik-frontend/src/util/functions/payments/primaryContactFromInspectionPeople.ts — Today’s default contact id for some flows: first row with primary, else people[0]. Any new “official” default rule should stay consistent with this helper or deliberately replace it and update callers.
  • attik-frontend/src/app/tools/inspections/[id]/components/WorkorderPage.tsx — Add/remove person flows PATCH inspection/:id with people; new rows use primary: false and existing primary is copied through on rebuild—there is no dedicated UI here (in the reviewed code) to toggle who is primary; internal manual change implies adding that (or equivalent) on the workorder contacts experience.
  • attik-frontend/src/app/client/job/[slug]/pay-beta/PaymentBetaClient.tsx and attik-frontend/src/app/client/job/[slug]/pay-beta/components/PayAtCloseTab.tsx — Use primaryContactIdFromInspectionPeople for payer-style defaults; behavior will follow whatever people[].primary and ordering rules become.

Mobile

  • attik-mobile/app/(app)/inspection/[id].tsx — Surfaces multiple contacts for portal actions; may need alignment once web defines primary and defaults.

Decision needed

  • Exact default algorithm when multiple contacts share a job (e.g. first primary from scheduler, first Client role, single primary: true invariant, behavior on Spectora/import). Decision needed: whether exactly one primary: true per inspection is enforced globally or per policy.
  • Internal-only editing (tools) vs also client-facing changes; conflict rules when staff clear or move primary.

References

  • Data model: attik-backend/src/models/peopleSchema.ts
  • Default id resolution today: attik-frontend/src/util/functions/payments/primaryContactFromInspectionPeople.ts
  • Workorder people PATCH assembly: attik-frontend/src/app/tools/inspections/[id]/components/WorkorderPage.tsx
  • Inspection update route: attik-backend/src/routes/inspection.ts

Additional transcript context

  • The discussion clarified that there are two distinct use cases that should both be supported by a primary contact concept.
  • Agent use case: when multiple buyer agents are attached, one agent should be flagged as primary so the correct agent is used in the HubSpot payload.
  • Client use case: when multiple clients are attached (for example spouses or co-buyers), staff want to collect both contacts but still identify the main person for calls, texts, and other communications.
  • The team also raised the question of whether downstream communications such as HomeBinder and messaging actions should optionally target the primary client only in some workflows.
  • This means the feature should not be treated as a purely visual marker for client care; it has concrete downstream implications for CRM mapping, communication targeting, and contact selection in integrations.

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

About 1 month ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.