feat(integration-ever-works): the per-entity sync settings take effect (OQ4, F77)

Merged
EV
8d ago
+681-31

Owner decision OQ4 (a) for review finding F77 (REVIEW-2026-10-17-post-merge-findings, unit G3), owner queue item I6d.

Problem

Every Ever Works mapping stores the per-entity sync toggles every Gauzy integration has (integration_entity_setting, written by PUT /mappings/:id entitySettings or the platform's integration-tenant API) and returns them, but no handler read them: an admin who set ORGANIZATION_TEAM (or TASK, DOCUMENT, …) to sync: false still had those records syncing both ways.

Change

A toggle with sync: false acts as direction off for the domains of that entity. All engine paths (inbound handlers, outbound pushes, sweeps, the initial sync and a resync) read the mapping through EverWorksMappingContextService, so the context now loads the toggles and answers the effective directions (plus entitySync):

EntityDomains turned off
Employeemembers
Agentagents
OrganizationTeamteams
Projectworks
StrategicInitiativemissions
Goalgoals
Tasktasks and ideas (an idea is a Gauzy task of the "Idea" issue type)
InboxIteminbox and agentEmail (the mirror writes Inbox items)
Documentdocs
KeyResult, Commentnone: they stop only those records (below)
  • KeyResult off: goals keep syncing without their key results. Inbound: no Gauzy key result is written and the goal snapshot keeps the key-result fields of the last sync, so turning it on again compares against the last agreed state (the next event brings them). Outbound: no sample is pushed, a KEY_RESULT change is skipped, a linked goal's push leaves the Ever Works criteria / metric / Definition of Done as they are (only its own fields go), and a new Gauzy goal is not created in Ever Works (it is made from its key results). The key-result sweep skips the mapping.
  • Comment off: tasks keep syncing without their comments: comment events skipped, comment changes not pushed, the comment sweep and the initial sync's comments phase skipped (phase spec entity: Comment).
  • A missing row is on: existing mappings keep exactly their directions.
  • Visible: GET/PUT /mappings answer effectiveDirections next to directions (additive; directions stays what the form edits). The settings page marks a domain whose record type's setting is off ("Not synced: …"), and the match review offers creates by the effective direction. The sync status already shows the context's (now effective) directions. README + DTO description.
  • Not changed: the webhook subscription keeps asking for agent mail while a mapping's agentEmail direction is on (the mirror skips it); kept so this PR stays off connection.service.ts, which #11107 changes. No contract change.

Verification

  • Red first: 11 new tests red on develop's sources (mapping context + view on SQLite, goals × 4, comments × 3, initial sync/resync), green with the change.
  • Plugin suite plugin-integration-ever-works: 43 suites, 766 tests green; plugin-integration-ever-works-ui: 6 suites, 84 tests green; .scripts/ever-works-integration.test.cjs (with a Postgres _test DB in Docker): 11/11.
  • tsc --noEmit, strict and with strict null checks off: 0 errors in scope for both plugins. prettier (touched lines), cspell, static gates (30/30) green.
  • Overlap check: #11107 / #11108 (aa3752) touch connection.service.ts, the docs content files, the ideas service, the UI connect component / ever-works.service.ts (connection interface) and the tasks service: this PR changes none of their lines (one added optional field in ever-works.service.ts's mapping interface; an en.json key in another section).

🤖 Generated with Claude Code


Summary by cubic

Makes the per-entity sync settings of Ever Works mappings take effect: a setting with sync: false now stops syncing that entity instead of being stored and ignored.

Every path that reads a mapping (inbound handlers, outbound pushes, sweeps, initial sync, resync) now goes through the mapping context, which loads the toggles and resolves the effective directions. Employee off stops members, Agent off stops agents, OrganizationTeam off stops teams, Project off stops works, StrategicInitiative off stops missions, Goal off stops goals, Task off stops tasks and ideas, InboxItem off stops inbox and agent mail, Document off stops docs. A missing row is on, so existing mappings keep their directions. KeyResult and Comment off stop only those records: goals sync without key results (none written in Gauzy, no sample pushed, a linked goal pushes only its own fields with the Ever Works criteria, metric, and Definition of Done as the last sync left them, and a new Gauzy goal is not created in Ever Works because it is made from its key results) and tasks sync without comments. A mapping that predates the toggles gets its rows created (all on) before a change is written.

The mapping API now answers effectiveDirections next to directions (additive), the settings page marks a domain whose record type setting is off, and the match review uses the effective direction. The webhook still requests agent mail while the agentEmail direction is on; made this way to avoid touching connection.service.ts.