Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ RATE_LIMIT_ADMIN_MAX=100
RATE_LIMIT_ADMIN_WINDOW_HOURS=1

# External API Keys (optional)
ANTHROPIC_API_KEY=your_anthropic_api_key_for_classification
ANTHROPIC_API_KEY=your_anthropic_api_key_for_classification
# Sentry
SENTRY_DSN=your_sentry_dsn_here
SENTRY_AUTH_TOKEN=your_sentry_auth_token_here
SENTRY_ORG=your_sentry_org_here
SENTRY_PROJECT=your_sentry_project_here
2 changes: 2 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"test": "jest"
},
"dependencies": {
"@sentry/node": "^10.46.0",
"@sentry/profiling-node": "^10.46.0",
"@supabase/supabase-js": "^2.47.10",
"@types/cookie-parser": "^1.4.10",
"@types/uuid": "^10.0.0",
Expand Down
18 changes: 18 additions & 0 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import express from 'express';
import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';
import * as Sentry from '@sentry/node';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

// Load environment variables before importing other modules
dotenv.config();

Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
integrations: [nodeProfilingIntegration()],
tracesSampleRate: 0.1,
profilesSampleRate: 0.1,
});


import logger from './config/logger';
import { requestIdMiddleware } from './middleware/requestContext';
import { requestLoggerMiddleware } from './middleware/requestLogger';
Expand All @@ -23,6 +35,10 @@ import { expiryService } from './services/expiry-service';
import { scheduleAutoResume } from './jobs/auto-resume';

const app = express();

// Add Sentry request handler before routes
app.use(Sentry.Handlers.requestHandler());

const PORT = process.env.PORT || 3001;
const ADMIN_API_KEY = process.env.ADMIN_API_KEY || 'development-admin-key';

Expand Down Expand Up @@ -178,6 +194,8 @@ app.post('/api/admin/expiry/process', createAdminLimiter(), adminAuth, async (re
}
});

// Add Sentry error handler after all routes
app.use(Sentry.Handlers.errorHandler());

// Start server
const server = app.listen(PORT, async () => {
Expand Down
5 changes: 5 additions & 0 deletions backend/src/middleware/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Request, Response, NextFunction } from 'express';
import { supabase } from '../config/database';
import logger from '../config/logger';
import { setRequestUserId } from './requestContext';
import * as Sentry from '@sentry/node';

export interface AuthenticatedRequest extends Request {
user?: {
Expand Down Expand Up @@ -57,6 +58,8 @@ export async function authenticate(
email: user.email || '',
};
setRequestUserId(user.id);
Sentry.setUser({ id: user.id, email: user.email });


next();
} catch (error) {
Expand Down Expand Up @@ -95,7 +98,9 @@ export async function optionalAuthenticate(
email: user.email || '',
};
setRequestUserId(user.id);
Sentry.setUser({ id: user.id, email: user.email });
}

}

next();
Expand Down
Loading