From 0c863124bb0a94cbc70029a692dbf56d5683d241 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 22 Apr 2026 05:40:12 +0100 Subject: [PATCH] refactor: derive setup promotion rules from plugins --- .../plugins/setup-promotion-helpers.test.ts | 35 ++++++++++++++----- .../plugins/setup-promotion-helpers.ts | 25 +++---------- ...hannel-contract-surface-guardrails.test.ts | 4 +++ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/channels/plugins/setup-promotion-helpers.test.ts b/src/channels/plugins/setup-promotion-helpers.test.ts index 6d70b0e71fc..40809e2c31f 100644 --- a/src/channels/plugins/setup-promotion-helpers.test.ts +++ b/src/channels/plugins/setup-promotion-helpers.test.ts @@ -22,23 +22,19 @@ describe("setup promotion helpers", () => { getLoadedChannelPluginMock.mockReset(); }); - it("keeps static named-account migration keys cheap", () => { + it("keeps static single-account migration keys cheap", () => { const keys = resolveSingleAccountKeysToMove({ - channelKey: "whatsapp", + channelKey: "demo", channel: { - accounts: { - work: { enabled: true }, - }, dmPolicy: "allowlist", allowFrom: ["+15551234567"], groupPolicy: "allowlist", - groupAllowFrom: ["120363000000000000@g.us"], + groupAllowFrom: ["group-123"], }, }); expect(keys).toEqual(["dmPolicy", "allowFrom", "groupPolicy", "groupAllowFrom"]); - expect(getLoadedChannelPluginMock).toHaveBeenCalledTimes(1); - expect(getLoadedChannelPluginMock).toHaveBeenCalledWith("whatsapp"); + expect(getLoadedChannelPluginMock).not.toHaveBeenCalled(); expect(getBundledChannelPluginMock).not.toHaveBeenCalled(); }); @@ -79,4 +75,27 @@ describe("setup promotion helpers", () => { expect(keys).toEqual(["token"]); expect(getBundledChannelPluginMock).not.toHaveBeenCalled(); }); + + it("loads bundled setup for named-account filters before registry bootstrap", () => { + getBundledChannelPluginMock.mockReturnValue({ + setup: { + namedAccountPromotionKeys: ["token"], + }, + }); + + const keys = resolveSingleAccountKeysToMove({ + channelKey: "demo", + channel: { + accounts: { + work: { enabled: true }, + }, + token: "secret", + dmPolicy: "allowlist", + }, + }); + + expect(keys).toEqual(["token"]); + expect(getLoadedChannelPluginMock).toHaveBeenCalledWith("demo"); + expect(getBundledChannelPluginMock).toHaveBeenCalledWith("demo"); + }); }); diff --git a/src/channels/plugins/setup-promotion-helpers.ts b/src/channels/plugins/setup-promotion-helpers.ts index 5caebe595ec..6e837923c71 100644 --- a/src/channels/plugins/setup-promotion-helpers.ts +++ b/src/channels/plugins/setup-promotion-helpers.ts @@ -41,16 +41,6 @@ const COMMON_SINGLE_ACCOUNT_KEYS_TO_MOVE = new Set([ "defaultTo", ]); -const BUNDLED_SINGLE_ACCOUNT_PROMOTION_FALLBACKS: Record = { - // Some setup/migration paths run before the channel setup surface has been loaded. - telegram: ["streaming"], -}; - -const BUNDLED_NAMED_ACCOUNT_PROMOTION_FALLBACKS: Record = { - // Keep top-level Telegram policy fallback intact when only auth needs seeding. - telegram: ["botToken", "tokenFile"], -}; - type ChannelSetupPromotionSurface = { singleAccountKeysToMove?: readonly string[]; namedAccountPromotionKeys?: readonly string[]; @@ -72,18 +62,15 @@ function getChannelSetupPromotionSurface( return setup as ChannelSetupPromotionSurface; } -function isStaticSingleAccountPromotionKey(channelKey: string, key: string): boolean { - if (COMMON_SINGLE_ACCOUNT_KEYS_TO_MOVE.has(key)) { - return true; - } - return BUNDLED_SINGLE_ACCOUNT_PROMOTION_FALLBACKS[channelKey]?.includes(key) ?? false; +function isStaticSingleAccountPromotionKey(key: string): boolean { + return COMMON_SINGLE_ACCOUNT_KEYS_TO_MOVE.has(key); } export function shouldMoveSingleAccountChannelKey(params: { channelKey: string; key: string; }): boolean { - if (isStaticSingleAccountPromotionKey(params.channelKey, params.key)) { + if (isStaticSingleAccountPromotionKey(params.key)) { return true; } const contractKeys = getChannelSetupPromotionSurface(params.channelKey, { @@ -118,7 +105,7 @@ export function resolveSingleAccountKeysToMove(params: { }; const keysToMove = entries.filter((key) => { - if (isStaticSingleAccountPromotionKey(params.channelKey, key)) { + if (isStaticSingleAccountPromotionKey(key)) { return true; } return Boolean(resolveSetupSurface()?.singleAccountKeysToMove?.includes(key)); @@ -128,9 +115,7 @@ export function resolveSingleAccountKeysToMove(params: { } const namedAccountPromotionKeys = - setupSurface?.namedAccountPromotionKeys ?? - getChannelSetupPromotionSurface(params.channelKey)?.namedAccountPromotionKeys ?? - BUNDLED_NAMED_ACCOUNT_PROMOTION_FALLBACKS[params.channelKey]; + setupSurface?.namedAccountPromotionKeys ?? resolveSetupSurface()?.namedAccountPromotionKeys; if (!namedAccountPromotionKeys) { return keysToMove; } diff --git a/src/secrets/channel-contract-surface-guardrails.test.ts b/src/secrets/channel-contract-surface-guardrails.test.ts index 230559ceef3..638b6cb4a8f 100644 --- a/src/secrets/channel-contract-surface-guardrails.test.ts +++ b/src/secrets/channel-contract-surface-guardrails.test.ts @@ -62,6 +62,10 @@ const CORE_SECRET_SURFACE_GUARDS = [ path: "src/config/sessions/group.ts", forbiddenPatterns: [/\bwhatsapp\b/, /@g\.us/], }, + { + path: "src/channels/plugins/setup-promotion-helpers.ts", + forbiddenPatterns: [/\btelegram\b/], + }, { path: "src/media-understanding/defaults.ts", forbiddenPatterns: [