- Add Cloudflare Turnstile to login, register, and password reset forms - Switch AI provider to LiteLLM, transcription to OpenAI Whisper - Change domain to scribe.pedshub.com - Fix PPTX export: add tables, bold/italic, numbered lists, code blocks, blockquotes - Fix announcement banner close button (CSP was blocking inline onclick) - Fix auth middleware: empty Bearer token now falls through to cookie auth - Fix audio backups: only save on transcription failure, stop auto-deleting on success - Soften AI correction injection to prevent model hallucination from correction history - Fix LiteLLM TTS model name handling (no incorrect openai/ prefix) - Expand AI instructions textarea in Learning Hub CMS - Update README for v6 with all features and providers - Add comprehensive docs/: architecture, API reference, database schema, authentication, AI providers, speech, learning hub, configuration, deployment
73 lines
2.4 KiB
JavaScript
73 lines
2.4 KiB
JavaScript
// ============================================================
|
|
// SICK VISIT ROUTE — sick visit note generation
|
|
// ============================================================
|
|
|
|
var express = require('express');
|
|
var router = express.Router();
|
|
var { callAI } = require('../utils/ai');
|
|
var PROMPTS = require('../utils/prompts');
|
|
var { authMiddleware } = require('../middleware/auth');
|
|
var logger = require('../utils/logger');
|
|
|
|
// ── POST generate sick visit note ────────────────────────────────────────
|
|
router.post('/sick-visit/note', authMiddleware, async function(req, res) {
|
|
var start = Date.now();
|
|
try {
|
|
var {
|
|
patientAge, patientGender, chiefComplaint,
|
|
transcript, dictation,
|
|
ros, physicalExam, diagnoses,
|
|
physicianMemories,
|
|
model
|
|
} = req.body;
|
|
|
|
if (!chiefComplaint) {
|
|
return res.status(400).json({ error: 'Chief complaint is required' });
|
|
}
|
|
|
|
// Assemble context
|
|
var context = 'SICK VISIT\n';
|
|
context += 'Patient: ' + (patientAge || 'Unknown age') + ', ' + (patientGender || 'Unknown gender') + '\n';
|
|
context += 'Chief Complaint: ' + chiefComplaint + '\n\n';
|
|
|
|
if (transcript) {
|
|
context += 'ENCOUNTER TRANSCRIPT/DICTATION:\n' + transcript + '\n\n';
|
|
} else if (dictation) {
|
|
context += 'PHYSICIAN DICTATION:\n' + dictation + '\n\n';
|
|
}
|
|
|
|
if (ros) {
|
|
context += ros + '\n\n';
|
|
}
|
|
|
|
if (physicalExam) {
|
|
context += physicalExam + '\n\n';
|
|
}
|
|
|
|
if (diagnoses) {
|
|
context += diagnoses + '\n\n';
|
|
}
|
|
|
|
if (physicianMemories) {
|
|
context += '[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n' + physicianMemories + '\n[END STYLE HINTS]\n\n';
|
|
}
|
|
|
|
var result = await callAI([
|
|
{ role: 'system', content: PROMPTS.sickVisitNote },
|
|
{ role: 'user', content: context }
|
|
], { model });
|
|
|
|
var dur = Date.now() - start;
|
|
logger.apiCall(req.user.id, '/api/sick-visit/note', {
|
|
model: result.model, tokensInput: result.usage?.input_tokens,
|
|
tokensOutput: result.usage?.output_tokens, duration: dur, statusCode: 200
|
|
});
|
|
|
|
res.json({ success: true, note: result.content, model: result.model });
|
|
} catch (e) {
|
|
logger.error('[SickVisit] Note generation failed', e.message);
|
|
res.status(500).json({ error: e.message });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|