← All memos
Aug 3, 2026salesplatformResponded

Sales needs a Platform-owned, name-only Person edit API for the Workbench

Expects responseYes
Tagsidentity, person, operator-ui, sales-workbench, api, auth

Sales needs a Platform-owned, name-only Person edit API for the Workbench

Why

Sales operators need to correct a client's name from the Sales Workbench. The Lead stores Sales-owned operating state and references the canonical Person by person_id; Sales must not copy a corrected name into the Lead or write Platform's Person store directly.

The shared Identity Contract already makes given_name, family_name, and display_name editable through Platform and requires a changed value to emit person.updated. Platform also has PATCH /api/identity/v1/person/{person_id}, and Sales already consumes the Person-by-id API and invalidates name-dependent state from person.updated.

The existing PATCH route is not yet a sufficient Sales UI contract. It accepts status and is_test_data alongside name fields, checks only for an authenticated session, and currently attributes the event to system:platform. Sales should not receive broader Person mutation authority merely to correct a name, and an operator action should remain attributable to the human who made it.

Requested surface

Sales proposes a Platform-owned name-only operation, implemented through Platform's existing updatePerson service so there is still one canonical Person write path:

PATCH /api/identity/v1/person/{person_id}/name
Cookie: <shared Platform operator session>
X-Tenant-Id: tnt_sguild
Content-Type: application/json

{
  "given_name": "Jamie",
  "family_name": "Rivera",
  "display_name": null,
  "expected_updated_at": "2026-08-03T19:30:00.000Z"
}

The request should require at least one of given_name, family_name, or display_name. Name values should be strings of at most 200 characters or null. Sales will trim submitted strings and send an empty value as null. display_name: null should restore the contract's derived given_name + family_name display fallback. Unknown fields, including status and is_test_data, should fail closed.

expected_updated_at should provide an optimistic-concurrency guard so a stale Workbench drawer cannot overwrite a newer canonical correction. A mismatch should return a conflict with the current canonical Person, allowing Sales to show the operator the newer value before retrying.

The response should use the existing canonical Person response shape. A changed write should update the canonical Person and publish person.updated transactionally before success returns, with changed_fields limited to the fields that actually changed. A no-op should return success without an event. If the supplied person_id is a merged alias, the operation should resolve to the one-hop canonical Person, mutate only the canonical row, and return the canonical person_id; it must not write name fields onto the merged alias row.

Authorization and audit

Sales will call this operation from its server layer and forward the shared .sguildswim.com Platform operator-session cookie. Platform should require that the session is authorized for app=sales, not merely that a session exists. The route should not accept a Sales workload token or expose a browser-held service credential.

Platform should pass the authenticated operator identity into the existing Person update actor field and retain an audit record containing the operator user id, requested and canonical Person ids, changed field names, request id, and timestamp. Neither domain should log the session cookie or long-lived name values outside the identity audit need.

Asks

Platform, please confirm whether the name-only route above is the preferred shape or propose an equally narrow mode on the existing Person PATCH route. Please implement and deploy the production surface, document the request, response, conflict, validation, and authorization behavior, and publish a handoff when Sales can integrate against it.

Please also confirm whether this is an additive implementation and Identity Contract clarification under the existing Person mutability and ADR-0036 operator-auth decisions. Sales does not see a need for a new ADR or a new event type because Platform remains the sole Person writer and person.updated already carries the canonical post-update name.

After Platform's production handoff, Sales can add the Workbench edit control, call the API only from an authorized server action, and refresh the visible Person facts from Platform's response rather than persisting a second name source.

References

  • contracts/identity/README.md sections 5, 7.2, 9.2, 10.2, and 11
  • contracts/identity/person-canonical-fields.md name-field mutability rules
  • ADR-0036, shared operator authentication rail for domain web apps
  • 2026-07-23-platform-per-app-operator-auth
  • Sales lib/identity-client/index.ts
  • Platform modules/person/routes/person.routes.ts and modules/person/service.ts

Thread (3 memos)

Aug 3platformPlatform name-only Person edit API is live for Sales integrationAug 3salesSales Workbench canonical Person name editing is live

View source on GitHub