@@ -13,6 +13,9 @@ import { tieredRateLimiter } from './middleware/rateLimiter';
1313import monitoringRoutes from './routes/monitoring' ;
1414import upgradeRoutes from './routes/upgrade' ;
1515import currencyRoutes from './routes/currency' ;
16+ import { handleClientError , apiErrorHandler } from './middleware/errorHandler' ;
17+ import { AnalyticsService } from './services/analyticsService' ;
18+ import { getTransactionStatus , startWebsocketService , updateTransactionStatus } from './services/websocketService' ;
1619
1720// Load environment variables
1821dotenv . config ( ) ;
@@ -96,6 +99,9 @@ app.use(cors(corsOptions));
9699app . use ( express . json ( { limit : '10mb' } ) ) ;
97100app . use ( express . urlencoded ( { extended : true , limit : '10mb' } ) ) ;
98101
102+ // Client-side error logging endpoint
103+ app . post ( '/api/client-errors' , handleClientError ) ;
104+
99105// Request logging middleware
100106app . use ( ( req , res , next ) => {
101107 logger . info ( 'Incoming HTTP Request' , {
@@ -197,6 +203,9 @@ app.post('/api/payment', async (req, res) => {
197203 res . set ( 'X-Rate-Limit-Remaining' , result . rateLimitInfo ?. remainingRequests ?. toString ( ) || '0' ) ;
198204
199205 if ( result . success ) {
206+ if ( result . transactionId ) {
207+ updateTransactionStatus ( result . transactionId , 'confirmed' ) ;
208+ }
200209 return res . status ( 200 ) . json ( {
201210 success : true ,
202211 transactionId : result . transactionId ,
@@ -206,6 +215,9 @@ app.post('/api/payment', async (req, res) => {
206215 }
207216 } ) ;
208217 } else {
218+ if ( result . transactionId ) {
219+ updateTransactionStatus ( result . transactionId , 'failed' ) ;
220+ }
209221 // Handle rate limit errors with appropriate status codes
210222 if ( result . error ?. includes ( 'Rate limit exceeded' ) ) {
211223 return res . status ( 429 ) . json ( {
@@ -270,6 +282,44 @@ app.get('/api/rate-limit/:userId', (req, res) => {
270282 }
271283} ) ;
272284
285+ /**
286+ * GET /api/analytics/:userId
287+ * Provide analytics insights for a user
288+ */
289+ app . get ( '/api/analytics/:userId' , ( req , res ) => {
290+ try {
291+ const { userId } = req . params ;
292+ if ( ! userId ) {
293+ return res . status ( 400 ) . json ( { success : false , error : 'User ID is required' } ) ;
294+ }
295+
296+ const analytics = AnalyticsService . generateReport ( userId ) ;
297+ return res . status ( 200 ) . json ( analytics ) ;
298+ } catch ( error ) {
299+ logger . error ( 'Analytics report generation failed' , { error, userId : req . params . userId } ) ;
300+ return res . status ( 500 ) . json ( { success : false , error : 'Failed to generate analytics report' } ) ;
301+ }
302+ } ) ;
303+
304+ /**
305+ * GET /api/transaction-status/:transactionId
306+ * Return current transaction status for real-time updates.
307+ */
308+ app . get ( '/api/transaction-status/:transactionId' , ( req , res ) => {
309+ try {
310+ const { transactionId } = req . params ;
311+ if ( ! transactionId ) {
312+ return res . status ( 400 ) . json ( { success : false , error : 'Transaction ID is required' } ) ;
313+ }
314+
315+ const status = getTransactionStatus ( transactionId ) ;
316+ return res . status ( 200 ) . json ( { success : true , transactionId, status } ) ;
317+ } catch ( error ) {
318+ logger . error ( 'Transaction status query failed' , { error, transactionId : req . params . transactionId } ) ;
319+ return res . status ( 500 ) . json ( { success : false , error : 'Unable to retrieve transaction status' } ) ;
320+ }
321+ } ) ;
322+
273323/**
274324 * GET /api/payment/:meterId
275325 * Get total paid amount for a meter
@@ -316,27 +366,7 @@ app.get('/api/payment/:meterId', async (req, res) => {
316366} ) ;
317367
318368// Error handling middleware
319- app . use ( ( err : any , req : express . Request , res : express . Response , next : express . NextFunction ) => {
320- if ( err . name === 'UnauthorizedError' ) {
321- return res . status ( 401 ) . json ( {
322- success : false ,
323- error : 'Unauthorized'
324- } ) ;
325- }
326-
327- if ( err . message === 'Not allowed by CORS' ) {
328- return res . status ( 403 ) . json ( {
329- success : false ,
330- error : 'CORS policy violation'
331- } ) ;
332- }
333-
334- logger . error ( 'Unhandled server error' , { err, method : req . method , path : req . path } ) ;
335- return res . status ( 500 ) . json ( {
336- success : false ,
337- error : 'Internal server error'
338- } ) ;
339- } ) ;
369+ app . use ( apiErrorHandler ) ;
340370
341371// 404 handler
342372app . use ( '*' , ( req , res ) => {
@@ -424,6 +454,8 @@ function startServer() {
424454 } ) ;
425455 } ) ;
426456 }
457+
458+ startWebsocketService ( ) ;
427459}
428460
429461startServer ( ) ;
0 commit comments