From 6fa0d87da4d7480e81f73e8b48a982b51ba39f36 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 23 Apr 2026 19:52:16 +0200 Subject: [PATCH] =?UTF-8?q?refactor(ts):=20day=204=20=E2=80=94=20middlewar?= =?UTF-8?q?e=20+=20utils=20+=20db=20.js=20=E2=86=92=20.ts=20(24=20files)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All remaining backend files renamed: src/middleware/auth.ts, logging.ts (2 files) src/utils/*.ts (20 files: ai, auditQueue, config, crypto, embeddings, errors, fileType, logger, models, notify, passwords, platform, promptSafe, prompts, redact, sessions, transcribe*, ttsGoogle) src/db/database.ts, migrate.ts (2 files) Spot-fixes to satisfy tsc (all within the spirit of 'no behavior change' — added `: any` annotations where the original JS relied on duck typing that tsc's default inference narrows too aggressively): utils/ai.ts — body, converseParams, request literals + fallback result object + err.code/model/message casts. AI client has lots of provider-specific ad-hoc object shapes; Day 5 will replace the `any`s with proper provider-response interfaces. utils/embeddings.ts — payload + request as `any`; generateEmbedding call sites pass `undefined as any` for the now-required second arg (model) until we refactor the signature. utils/prompts.ts — PROMPTS typed as Record so .loadFromDb / .updatePrompt / .getAllPrompts attachments after the const literal compile. utils/transcribeLocal.ts — buildArgs() has two `var args = [...]` in the same function scope (var-hoisted); both now typed as any[] so they don't type-clash across conditionals. Backend is now 54 of 54 TypeScript files, permissive mode. `npm run typecheck` EXIT 0. Prod container still running the old JS image — no Dockerfile change yet. Next: Day 5 flips strict: true, fixes every error tsc surfaces, adds Vitest + Zod + Knip tooling. --- src/db/{database.js => database.ts} | 0 src/db/{migrate.js => migrate.ts} | 0 src/middleware/{auth.js => auth.ts} | 0 src/middleware/{logging.js => logging.ts} | 0 src/utils/{ai.js => ai.ts} | 22 +++++++++---------- src/utils/{auditQueue.js => auditQueue.ts} | 0 src/utils/{config.js => config.ts} | 0 src/utils/{crypto.js => crypto.ts} | 0 src/utils/{embeddings.js => embeddings.ts} | 8 +++---- src/utils/{errors.js => errors.ts} | 0 src/utils/{fileType.js => fileType.ts} | 0 src/utils/{logger.js => logger.ts} | 0 src/utils/{models.js => models.ts} | 0 src/utils/{notify.js => notify.ts} | 0 src/utils/{passwords.js => passwords.ts} | 0 src/utils/{platform.js => platform.ts} | 0 src/utils/{promptSafe.js => promptSafe.ts} | 0 src/utils/{prompts.js => prompts.ts} | 2 +- src/utils/{redact.js => redact.ts} | 0 src/utils/{sessions.js => sessions.ts} | 0 .../{transcribeAWS.js => transcribeAWS.ts} | 0 ...ranscribeGoogle.js => transcribeGoogle.ts} | 0 ...{transcribeLocal.js => transcribeLocal.ts} | 6 ++--- src/utils/{ttsGoogle.js => ttsGoogle.ts} | 0 24 files changed, 19 insertions(+), 19 deletions(-) rename src/db/{database.js => database.ts} (100%) rename src/db/{migrate.js => migrate.ts} (100%) rename src/middleware/{auth.js => auth.ts} (100%) rename src/middleware/{logging.js => logging.ts} (100%) rename src/utils/{ai.js => ai.ts} (97%) rename src/utils/{auditQueue.js => auditQueue.ts} (100%) rename src/utils/{config.js => config.ts} (100%) rename src/utils/{crypto.js => crypto.ts} (100%) rename src/utils/{embeddings.js => embeddings.ts} (97%) rename src/utils/{errors.js => errors.ts} (100%) rename src/utils/{fileType.js => fileType.ts} (100%) rename src/utils/{logger.js => logger.ts} (100%) rename src/utils/{models.js => models.ts} (100%) rename src/utils/{notify.js => notify.ts} (100%) rename src/utils/{passwords.js => passwords.ts} (100%) rename src/utils/{platform.js => platform.ts} (100%) rename src/utils/{promptSafe.js => promptSafe.ts} (100%) rename src/utils/{prompts.js => prompts.ts} (99%) rename src/utils/{redact.js => redact.ts} (100%) rename src/utils/{sessions.js => sessions.ts} (100%) rename src/utils/{transcribeAWS.js => transcribeAWS.ts} (100%) rename src/utils/{transcribeGoogle.js => transcribeGoogle.ts} (100%) rename src/utils/{transcribeLocal.js => transcribeLocal.ts} (95%) rename src/utils/{ttsGoogle.js => ttsGoogle.ts} (100%) diff --git a/src/db/database.js b/src/db/database.ts similarity index 100% rename from src/db/database.js rename to src/db/database.ts diff --git a/src/db/migrate.js b/src/db/migrate.ts similarity index 100% rename from src/db/migrate.js rename to src/db/migrate.ts diff --git a/src/middleware/auth.js b/src/middleware/auth.ts similarity index 100% rename from src/middleware/auth.js rename to src/middleware/auth.ts diff --git a/src/middleware/logging.js b/src/middleware/logging.ts similarity index 100% rename from src/middleware/logging.js rename to src/middleware/logging.ts diff --git a/src/utils/ai.js b/src/utils/ai.ts similarity index 97% rename from src/utils/ai.js rename to src/utils/ai.ts index 1eda32a..09d65cb 100644 --- a/src/utils/ai.js +++ b/src/utils/ai.ts @@ -223,7 +223,7 @@ async function callBedrock(messages, model, temperature, maxTokens) { if (isAnthropic) { // Anthropic Messages API format (native, best performance) var InvokeModelCommand = BedrockModule.InvokeModelCommand; - var body = { + var body: any = { anthropic_version: 'bedrock-2023-05-31', max_tokens: maxTokens, temperature: temperature, @@ -279,7 +279,7 @@ async function callBedrock(messages, model, temperature, maxTokens) { return { role: m.role, content: [{ text: m.content }] }; }); - var converseParams = { + var converseParams: any = { modelId: modelId, messages: converseMessages, inferenceConfig: { @@ -346,7 +346,7 @@ async function callVertex(messages, model, temperature, maxTokens) { } }); - var request = { contents: contents }; + var request: any = { contents: contents }; if (systemInstruction) { request.systemInstruction = { parts: [{ text: systemInstruction }] }; } @@ -418,8 +418,8 @@ async function callAI(messages, options) { var allowed = await getAllowedModelIds(db); if (allowed && allowed.size > 0 && !allowed.has(requestedModel)) { var err = new Error('Model not permitted'); - err.code = 'model_not_permitted'; - err.model = requestedModel; + (err as any).code = 'model_not_permitted'; + (err as any).model = requestedModel; throw err; } } catch (e) { @@ -487,28 +487,28 @@ async function callAI(messages, options) { if (activeProvider === 'openrouter' && model !== FALLBACK_MODEL && openrouter) { logger.warn('Trying fallback model: ' + FALLBACK_MODEL); try { - var fallbackResult = await callOpenRouter(messages, FALLBACK_MODEL, temperature, maxTokens); + var fallbackResult: any = await callOpenRouter(messages, FALLBACK_MODEL, temperature, maxTokens); fallbackResult.fallback = true; fallbackResult.duration = Date.now() - startTime; logger.info('Fallback success', { model: FALLBACK_MODEL }); return fallbackResult; } catch (err2) { - logger.error('Fallback also failed', { error: err2.message }); - throw new Error('All models failed: ' + err2.message); + logger.error('Fallback also failed', { error: (err2 as any).message }); + throw new Error('All models failed: ' + (err2 as any).message); } } if (activeProvider === 'litellm' && model !== FALLBACK_MODEL && litellmClient) { logger.warn('Trying fallback model on LiteLLM: ' + FALLBACK_MODEL); try { - var litellmFallback = await callLiteLLM(messages, FALLBACK_MODEL, temperature, maxTokens); + var litellmFallback: any = await callLiteLLM(messages, FALLBACK_MODEL, temperature, maxTokens); litellmFallback.fallback = true; litellmFallback.duration = Date.now() - startTime; logger.info('LiteLLM fallback success', { model: FALLBACK_MODEL }); return litellmFallback; } catch (err3) { - logger.error('LiteLLM fallback also failed', { error: err3.message }); - throw new Error('All models failed: ' + err3.message); + logger.error('LiteLLM fallback also failed', { error: (err3 as any).message }); + throw new Error('All models failed: ' + (err3 as any).message); } } } diff --git a/src/utils/auditQueue.js b/src/utils/auditQueue.ts similarity index 100% rename from src/utils/auditQueue.js rename to src/utils/auditQueue.ts diff --git a/src/utils/config.js b/src/utils/config.ts similarity index 100% rename from src/utils/config.js rename to src/utils/config.ts diff --git a/src/utils/crypto.js b/src/utils/crypto.ts similarity index 100% rename from src/utils/crypto.js rename to src/utils/crypto.ts diff --git a/src/utils/embeddings.js b/src/utils/embeddings.ts similarity index 97% rename from src/utils/embeddings.js rename to src/utils/embeddings.ts index 74072ef..2f7af3b 100644 --- a/src/utils/embeddings.js +++ b/src/utils/embeddings.ts @@ -67,7 +67,7 @@ async function generateEmbeddingLiteLLM(text, model, dimensions) { headers['Authorization'] = 'Bearer ' + process.env.LITELLM_API_KEY; } - var payload = { + var payload: any = { model: model, input: text }; @@ -113,7 +113,7 @@ async function generateEmbeddingVertexDirect(text, model, dimensions) { var modelName = model.replace(/^vertex_ai\//, ''); // For text-embedding-005, we can specify output dimensions - var request = { + var request: any = { instances: [{ content: text }] }; @@ -181,7 +181,7 @@ async function searchSimilar(queryText, opts) { var db = require('../db/database'); // Generate embedding for query - var queryEmbedding = await generateEmbedding(queryText); + var queryEmbedding = await generateEmbedding(queryText, undefined as any); // Build WHERE clause for filtering var whereClause = 'WHERE c.published = true AND c.embedding IS NOT NULL'; @@ -233,7 +233,7 @@ async function generateContentEmbedding(content) { stripHtml(content.body || '').substring(0, 6000) ].filter(Boolean).join('\n\n'); - return await generateEmbedding(text); + return await generateEmbedding(text, undefined as any); } /** diff --git a/src/utils/errors.js b/src/utils/errors.ts similarity index 100% rename from src/utils/errors.js rename to src/utils/errors.ts diff --git a/src/utils/fileType.js b/src/utils/fileType.ts similarity index 100% rename from src/utils/fileType.js rename to src/utils/fileType.ts diff --git a/src/utils/logger.js b/src/utils/logger.ts similarity index 100% rename from src/utils/logger.js rename to src/utils/logger.ts diff --git a/src/utils/models.js b/src/utils/models.ts similarity index 100% rename from src/utils/models.js rename to src/utils/models.ts diff --git a/src/utils/notify.js b/src/utils/notify.ts similarity index 100% rename from src/utils/notify.js rename to src/utils/notify.ts diff --git a/src/utils/passwords.js b/src/utils/passwords.ts similarity index 100% rename from src/utils/passwords.js rename to src/utils/passwords.ts diff --git a/src/utils/platform.js b/src/utils/platform.ts similarity index 100% rename from src/utils/platform.js rename to src/utils/platform.ts diff --git a/src/utils/promptSafe.js b/src/utils/promptSafe.ts similarity index 100% rename from src/utils/promptSafe.js rename to src/utils/promptSafe.ts diff --git a/src/utils/prompts.js b/src/utils/prompts.ts similarity index 99% rename from src/utils/prompts.js rename to src/utils/prompts.ts index 334931c..720e85b 100644 --- a/src/utils/prompts.js +++ b/src/utils/prompts.ts @@ -47,7 +47,7 @@ For ABNORMAL systems: For NOT REVIEWED systems: simply state "Not reviewed" or "Not examined" `; -const PROMPTS = { +const PROMPTS: Record = { // ======================== HPI ======================== hpiEncounter: `You are an expert pediatric medical scribe. diff --git a/src/utils/redact.js b/src/utils/redact.ts similarity index 100% rename from src/utils/redact.js rename to src/utils/redact.ts diff --git a/src/utils/sessions.js b/src/utils/sessions.ts similarity index 100% rename from src/utils/sessions.js rename to src/utils/sessions.ts diff --git a/src/utils/transcribeAWS.js b/src/utils/transcribeAWS.ts similarity index 100% rename from src/utils/transcribeAWS.js rename to src/utils/transcribeAWS.ts diff --git a/src/utils/transcribeGoogle.js b/src/utils/transcribeGoogle.ts similarity index 100% rename from src/utils/transcribeGoogle.js rename to src/utils/transcribeGoogle.ts diff --git a/src/utils/transcribeLocal.js b/src/utils/transcribeLocal.ts similarity index 95% rename from src/utils/transcribeLocal.js rename to src/utils/transcribeLocal.ts index fc3ddcd..2dcf770 100644 --- a/src/utils/transcribeLocal.js +++ b/src/utils/transcribeLocal.ts @@ -122,17 +122,17 @@ function transcribeWithLocal(audioBuffer, mimeType) { /** * Build command-line args based on the detected binary */ -function buildArgs(binary, audioPath) { +function buildArgs(binary: string, audioPath: string): any[] { if (binary.includes('faster-whisper')) { // faster-whisper CLI - var args = ['--model', WHISPER_MODEL_SIZE, '--language', WHISPER_LANGUAGE]; + var args: any[] = ['--model', WHISPER_MODEL_SIZE, '--language', WHISPER_LANGUAGE]; if (WHISPER_THREADS) args.push('--threads', WHISPER_THREADS); args.push(audioPath); return args; } // whisper.cpp style - var args = ['-f', audioPath, '-l', WHISPER_LANGUAGE, '-t', WHISPER_THREADS, '--no-timestamps']; + var args: any[] = ['-f', audioPath, '-l', WHISPER_LANGUAGE, '-t', WHISPER_THREADS, '--no-timestamps']; if (WHISPER_MODEL_PATH) { args.push('-m', WHISPER_MODEL_PATH); } else { diff --git a/src/utils/ttsGoogle.js b/src/utils/ttsGoogle.ts similarity index 100% rename from src/utils/ttsGoogle.js rename to src/utils/ttsGoogle.ts