···
167
-
// Clean up expired sessions every hour
167
+
// Clean up expired sessions every 15 minutes
const sessionCleanupInterval = setInterval(
// Helper function to sync user subscriptions from Polar
···
"/api/transcriptions/health": {
1798
-
const isHealthy = await whisperService.checkHealth();
1799
-
return Response.json({ available: isHealthy });
1799
+
status: "healthy",
1800
+
timestamp: new Date().toISOString(),
1806
+
details: {} as Record<string, unknown>,
1811
+
db.query("SELECT 1").get();
1812
+
health.services.database = true;
1814
+
health.status = "unhealthy";
1815
+
health.details.databaseError =
1816
+
error instanceof Error ? error.message : String(error);
1819
+
// Check Whisper service
1821
+
const whisperHealthy = await whisperService.checkHealth();
1822
+
health.services.whisper = whisperHealthy;
1823
+
if (!whisperHealthy) {
1824
+
health.status = "degraded";
1825
+
health.details.whisperNote = "Whisper service unavailable";
1828
+
health.status = "degraded";
1829
+
health.details.whisperError =
1830
+
error instanceof Error ? error.message : String(error);
1833
+
// Check storage (uploads and transcripts directories)
1835
+
const uploadsDir = Bun.file("./uploads");
1836
+
const transcriptsDir = Bun.file("./transcripts");
1837
+
const uploadsExists = await uploadsDir.exists();
1838
+
const transcriptsExists = await transcriptsDir.exists();
1839
+
health.services.storage = uploadsExists && transcriptsExists;
1840
+
if (!health.services.storage) {
1841
+
health.status = "unhealthy";
1842
+
health.details.storageNote = `Missing directories: ${[
1843
+
!uploadsExists && "uploads",
1844
+
!transcriptsExists && "transcripts",
1850
+
health.status = "unhealthy";
1851
+
health.details.storageError =
1852
+
error instanceof Error ? error.message : String(error);
1855
+
const statusCode = health.status === "healthy" ? 200 : 503;
1856
+
return Response.json(health, { status: statusCode });
"/api/transcriptions/:id": {
···
2586
-
updateUserEmailAddress(userId, email);
2587
-
return Response.json({ success: true });
2643
+
// Get user's current email
2645
+
.query<{ email: string; name: string | null }, [number]>(
2646
+
"SELECT email, name FROM users WHERE id = ?",
2651
+
return Response.json({ error: "User not found" }, { status: 404 });
2654
+
// Send verification email to user's current email
2656
+
const token = createEmailChangeToken(userId, email);
2657
+
const origin = process.env.ORIGIN || "http://localhost:3000";
2658
+
const verifyUrl = `${origin}/api/user/email/verify?token=${token}`;
2662
+
subject: "Verify your email change",
2663
+
html: emailChangeTemplate({
2665
+
currentEmail: user.email,
2667
+
verifyLink: verifyUrl,
2671
+
return Response.json({
2673
+
message: `Verification email sent to ${user.email}`,
2674
+
pendingEmail: email,
2676
+
} catch (emailError) {
2678
+
"[Admin] Failed to send email change verification:",
2681
+
return Response.json(
2682
+
{ error: "Failed to send verification email" },
return handleError(error);
···
const transcriptId = req.params.id;
3140
-
// Update status to 'selected' and start transcription
3141
-
db.run("UPDATE transcriptions SET status = ? WHERE id = ?", [
3146
-
// Get filename to start transcription
3238
+
// Check if transcription exists and get its current status
3148
-
.query<{ filename: string }, [string]>(
3149
-
"SELECT filename FROM transcriptions WHERE id = ?",
3240
+
.query<{ filename: string; status: string }, [string]>(
3241
+
"SELECT filename, status FROM transcriptions WHERE id = ?",
3153
-
if (transcription) {
3154
-
whisperService.startTranscription(
3156
-
transcription.filename,
3245
+
if (!transcription) {
3246
+
return Response.json(
3247
+
{ error: "Transcription not found" },
3252
+
// Validate that status is appropriate for selection (e.g., 'uploading' or 'pending')
3253
+
const validStatuses = ["uploading", "pending", "failed"];
3254
+
if (!validStatuses.includes(transcription.status)) {
3255
+
return Response.json(
3257
+
error: `Cannot select transcription with status: ${transcription.status}`,
3263
+
// Update status to 'selected' and start transcription
3264
+
db.run("UPDATE transcriptions SET status = ? WHERE id = ?", [
3269
+
whisperService.startTranscription(
3271
+
transcription.filename,
return Response.json({ success: true });