@@ -8,6 +8,7 @@ const socketIo = require('socket.io');
88const bcryptjs = require ( 'bcryptjs' ) ;
99const jwt = require ( 'jsonwebtoken' ) ;
1010const nodemailer = require ( 'nodemailer' )
11+ const path = require ( 'path' ) ;
1112const { updateShipmentStatus } = require ( './utils/statusUpdate' ) ;
1213const admin = require ( "firebase-admin" ) ;
1314const rateLimit = require ( 'express-rate-limit' ) ;
@@ -119,7 +120,7 @@ io.on("connection", (socket) => {
119120 shipment . events . push ( {
120121 status : newStatus ,
121122 date : new Date ( ) . toISOString ( ) ,
122- location : { latitude , longitude } ,
123+ location : locationName ,
123124 coordinates : { latitude, longitude } ,
124125 } ) ;
125126
@@ -225,7 +226,7 @@ const transporter = nodemailer.createTransport({
225226} )
226227
227228//Login
228- app . post ( '/login' , async ( req , res ) => {
229+ app . post ( '/api/ login' , async ( req , res ) => {
229230 const { username, password } = req . body
230231
231232 try {
@@ -255,7 +256,7 @@ app.post('/login', async (req, res) => {
255256} )
256257
257258// Verify
258- app . post ( '/verify-2fa' , async ( req , res ) => {
259+ app . post ( '/api/ verify-2fa' , async ( req , res ) => {
259260 const { username, code } = req . body
260261 const entry = twoFACodes [ username ]
261262
@@ -282,7 +283,7 @@ app.post('/verify-2fa', async (req, res) => {
282283} )
283284
284285//Signup
285- app . post ( "/signup" , async ( req , res ) => {
286+ app . post ( "/api/ signup" , async ( req , res ) => {
286287 try {
287288 console . log ( "Incoming signup request:" , req . body ) ;
288289 const { fullname, username, email, password, address } = req . body ;
@@ -355,7 +356,7 @@ app.post("/signup", async (req, res) => {
355356 }
356357} ) ;
357358//Driver Login
358- app . post ( '/driverlogin' , async ( req , res ) => {
359+ app . post ( '/api/ driverlogin' , async ( req , res ) => {
359360 const { username, password } = req . body ;
360361 console . log ( `Incoming request: ${ req . method } ${ req . url } ` ) ;
361362
@@ -382,7 +383,7 @@ app.post('/driverlogin', async (req, res) => {
382383} ) ;
383384
384385//Driver get shipments
385- app . get ( '/driver/shipments' , async ( req , res ) => {
386+ app . get ( '/api/ driver/shipments' , async ( req , res ) => {
386387 try {
387388 const activeShipments = await TrackData . find ( { } , {
388389 trackingNumber : 1 ,
@@ -401,7 +402,7 @@ app.get('/driver/shipments', async (req, res) => {
401402 }
402403} )
403404// Driver selects shipments to track
404- app . post ( '/driver/select-shipment' , async ( req , res ) => {
405+ app . post ( '/api/ driver/select-shipment' , async ( req , res ) => {
405406 const { trackingNumber, driverUsername } = req . body ;
406407 console . log ( 'Received for assign:' , { trackingNumber, driverUsername } )
407408
@@ -424,7 +425,7 @@ app.post('/driver/select-shipment', async (req, res) => {
424425
425426
426427// Email
427- app . post ( "/verify-email" , async ( req , res ) => {
428+ app . post ( "/api/ verify-email" , async ( req , res ) => {
428429 try {
429430 const { email } = req . body ;
430431 // Get user from Firebase
@@ -472,7 +473,7 @@ const resendEmailLimiter = rateLimit({
472473} ) ;
473474
474475// Resend Verification Email Route
475- app . post ( '/resend-verification' , resendEmailLimiter , async ( req , res ) => {
476+ app . post ( '/api/ resend-verification' , resendEmailLimiter , async ( req , res ) => {
476477 try {
477478 const { email } = req . body ;
478479 const userRecord = await admin . auth ( ) . getUserByEmail ( email ) ;
@@ -497,7 +498,7 @@ app.post('/resend-verification', resendEmailLimiter, async (req, res) => {
497498} ) ;
498499
499500// Delete
500- app . delete ( '/track/:trackingNumber' , async ( req , res ) => {
501+ app . delete ( '/api/ track/:trackingNumber' , async ( req , res ) => {
501502 const { trackingNumber } = req . params ;
502503 try {
503504 const deletedShipment = await TrackData . findOneAndDelete ( { trackingNumber } ) ;
@@ -513,7 +514,7 @@ app.delete('/track/:trackingNumber', async (req, res) => {
513514} ) ;
514515
515516// Track Shipment
516- app . post ( '/track' , async ( req , res ) => {
517+ app . post ( '/api/ track' , async ( req , res ) => {
517518 const { trackingNumber } = req . body ;
518519
519520 try {
@@ -574,17 +575,8 @@ app.post('/track', async (req, res) => {
574575} ) ;
575576
576577// Notifications
577- const hubs = [
578- "Fortis Residences" ,
579- "Warehouse1" ,
580- "Sorting Center A" ,
581- "Sorting Center B" ,
582- "Hub2" ,
583- "Warehouse2"
584- ] ;
585- const lastKnownLocations = new Map ( ) ;
586-
587- let dbReady = false ;
578+ const criticalStatuses = [ "Out for delivery" , "Delivered" , "Exception" ] ;
579+ const lastStatusMap = new Map ( ) ;
588580
589581setInterval ( async ( ) => {
590582 if ( ! dbReady ) return ;
@@ -593,30 +585,43 @@ setInterval(async () => {
593585 const recentShipments = await TrackData . find ( ) . sort ( { updatedAt : - 1 } ) . limit ( 10 ) ;
594586
595587 recentShipments . forEach ( ( shipment ) => {
596- const isAtHub = hubs . some ( hub => hub . toLowerCase ( ) === shipment . location . toLowerCase ( ) ) ;
597- const lastLocation = lastKnownLocations . get ( shipment . trackingNumber ) ;
588+ const lastStatus = lastStatusMap . get ( shipment . trackingNumber ) ;
598589
599- // Only notify if newly arrived at a hub (i.e., location changed)
600- if ( isAtHub && lastLocation !== shipment . location ) {
601- lastKnownLocations . set ( shipment . trackingNumber , shipment . location ) ; // update memory
590+ if ( criticalStatuses . includes ( shipment . status ) && shipment . status !== lastStatus ) {
591+ lastStatusMap . set ( shipment . trackingNumber , shipment . status ) ;
602592
603593 io . emit ( "shipmentUpdate" , {
604594 trackingNumber : shipment . trackingNumber ,
605595 status : shipment . status ,
606596 location : shipment . location ,
607597 timestamp : new Date ( shipment . updatedAt ) . toLocaleString ( ) ,
608- isAtHub : true ,
598+ critical : true ,
599+ message : getStatusMessage ( shipment . status , shipment . location ) ,
609600 } ) ;
610601
611- console . log ( ` Emitted hub update for ${ shipment . trackingNumber } at ${ shipment . location } ` ) ;
602+ console . log ( ` Emitted critical update: ${ shipment . trackingNumber } - ${ shipment . status } ` ) ;
612603 }
613604 } ) ;
614605 } catch ( err ) {
615- console . error ( " Error during hub check:" , err ) ;
606+ console . error ( " Error during status check:" , err ) ;
616607 }
617608} , 10000 ) ;
618609
619- app . get ( '/history' , async ( req , res ) => {
610+ function getStatusMessage ( status , location ) {
611+ switch ( status ) {
612+ case "Out for delivery" :
613+ return `Shipment is out for delivery from ${ location } ` ;
614+ case "Delivered" :
615+ return `Shipment has been delivered successfully.` ;
616+ case "Exception" :
617+ return `Shipment has encountered an issue. Please contact support.` ;
618+ default :
619+ return `Shipment update: ${ status } ` ;
620+ }
621+ }
622+
623+
624+ app . get ( '/api/history' , async ( req , res ) => {
620625 try {
621626 const shippedData = await TrackData . find ( ) ;
622627 if ( shippedData . length > 0 ) {
@@ -629,6 +634,18 @@ app.get('/history', async (req, res) => {
629634 res . status ( 500 ) . json ( { status : 'error' , message : 'An error occurred while fetching shipment data.' } ) ;
630635 }
631636} ) ;
637+ app . use ( '/api/*' , ( _req , res ) => {
638+ res . status ( 404 ) . json ( { message : 'API route not found' } ) ;
639+ } ) ;
640+ app . use ( express . static ( path . join ( __dirname , "../client/build" ) ) ) ;
641+ // Catch-all route to serve React's `index.html`
642+ app . get ( "*" , ( _req , res ) => {
643+ res . sendFile ( path . join ( __dirname , "../client/build/index.html" ) ) ;
644+ } ) ;
645+ app . use ( ( err , req , res , next ) => {
646+ console . error ( err . stack ) ;
647+ res . status ( 500 ) . json ( { message : 'Something broke!' } ) ;
648+ } ) ;
632649// Start Server
633650server . listen ( PORT , ( ) => {
634651 console . log ( ` Server running on PORT: ${ PORT } ` ) ;
0 commit comments