refactor(ipc): split sync-handlers.ts god module (Phase 2.1–2.4) - #241
Merged
Conversation
Move PLATFORM_MAP, registerDevice, and persistKeysAndRegisterDevice from apps/desktop/src/main/ipc/sync-handlers.ts into a new apps/desktop/src/main/sync/device-registration.ts. This is a prerequisite for the Phase 2 sync-handlers split: these helpers are needed by multiple child handler files (auth-oauth, auth-device) and already have external consumers (sync/linking-service.ts, main/test-hooks.ts). - sync-handlers.ts shrinks 1318 → 1157 lines - No behavior change; imports redirected in linking-service.ts and test-hooks.ts - Part of Phase 2 (tech-debt-remediation.md): prep commit before splitting handlers
…2.1) Split OAuth loopback, PKCE state, and OAuth-flow handlers out of the 1157-line sync-handlers god module into a cohesive auth-oauth-handlers module with matching tests. sync-handlers continues to compose the new module's register/unregister into its public API so ipc/index.ts and session-teardown consumers stay unchanged this commit. Moved: AUTH_INIT_OAUTH, AUTH_REFRESH_TOKEN, SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE, GET_RECOVERY_PHRASE, AUTH_LOGOUT + oauthSessions map, loopback server helpers, and seedOAuthSession export. GET_RECOVERY_PHRASE consumes pendingRecoveryPhrase via a narrow getter from auth-device-handlers (still in sync-handlers for now; will land in Phase 2.2). - sync-handlers.ts 1157 → 866 lines - sync-handlers.test.ts 749 → 554 lines - New: auth-oauth-handlers.ts (364), auth-oauth-handlers.test.ts (341)
… 2.2) Split OTP, device-linking, and device-CRUD handlers (plus OTP clipboard detection + pendingRecoveryPhrase state) out of sync-handlers into a dedicated auth-device-handlers module with matching tests. performFirstDeviceSetup and getAndClearPendingRecoveryPhrase are exported so auth-oauth-handlers can drive SETUP_FIRST_DEVICE and GET_RECOVERY_PHRASE through narrow, explicit interfaces instead of reading module-private state. Moved: AUTH_REQUEST_OTP, AUTH_VERIFY_OTP, AUTH_RESEND_OTP, SETUP_NEW_ACCOUNT, GENERATE_LINKING_QR, LINK_VIA_QR, COMPLETE_LINKING_QR, LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, GET_DEVICES, REMOVE_DEVICE, RENAME_DEVICE. - sync-handlers.ts 866 → 542 lines - sync-handlers.test.ts 554 → 314 lines - New: auth-device-handlers.ts (416), auth-device-handlers.test.ts (483) - generated-ipc-invoke-map.ts + preload/generated-rpc.ts regenerated
…hase 2.3) Move attachment upload/download handlers, AttachmentSyncService + UploadQueue singletons, broadcastUploadProgress helper, and the attachmentEvents onSaved/onDownloadNeeded listeners out of sync-handlers into sync-attachment-handlers. sync-handlers.ts composes the new module's register/unregister/clear helpers through its public API so ipc/index.ts and session-teardown stay untouched this commit. Moved: UPLOAD_ATTACHMENT, GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS + R2 chunking plumbing. - sync-handlers.ts 542 → 280 lines - New: sync-attachment-handlers.ts (280 lines) with lifecycle-level test coverage (handler registration, event subscription, teardown)
After splitting OAuth, device/OTP, and attachment concerns into their own handler files, what remains in the former god-module is pure sync-engine control (status/trigger/history/queue/pause/resume/ emergency-wipe/etc.) plus startup integrity and the cross-cutting clearInMemoryAuthState composer. Rename the file to reflect that narrower role and delete the back-compat import path — memry is pre-production, so the old path has no consumers outside this branch. - apps/desktop/src/main/ipc/sync-handlers.ts → sync-core-handlers.ts - apps/desktop/src/main/ipc/sync-handlers.test.ts → sync-core-handlers.test.ts - Update imports: ipc/index.ts, ipc/index.test.ts (vi.mock path), sync/session-teardown.ts - Regenerate generated-ipc-invoke-map.ts + preload/generated-rpc.ts
Phase 2 split sync-handlers.ts into auth-oauth-handlers.ts, auth-device-handlers.ts, sync-attachment-handlers.ts, and sync-core-handlers.ts. All four compose the same imports the old god-module had (`../sync/runtime`, `../sync/http-client`, `../sync/token-manager`, etc.), so they inherit the same exemption. Without this, `pnpm check:architecture` (part of CI Lint, Typecheck, and Tests) fails with "feature IPC import of sync module" on every Phase 2 file — blocker for merging PR #241.
9 tasks
h4yfans
added a commit
that referenced
this pull request
May 6, 2026
* refactor(sync): extract device-registration module Move PLATFORM_MAP, registerDevice, and persistKeysAndRegisterDevice from apps/desktop/src/main/ipc/sync-handlers.ts into a new apps/desktop/src/main/sync/device-registration.ts. This is a prerequisite for the Phase 2 sync-handlers split: these helpers are needed by multiple child handler files (auth-oauth, auth-device) and already have external consumers (sync/linking-service.ts, main/test-hooks.ts). - sync-handlers.ts shrinks 1318 → 1157 lines - No behavior change; imports redirected in linking-service.ts and test-hooks.ts - Part of Phase 2 (tech-debt-remediation.md): prep commit before splitting handlers * refactor(ipc): extract auth-oauth-handlers from sync-handlers (Phase 2.1) Split OAuth loopback, PKCE state, and OAuth-flow handlers out of the 1157-line sync-handlers god module into a cohesive auth-oauth-handlers module with matching tests. sync-handlers continues to compose the new module's register/unregister into its public API so ipc/index.ts and session-teardown consumers stay unchanged this commit. Moved: AUTH_INIT_OAUTH, AUTH_REFRESH_TOKEN, SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE, GET_RECOVERY_PHRASE, AUTH_LOGOUT + oauthSessions map, loopback server helpers, and seedOAuthSession export. GET_RECOVERY_PHRASE consumes pendingRecoveryPhrase via a narrow getter from auth-device-handlers (still in sync-handlers for now; will land in Phase 2.2). - sync-handlers.ts 1157 → 866 lines - sync-handlers.test.ts 749 → 554 lines - New: auth-oauth-handlers.ts (364), auth-oauth-handlers.test.ts (341) * refactor(ipc): extract auth-device-handlers from sync-handlers (Phase 2.2) Split OTP, device-linking, and device-CRUD handlers (plus OTP clipboard detection + pendingRecoveryPhrase state) out of sync-handlers into a dedicated auth-device-handlers module with matching tests. performFirstDeviceSetup and getAndClearPendingRecoveryPhrase are exported so auth-oauth-handlers can drive SETUP_FIRST_DEVICE and GET_RECOVERY_PHRASE through narrow, explicit interfaces instead of reading module-private state. Moved: AUTH_REQUEST_OTP, AUTH_VERIFY_OTP, AUTH_RESEND_OTP, SETUP_NEW_ACCOUNT, GENERATE_LINKING_QR, LINK_VIA_QR, COMPLETE_LINKING_QR, LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, GET_DEVICES, REMOVE_DEVICE, RENAME_DEVICE. - sync-handlers.ts 866 → 542 lines - sync-handlers.test.ts 554 → 314 lines - New: auth-device-handlers.ts (416), auth-device-handlers.test.ts (483) - generated-ipc-invoke-map.ts + preload/generated-rpc.ts regenerated * refactor(ipc): extract sync-attachment-handlers from sync-handlers (Phase 2.3) Move attachment upload/download handlers, AttachmentSyncService + UploadQueue singletons, broadcastUploadProgress helper, and the attachmentEvents onSaved/onDownloadNeeded listeners out of sync-handlers into sync-attachment-handlers. sync-handlers.ts composes the new module's register/unregister/clear helpers through its public API so ipc/index.ts and session-teardown stay untouched this commit. Moved: UPLOAD_ATTACHMENT, GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS + R2 chunking plumbing. - sync-handlers.ts 542 → 280 lines - New: sync-attachment-handlers.ts (280 lines) with lifecycle-level test coverage (handler registration, event subscription, teardown) * refactor(ipc): rename sync-handlers → sync-core-handlers (Phase 2.4) After splitting OAuth, device/OTP, and attachment concerns into their own handler files, what remains in the former god-module is pure sync-engine control (status/trigger/history/queue/pause/resume/ emergency-wipe/etc.) plus startup integrity and the cross-cutting clearInMemoryAuthState composer. Rename the file to reflect that narrower role and delete the back-compat import path — memry is pre-production, so the old path has no consumers outside this branch. - apps/desktop/src/main/ipc/sync-handlers.ts → sync-core-handlers.ts - apps/desktop/src/main/ipc/sync-handlers.test.ts → sync-core-handlers.test.ts - Update imports: ipc/index.ts, ipc/index.test.ts (vi.mock path), sync/session-teardown.ts - Regenerate generated-ipc-invoke-map.ts + preload/generated-rpc.ts * chore(arch): extend sync-boundary IPC exemption to Phase 2 split files Phase 2 split sync-handlers.ts into auth-oauth-handlers.ts, auth-device-handlers.ts, sync-attachment-handlers.ts, and sync-core-handlers.ts. All four compose the same imports the old god-module had (`../sync/runtime`, `../sync/http-client`, `../sync/token-manager`, etc.), so they inherit the same exemption. Without this, `pnpm check:architecture` (part of CI Lint, Typecheck, and Tests) fails with "feature IPC import of sync module" on every Phase 2 file — blocker for merging PR #241.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits the 1318-line
apps/desktop/src/main/ipc/sync-handlers.tsIPC god-module into 4cohesive files plus a shared
sync/device-registration.tshelper. Behavior-preserving;no channel renames, no contract changes, no preload changes. Part of Phase 2 of
tech-debt-remediation.md (C3 in the audit).
Before: 1318 lines mixing OAuth loopback, OTP+clipboard, device linking, R2 attachment
chunking, and sync-engine control.
After: 5 files, all <500 lines, each with a single cohesive responsibility.
PLATFORM_MAP+registerDevice+persistKeysAndRegisterDevice(shared by OAuth/OTP/recovery/linking)AttachmentSyncService+ upload queue + UPLOAD/DOWNLOAD_ATTACHMENT + R2 event plumbingcheckSyncIntegrity+ composes the 3 sub-modulessync-core-handlersexposes the same public API (registerSyncHandlers,unregisterSyncHandlers,checkSyncIntegrity,clearInMemoryAuthState) soipc/index.tsandsession-teardown.tsstaysimple. Cross-module state leakage is replaced with narrow interfaces:
performFirstDeviceSetupand
getAndClearPendingRecoveryPhraseare exported from auth-device so auth-oauth can driveSETUP_FIRST_DEVICEandGET_RECOVERY_PHRASEwithout reading module-private state.Commits (5)
refactor(sync): extract device-registration module(7e1df54)refactor(ipc): extract auth-oauth-handlers from sync-handlers (Phase 2.1)(0c8c381)refactor(ipc): extract auth-device-handlers from sync-handlers (Phase 2.2)(00468cc)refactor(ipc): extract sync-attachment-handlers from sync-handlers (Phase 2.3)(e28e24f)refactor(ipc): rename sync-handlers → sync-core-handlers (Phase 2.4)(fa82ee1)Deferred
Phase 2.5 (apply
registerCommandwrapper) is not included in this PR. Migrating the18 schema-input handlers from
ipcMain.handle(…, createValidatedHandler(…))toregisterCommand(…)adds implicitwithErrorHandlerwrapping around throws, which changesthe error envelope contract for handlers that currently rely on propagating thrown errors
directly to the renderer (e.g.,
LINK_VIA_RECOVERY,APPROVE_LINKING,REMOVE_DEVICE).Deferred to a follow-up PR so the blast radius of that semantic change is reviewed in
isolation.
Test plan
pnpm lint— 0 errors (warnings unchanged from main baseline)pnpm --filter @memry/desktop exec tsc --noEmit -p tsconfig.node.json— cleanpnpm --filter @memry/desktop test— 5827/5828 pass (1 skipped, unchanged from main)pnpm ipc:check— IPC invoke map + generated RPC up to dateclearInMemoryAuthStatecomposes across 3 child modules — per CRDT sign-out memory, mixed concerns previously caused a production bug here)