From 191b81756decb4d96e380cff459bdab113e2c51d Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sat, 23 May 2026 12:46:10 -0700 Subject: [PATCH] fix(platform-service): resolve 3 TS errors in /devops/info handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The platform-service build was failing with 3 unrelated TS errors, surfaced while running the Gitea outdated-package detector earlier in this session: src/server.ts(18,8): Cannot find module '@bytelyst/devops/server' src/server.ts(318,61): Property 'cosmosEndpoint' does not exist on type 'ProductIdentity' src/server.ts(321,42): Property 'platformServiceUrl' does not exist on type 'ProductIdentity' Root causes (two distinct bugs): 1. Stale install. '@bytelyst/devops' was already declared as 'workspace:*' in services/platform-service/package.json (line 24), but node_modules/@bytelyst/devops/ did not exist. Re-running 'pnpm install' at the workspace root materialised the symlink. 2. Variable shadowing. In the GET /devops/info handler the code declared a local 'const config' from loadProductIdentity() that shadowed the module-level 'config' (env vars) imported from './lib/config.js' at line 112. The author then tried to read 'config.cosmosEndpoint' and 'config.platformServiceUrl' off the ProductIdentity, where those keys never exist: ProductIdentity = { productId, displayName, licensePrefix, configDirName, envVarPrefix, bundleIdSuffix, packageName } The intended values live on the env config: config.COSMOS_ENDPOINT (Zod-validated, required at boot) config.HOST + config.PORT (defaults '0.0.0.0' / 4003) There is no 'platformServiceUrl' field anywhere in the codebase — it only appeared in this single buggy line. Reconstructed as '\${HOST}:\${PORT}' which is the URL admins would use to reach this service for the devops/info diagnostic dashboard. Fix (services/platform-service/src/server.ts:310-339): - Rename local 'const config' to 'const productIdentity' to break the shadowing. - Use productIdentity.productId for the devops productId field. - Use config.COSMOS_ENDPOINT (the env config) for the cosmos dependency health check URL. - Use `http://${config.HOST}:${config.PORT}` for the extra platformServiceUrl field. - Add a doc comment block explaining the two-config distinction so future contributors don't reintroduce the shadow. Verified: pnpm --filter @lysnrai/platform-service build OK (0 errors) pnpm --filter @lysnrai/platform-service test 1511/1512 pass The 1 remaining failure (src/modules/products/cache.test.ts line 104, 'returns all cached products' expects 2 products but got 3) is a PRE-EXISTING product-registry test drift on main, verified by stashing this commit's changes and re-running the same test against the unmodified tree. It will be addressed separately. --- pnpm-lock.yaml | 92 ++++++++++++++++++------- services/platform-service/src/server.ts | 18 +++-- 2 files changed, 81 insertions(+), 29 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94f25294..3eff7316 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,6 +98,9 @@ importers: '@bytelyst/design-tokens': specifier: workspace:* version: link:../../packages/design-tokens + '@bytelyst/devops': + specifier: workspace:* + version: link:../../packages/devops '@bytelyst/errors': specifier: workspace:* version: link:../../packages/errors @@ -113,6 +116,9 @@ importers: '@bytelyst/telemetry-client': specifier: workspace:* version: link:../../packages/telemetry-client + '@bytelyst/ui': + specifier: workspace:* + version: link:../../packages/ui '@radix-ui/react-slider': specifier: ^1.3.6 version: 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -194,7 +200,7 @@ importers: version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.1.6 - version: 16.1.6(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 16.1.6(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) husky: specifier: ^9.0.0 version: 9.1.7 @@ -291,7 +297,7 @@ importers: version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.1.6 - version: 16.1.6(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 16.1.6(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) husky: specifier: ^9.0.0 version: 9.1.7 @@ -520,6 +526,15 @@ importers: specifier: ^4.0.0 version: 4.21.0 + packages/devops: + devDependencies: + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + react: + specifier: ^19.2.4 + version: 19.2.4 + packages/diagnostics-client: dependencies: '@bytelyst/api-client': @@ -684,6 +699,19 @@ importers: specifier: ^5.7.3 version: 5.9.3 + packages/mcp-client: + dependencies: + '@modelcontextprotocol/sdk': + specifier: ^1.0.0 + version: 1.27.1(zod@4.3.6) + devDependencies: + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.11)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + packages/monitoring: {} packages/offline-queue: {} @@ -1214,6 +1242,9 @@ importers: '@bytelyst/datastore': specifier: workspace:* version: link:../../packages/datastore + '@bytelyst/devops': + specifier: workspace:* + version: link:../../packages/devops '@bytelyst/errors': specifier: workspace:* version: link:../../packages/errors @@ -17398,6 +17429,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.9(hono@4.12.3) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.2.1(express@5.2.1) + hono: 4.12.3 + jose: 6.1.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - supports-color + '@mswjs/interceptors@0.41.3': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -19838,14 +19891,14 @@ snapshots: msw: 2.12.10(@types/node@20.19.33)(typescript@5.9.3) vite: 7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@3.2.4(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(vite@7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(vite@7.3.1(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.10(@types/node@22.19.11)(typescript@5.9.3) - vite: 7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@20.19.33)(typescript@5.9.3))(vite@7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: @@ -21156,7 +21209,7 @@ snapshots: '@next/eslint-plugin-next': 16.1.6 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@2.6.1)) @@ -21179,7 +21232,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -21194,21 +21247,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - get-tsconfig: 4.13.6 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.15 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) - transitivePeerDependencies: - - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 @@ -21220,14 +21258,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -21271,7 +21309,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -25905,7 +25943,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(vite@7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(vite@7.3.1(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -26227,6 +26265,10 @@ snapshots: dependencies: zod: 3.25.76 + zod-to-json-schema@3.25.1(zod@4.3.6): + dependencies: + zod: 4.3.6 + zod-validation-error@4.0.2(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/services/platform-service/src/server.ts b/services/platform-service/src/server.ts index 16d3421e..accc8380 100644 --- a/services/platform-service/src/server.ts +++ b/services/platform-service/src/server.ts @@ -309,16 +309,26 @@ await app.register( }, async (request, reply) => { try { - const config = (await import('@bytelyst/config')).loadProductIdentity(); + // Two distinct config sources here — they were previously colliding + // because both were named `config` and the inner one shadowed the + // module-level env config imported at the top of this file: + // * productIdentity — loaded from shared/product.json. Has + // productId/displayName/etc., NOT environment values. + // * config (outer) — env-validated Zod object from ./lib/config.js. + // Has COSMOS_ENDPOINT, HOST, PORT, BACKEND_URL, etc. + // The original code tried to read config.cosmosEndpoint and + // config.platformServiceUrl off the ProductIdentity, which fails + // TS2339 because those keys don't exist there. + const productIdentity = (await import('@bytelyst/config')).loadProductIdentity(); const info = await collectDevopsInfo({ - productId: config.productId || 'platform', + productId: productIdentity.productId || 'platform', serviceName: 'platform-service', serviceVersion: readServiceVersion(import.meta.url), dependencyChecks: [ - () => httpDependencyCheck('cosmos-db', config.cosmosEndpoint || 'unknown'), + () => httpDependencyCheck('cosmos-db', config.COSMOS_ENDPOINT || 'unknown'), ], extra: { - platformServiceUrl: config.platformServiceUrl, + platformServiceUrl: `http://${config.HOST}:${config.PORT}`, }, }); return reply.send(info);