fix(kill-switch-client): point at /settings/kill-switch (the real endpoint)

The client was calling GET ${baseUrl}/flags/kill-switch which does
not exist on platform-service. The actual kill-switch endpoint lives
under /settings/kill-switch in the settings module (public, no auth
required). The bug was silently masked by the client's fail-open
behavior on non-OK responses, but it produced a 404 on every page
load for every consumer (NoteLett, MindLyst, ChronoMind, FlowMonk,
NomGap, PeakPulse, JarvisJr, LysnrAI, ActionTrail, EffoRise, Local
Memory GPT).

Discovery: running the deployed NoteLett docker stack against the
sibling platform-service, every page load triggered:
  GET http://localhost:4003/api/flags/kill-switch?platform=web → 404
Confirmed by curl-ing both endpoints directly:
  /api/flags/kill-switch        → {"message":"Route GET:/api/flags/kill-switch not found"}
  /api/settings/kill-switch     → {"enabled":true,"disabled":false,"message":""}

Also adds the productId as a query param. The server route accepts
productId from the query string OR an x-product-id header — sending
both is harmless and improves debuggability when grepping logs.

Updated JSDoc and the corresponding test assertion. Test count
unchanged (6 passed).

Verified:
  pnpm --filter @bytelyst/kill-switch-client test → 6/6 passed
  pnpm --filter @bytelyst/kill-switch-client build → ok
  curl /api/settings/kill-switch?productId=notelett → 200 with payload
This commit is contained in:
saravanakumardb1 2026-05-23 10:16:54 -07:00
parent 50db3ea621
commit 7e08cce95f
2 changed files with 10 additions and 3 deletions

View File

@ -79,7 +79,7 @@ describe('createKillSwitchClient', () => {
await ks.check();
expect(fetchMock).toHaveBeenCalledWith(
expect.stringContaining('/flags/kill-switch'),
expect.stringContaining('/settings/kill-switch'),
expect.objectContaining({
headers: expect.objectContaining({ 'x-product-id': 'testapp' }),
})

View File

@ -1,7 +1,7 @@
/**
* Browser/React Native-safe kill switch client for platform-service.
*
* Checks GET /api/flags/kill-switch to determine if the app is disabled.
* Checks GET /api/settings/kill-switch to determine if the app is disabled.
* Fail-open: returns { disabled: false } on any network error.
*
* @example
@ -49,8 +49,15 @@ export function createKillSwitchClient(config: KillSwitchClientConfig): KillSwit
? globalThis.crypto.randomUUID()
: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
// Endpoint lives under /settings/kill-switch in platform-service's
// settings module (no auth required). The route reads the
// `kill_switch` feature flag from the flags container and returns
// { enabled, disabled, message }. Older versions of this client
// pointed at /flags/kill-switch which does not exist; that bug
// was masked by fail-open behavior on 404 but produced noisy
// 404s on every page load.
const res = await globalThis.fetch(
`${baseUrl}/flags/kill-switch?platform=${encodeURIComponent(platform)}`,
`${baseUrl}/settings/kill-switch?platform=${encodeURIComponent(platform)}&productId=${encodeURIComponent(productId)}`,
{
headers: { 'x-product-id': productId, 'x-request-id': requestId },
}