From 535998f01a68056546cfcc4686eb63393dc48b95 Mon Sep 17 00:00:00 2001 From: Daniel Onyejesi Date: Mon, 30 Mar 2026 20:53:11 -0400 Subject: [PATCH] =?UTF-8?q?Emails:=20true=20markdown/Resend=20style=20?= =?UTF-8?q?=E2=80=94=20plain=20white,=20no=20card,=20clean=20type=20TTS:?= =?UTF-8?q?=20prefix=20model=20with=20openai/=20so=20LiteLLM=20routes=20co?= =?UTF-8?q?rrectly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Email: horizontal rules instead of card border, spacious padding, wordmark + divider + body + divider + footer. Reads like a doc. TTS: tts-1 becomes openai/tts-1 automatically unless already prefixed. --- src/routes/auth.js | 77 +++++++++++++++++++++------------------------- src/routes/tts.js | 4 ++- 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/routes/auth.js b/src/routes/auth.js index cf81fbc..515cef7 100644 --- a/src/routes/auth.js +++ b/src/routes/auth.js @@ -38,78 +38,71 @@ function safeAppUrl() { } // ============================================================ -// EMAIL TEMPLATES — clean, minimal (Linear / Resend style) +// EMAIL TEMPLATES — markdown-style, Resend/Linear aesthetic +// Plain, spacious, no decorative chrome. Reads like a document. // ============================================================ function emailWrapper(body) { var siteName = process.env.SITE_NAME || 'Pediatric AI Scribe'; + var F = '-apple-system,BlinkMacSystemFont,\'Segoe UI\',Helvetica,Arial,sans-serif'; return ` - ${escHtml(siteName)} - - - -
+ + + - -
+ - -
- - + +
+

${escHtml(siteName)}

+
- - + +
+ ${body} +
- - + +

+ ${escHtml(siteName)} — AI-powered clinical documentation
+ If you didn’t request this, you can safely ignore it. +

+ - - + + + `; } function btnHtml(href, label) { - return ` -
+ return ` +
${escHtml(label)} + style="display:inline-block;color:#ffffff;padding:11px 22px;border-radius:5px; + text-decoration:none;font-weight:500;font-size:14px;line-height:1; + font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;">${escHtml(label)}
`; } function linkFallback(url) { - return `

- Or copy and paste this link into your browser: -

-

${escHtml(url)}

`; + return `

If the button doesn’t work, copy this link:

+

${escHtml(url)}

`; } // Email helper — DB settings override env vars diff --git a/src/routes/tts.js b/src/routes/tts.js index e6f6b01..e880534 100644 --- a/src/routes/tts.js +++ b/src/routes/tts.js @@ -42,7 +42,9 @@ router.post('/text-to-speech', authMiddleware, async (req, res) => { if (!process.env.LITELLM_API_BASE) return res.status(400).json({ error: 'LITELLM_API_BASE not set.' }); // Use the full model path (e.g. vertex_ai/google-tts) or the model_name alias // from your LiteLLM model_list. Full path is safer if your config uses it directly. - var ttsModel = process.env.LITELLM_TTS_MODEL || 'tts-1'; + // Prefix with openai/ so LiteLLM routes correctly to the TTS endpoint + var rawModel = process.env.LITELLM_TTS_MODEL || 'tts-1'; + var ttsModel = rawModel.indexOf('/') === -1 ? 'openai/' + rawModel : rawModel; var ttsVoice = process.env.LITELLM_TTS_VOICE || 'en-US-Journey-F'; var base = process.env.LITELLM_API_BASE.replace(/\/+$/, ''); var ttsHeaders = { 'Content-Type': 'application/json' };