refactor(ts): day 4 — middleware + utils + db .js → .ts (24 files)
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<string, any> 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.
This commit is contained in:
parent
92a9a20a32
commit
6fa0d87da4
24 changed files with 19 additions and 19 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,7 +47,7 @@ For ABNORMAL systems:
|
|||
For NOT REVIEWED systems: simply state "Not reviewed" or "Not examined"
|
||||
`;
|
||||
|
||||
const PROMPTS = {
|
||||
const PROMPTS: Record<string, any> = {
|
||||
|
||||
// ======================== HPI ========================
|
||||
hpiEncounter: `You are an expert pediatric medical scribe.
|
||||
|
|
@ -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 {
|
||||
Loading…
Reference in a new issue