Skip to content

feat: Ever Async integration scaffold (integration-ever-async + -ui) - #9924

Draft
evereq wants to merge 1 commit into
developfrom
feat/integration-ever-async
Draft

feat: Ever Async integration scaffold (integration-ever-async + -ui)#9924
evereq wants to merge 1 commit into
developfrom
feat/integration-ever-async

Conversation

@evereq

@evereq evereq commented Aug 7, 2026

Copy link
Copy Markdown
Member

What this is

STRUCTURAL DRAFT scaffold for the Gauzy side of the Ever Async integration. It adds the new plugin pair packages/plugins/integration-ever-async (NestJS backend) + packages/plugins/integration-ever-async-ui (Angular UI) and is purely additive: no existing file is modified and the packages are not yet wired into the workspace builds — the wiring checklist below lists every registration step, so reviewers can shape the API surface before any build wiring lands.

What is Ever Async?

Ever Async is a new open-source, async-first team communication assistant by Ever Co. It listens in chat platforms (Slack/Discord), and resolves messages like "my last task" into live work context — task links, statuses, projects — pulled from connected tools. Its Gauzy connector (crates/plugins/connector-gauzy in the ever-async repo) consumes the Gauzy REST API (Bearer token + Tenant-Id header), maps the chat author to a Gauzy employee, and returns scored task context into the conversation — exactly like it does from Jira/GitHub.

Integration contract

Both halves are specified in the ever-async repo: docs/integrations/gauzy.md.

The Gauzy-side plugin (this PR) owns: the Ever Async server URL, the API token the integration uses (write-only — accepted on setup/update, never returned; only a hasApiToken flag is exposed), and the chat-user → employee mappings consumed by the connector's [connectors.gauzy.user_map] config. Tenant/organization context comes from RequestContext + the organizationId query param (Plane convention).

What's scaffolded

Backend (@gauzy/plugin-integration-ever-async) — mirrors integration-plane's topology exactly (plugin class w/ @Plugin decorator, module, controller, service, typed DTOs, settings enum, Nx project.json, tsconfigs, jest + eslint configs):

  • POST /api/integration/ever-async/setup — store server URL + write-only token + mappings (INTEGRATION_ADD)
  • GET /api/integration/ever-async/settings — settings without the token (INTEGRATION_VIEW)
  • PUT /api/integration/ever-async/settings — partial update (INTEGRATION_EDIT)
  • POST /api/integration/ever-async/verify — pings the Ever Async server's /healthz (stub for the connect wizard's test button)
  • GET /api/integration/ever-async/status, DELETE /:integrationTenantId (soft-archive)
  • DTOs: ConfigureEverAsyncIntegrationDto { serverUrl, apiToken (write-only), userMappings: [{ chatUserId, employeeId }] }, UpdateEverAsyncSettingsDto (PartialType), VerifyEverAsyncConnectionDto
  • Settings stored as IntegrationSetting rows: EVER_ASYNC_SERVER_URL, EVER_ASYNC_API_TOKEN, EVER_ASYNC_USER_MAPPINGS (JSON), IS_ENABLED

UI (@gauzy/plugin-integration-ever-async-ui) — mirrors integration-plane-ui (PluginUiDefinition, lazy module with ROUTES factory, layout w/ router-outlet + i18n bootstrap, ng-packagr build config):

  • IntegrationEverAsyncPlugin registering /pages/integrations/ever-async at integrations-sections
  • EverAsyncConnectComponent — connect wizard form (server URL + API token + Test connection button) with Nebular + reactive forms + a11y/error patterns copied from PlaneAuthorizeComponent
  • Package-local EverAsyncService HTTP client (kept local so the PR stays additive; see checklist)

Where a symbol could not be verified against a buildable workspace, the file stays minimal and carries a single // scaffold: comment saying what to wire.

Wiring checklist (deliberately NOT done in this PR)

  • Backend registration: apps/api/src/plugins.tsimport { IntegrationEverAsyncPlugin } from '@gauzy/plugin-integration-ever-async' and add it to the plugins array (same as IntegrationPlanePlugin).
  • UI registration: apps/gauzy/src/plugin-ui.config.tsimport { IntegrationEverAsyncPlugin } from '@gauzy/plugin-integration-ever-async-ui' and add it to the plugin definitions (same as the Plane UI plugin).
  • Contracts: add EVER_ASYNC = 'Ever_Async' to IntegrationEnum in packages/contracts/src/lib/integration.model.ts, then replace the local EVER_ASYNC_INTEGRATION_NAME constant in ever-async-setting.enum.ts (two as IntegrationEnum casts drop out).
  • Workspace deps / install: packages/plugins/* is already covered by the yarn workspaces glob (package.workspaces.json) — just run yarn install to link; optionally add "@gauzy/plugin-integration-ever-async": "^0.1.0" to apps/api/package.json (note: integration-plane currently resolves via the workspace without an explicit entry there — follow maintainer preference).
  • Root package.json build scripts: add plugin-integration-ever-async to build:package:plugins:post{,:prod,:docker} and build:package:api{,:prod,:docker,:dev:docker} + build:package:all:docker lists; add plugin-integration-ever-async-ui to build:integration-ui-plugins{,:prod,:docker,:dev:docker} and build:package:gauzy* + build:package:all:docker; add the per-plugin build:package:plugin:integration-ever-async{,-ui}{,:prod,:docker} script entries (mirror the integration-plane entries at lines ~241-243 / ~306-309).
  • tsconfig paths: none needed — verified integration-plane has no tsconfig.base.json path entry; plugin packages resolve via yarn workspaces + dist.
  • i18n keys: add INTEGRATIONS.EVER_ASYNC_PAGE.* to packages/ui-core/i18n/assets/i18n/*.json (en.json minimum; Crowdin for the rest): TITLE, SETUP_INFO, SERVER_URL, SERVER_URL_PLACEHOLDER, API_TOKEN, API_TOKEN_PLACEHOLDER, API_TOKEN_HINT, URL_REQUIRED, URL_INVALID, TOKEN_REQUIRED, TEST_CONNECTION, CONNECTION_OK, CONNECTION_FAILED, CONNECTED.
  • Integration catalog asset: add the integrations/ever-async.svg icon (referenced by findOrCreateBaseIntegration's imgSrc, same location as integrations/plane.svg); optionally seed the base Integration record instead of relying on runtime find-or-create.
  • UI service promotion (optional): move EverAsyncService from this package to packages/ui-core/core/src/lib/services/ever-async/ mirroring PlaneService, and export it from @gauzy/ui-core/core.
  • Follow-ups per the contract: settings page with the user-mapping table + per-project enable; integration-scoped token issuance/rotation via TenantApiKeyService (Plane's regenerate-key pattern) to replace hand-issued tokens.

🤖 Generated with Claude Code


Summary by cubic

Scaffolded the Ever Async integration with new backend and UI plugins, including setup, settings, status, and connection verification. This is purely additive and not yet wired into builds.

  • New Features

    • Backend @gauzy/plugin-integration-ever-async: plugin + module + controller + service; endpoints:
      • POST /api/integration/ever-async/setup, GET/PUT /settings, POST /verify, GET /status, DELETE /:integrationTenantId
    • Write-only API token storage; exposes hasApiToken flag
    • Settings stored via IntegrationSetting (SERVER_URL, API_TOKEN, USER_MAPPINGS, IS_ENABLED)
    • UI @gauzy/plugin-integration-ever-async-ui: plugin + routes + connect wizard with Test connection and save
  • Migration

    • Register plugins in API and web app configs
    • Add EVER_ASYNC = 'Ever_Async' to IntegrationEnum
    • Add build script entries for both packages
    • Add i18n keys INTEGRATIONS.EVER_ASYNC_PAGE.*
    • Add icon integrations/ever-async.svg

Written for commit 4d504d8. Summary will update on new commits.

Review in cubic

…sync + ui)

Structural draft: adds the backend NestJS plugin (@gauzy/plugin-integration-ever-async)
and the Angular UI plugin (@gauzy/plugin-integration-ever-async-ui) mirroring the
integration-plane / integration-plane-ui topology and conventions. Purely additive —
no existing files touched and the packages are NOT yet wired into workspace builds;
the wiring checklist is in the PR description.

Ever Async: https://github.com/ever-co/ever-async
Contract: docs/integrations/gauzy.md in the ever-async repo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3c115874-86fe-41ab-b4f6-3d29392ea0a4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
9.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

throw new HttpException('No Ever Async server URL to verify.', HttpStatus.BAD_REQUEST);
}

const healthzUrl = `${targetUrl.replace(/\/+$/, '')}/healthz`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants