feat(integration-ever-works): people matching and agent provisioning (G-P1-6)

Merged
EV
10d ago
+1110-4

What

G-P1-6 of the Gauzy ↔ Ever Works integration: people and agents, inside the flag-gated plugin @gauzy/plugin-integration-ever-works. Nothing loads unless EVER_WORKS_ENABLED=true. This PR adds no migration and no core change.

People (members ↔ employees, MEMBER links)

  • GET /mappings/:integrationTenantId/people returns the Ever Works members of the mapped organization (contract GET /members, all pages, organization-scoped with X-Scope-Slug). Each member comes with its Gauzy pairing and an optional suggestion: an exact, case-insensitive match of a verified Ever Works email with a Gauzy person. The response also lists the Gauzy people who have no pairing yet.
  • PUT /mappings/:integrationTenantId/people confirms links, removes unlinks, or acceptSuggestions. Each member and each employee is paired at most once, and a new pairing replaces the old one on either side. The change is written in one transaction. Nothing is linked silently, and unlinking removes only the pairing.
  • Agents are never offered as people.
  • Ever ID matching is not possible yet: Gauzy stores no Ever ID subjects. The member's everIdSubjects are kept on the link for when it can.

Agents (EW → Gauzy, one way, AGENT links)

  • Each Ever Works agent of a mapped organization becomes a Gauzy employee of kind agent through the platform's agent-provisioning path from #10766 (EmployeeService.createAgentEmployee: no password, no welcome email, no invite). Its employee_agent_profile has source='ever_works' and managedExternally=true, plus slug, title, capabilities, status, scope, reports-to, model, avatar and web URL (HTTPS only).
  • The address is agent-<id>@agents.invalid. .invalid (RFC 2606) can never receive mail. EVER_WORKS_AGENT_EMAIL_DOMAIN may override the domain, but it must also end in .invalid.
  • The inbound handler covers agent.created/updated/status_changed/archived/deleted/visibility_changed:
    • An event at or below the linked version is skipped.
    • An archived or deleted agent is archived (isActive=false, isArchived=true), never deleted.
    • An agent made private is unlinked and stops syncing.
    • With the mapping's agents direction off, nothing is written.
  • Ever Works owns its agents: the profile is rewritten from Ever Works on each change, and Gauzy edits are never pushed.
  • GET /mappings/:integrationTenantId/agents lists the linked agent employees. POST …/agents/import queues every agent of the organization as an initial event. Managers come first, by reporting depth. The sync loop applies them under its lease, with the version check, so an import never overwrites a newer change. The response is { queued, duplicates }.

The endpoints and events used are all in contract v1 (GET /members, GET /agents, the agent.* events). No endpoint was invented.

Not in this PR

  • Invite actions ("invite to Ever Works" / "invite to Gauzy"). Ever Works invitations need members:write, which is P2 in the contract. The Gauzy invite command/service is not exported from @gauzy/core either.
  • The UI People tab is part of the connect wizard (G-P1-11).

Verification

Local, EVERDESK3, Node 26.12.0. Per the owner's merge-first directive of 2026-10-16, the full suites run once all integration PRs are in.

  • Strict typecheck of the plugin (strict, noImplicitOverride, noPropertyAccessFromIndexSignature): no errors.
  • ever-works-agents.service.spec.ts passes 11/11 after the Greptile fixes in ed6db7ea75. These add: the mapping switch, cleared fields following Ever Works, import through the sync loop in manager-first order, and reporting depths with a cycle.
  • Originally the spec passed 7/7. It covers the mail-proof address and its override rule, provisioning through the platform path with the managed profile and the link, archive instead of delete, version skip, private → unlink, direction off, and a refusal when the provisioning path is missing (nothing half-written).
  • cspell is clean on the changed files.

🤖 Generated with Claude Code