086830f81b
## Problem Updating credentials for an existing IMAP/SMTP/CalDAV connected account in **Settings → Accounts → Connection settings** has no effect on the sync. The save persists the new `connectionParameters`, but `messageChannel.syncStatus` / `messageChannel.syncStage` / `connectedAccount.authFailedAt` are left untouched, and no fetch job is queued. This matters most when the channel is in `FAILED_INSUFFICIENT_PERMISSIONS` (e.g. after Apple invalidates iCloud app-specific passwords, or on any other auth failure): `MessagingRelaunchFailedMessageChannelsCronJob` only retries `FAILED_UNKNOWN`, so the account is stuck on "Sync failed" forever despite the credentials now being correct. The only known workarounds are a direct DB update or deleting and recreating the account. #19273 fixed the frontend cache angle of credential editing; this PR fixes the backend half of the same UX (the channel state machine). ## Reproduce 1. Connect an IMAP/SMTP account. 2. Force an auth failure (e.g. revoke the app-specific password upstream). Wait until `messageChannel.syncStatus` flips to `FAILED_INSUFFICIENT_PERMISSIONS`. 3. Generate a fresh password, edit the account in **Settings → Accounts**, save. 4. Observe: account stays "Sync failed" indefinitely; `core.messageChannel.syncStatus` and `core.connectedAccount.authFailedAt` are unchanged; no IMAP connect attempt in the worker logs. ## Root cause `packages/twenty-server/src/modules/connected-account/services/imap-smtp-caldav-apis.service.ts → processAccount` saves the updated `connectionParameters` but never resets the sync state nor enqueues a fetch job. The OAuth providers handle this: | Reset step | `google-apis.service.ts` | `microsoft-apis.service.ts` | `imap-smtp-caldav-apis.service.ts` (before this PR) | |---|---|---|---| | `updateConnectedAccountOnReconnect` (clears `authFailedAt`) | yes | yes | — | | `accountsToReconnectService.removeAccountToReconnect` | yes | yes | — | | `resetAndMarkAsMessagesListFetchPending` | yes | yes | — | | Enqueue `MessagingMessageListFetchJob` | yes | yes | — | | `resetAndMarkAsCalendarEventListFetchPending` | yes | yes | — | | Enqueue `CalendarEventListFetchJob` | yes | yes | — | #12061 introduced this behaviour for Google/Microsoft. The IMAP service was added later and the equivalent reconnect plumbing was never ported. ## Fix Mirrors the Google/Microsoft pattern in `processAccount`: - **Inside** the transaction, when an account already exists: clear `authFailedAt` on the connected account. - **After** the transaction, when an existing account is being updated: - drop the account from `accountsToReconnect` user-vars, - if the message channel exists and IMAP is configured, call `resetAndMarkAsMessagesListFetchPending` and enqueue `MessagingMessageListFetchJob` (skipped while the channel is still `PENDING_CONFIGURATION`), - same logic for the calendar channel and `CalendarEventListFetchJob`. Wires `MessageChannelSyncStatusService`, `CalendarChannelSyncStatusService`, `AccountsToReconnectService` and the messaging/calendar queues into `IMAPAPIsModule`. ## Tests - Extended the existing `should preserve existing channels when updating account credentials` case to assert: `authFailedAt: null` is written within the transaction; `removeAccountToReconnect` is called with the resolved `userId`; `resetAndMarkAs*` and queue `add` are called for both channels. - New case: `should not queue fetch jobs for channels still in PENDING_CONFIGURATION`. - New case: `should not run reconnect logic when creating a brand new account`. I could not run the full server test suite locally (no `node_modules` checked out); relying on CI. ## Out of scope - Extending `UpdateConnectedAccountOnReconnectService` to a non-OAuth shape: kept inline to minimise the blast radius. Refactoring opportunity for a follow-up. - Behaviour when the user removes IMAP or CALDAV from the parameters on update (the channel currently lingers in its old state). Pre-existing and not made worse by this PR.