this is my app.ts


// Library imports
import morgan from 'morgan';
import helmet from 'helmet';
import express from 'express';
import cors from 'cors';
import passport from 'passport';
import session from 'express-session';
require('dotenv').config();

// Local imports
import * as middlewares from './middlewares/middlewares';
import MessageResponse from './interfaces/MessageResponse';
import roadmaproute from './routes/roadmap.route';
import { authRouter } from './routes/auth.route'
import { useGoogleStrategy } from './configs/auth.config';
import { jwtAuth } from './middlewares/auth.middlewares';
import userRouter from './routes/user.route';


const corsOptions = {
  origin: 'http://localhost:3000', // Make sure this matches your frontend URL exactly
  credentials: true, // This is crucial for allowing cookies to be sent
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
};


const app = express();
app.use(cors(corsOptions));
app.use(morgan('dev'));
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(express.json());

app.use(session({
  secret: process.env.SESSION_SECRET || "keyboard cat",
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production', // true in production
    httpOnly: true,
    sameSite: 'lax', // or 'strict', depending on your needs
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}));

app.use(passport.initialize());
app.use(passport.session());

app.use('/speck/v1/auth', authRouter)
app.get('/speck/v1/serverHealth', (req, res) => {
  res.status(200).send('Server is healthy');
});

useGoogleStrategy();

app.get<{}, MessageResponse>('/', jwtAuth, (req, res) => {
  res.json({
    message: '🦄🌈✨👋🌎🌍🌏✨🌈🦄',
  });
});

app.use('/speck/v1/roadmap', jwtAuth, roadmaproute);
app.use('/speck/v1/user', jwtAuth, userRouter);

app.use(middlewares.notFound);
app.use(middlewares.errorHandler);

export default app;


this is server.ts


import express from 'express';
import expressWs from 'express-ws';
import WebSocket from 'ws';

import { createRoadmapWithStatusUpdates } from '../src/services/roadmap.service/roadmapLongchain.service';
import app from '../src/app';
import { jwtAuth } from '../src/middlewares/auth.middlewares';

// Extend Express's Request interface to include `user`
declare module 'express-serve-static-core' {
    interface Request {
        user?: {
            id: number;
            // Include other user properties if needed
        };
    }
}

// Initialize WebSocket server with the Express app
const wsInstance = expressWs(app);
const wss = wsInstance.getWss();

// WebSocket route for roadmap creation
app.ws('/speck/v1/roadmap/create', async (ws: WebSocket, req: express.Request) => {
    try {
        // Authenticate the user
        await new Promise<void>((resolve, reject) => {
            jwtAuth(req, {} as express.Response, (err) => {
                if (err) {
                    ws.send(JSON.stringify({ error: 'Unauthorized' }));
                    ws.close();
                    reject(new Error('Unauthorized'));
                } else {
                    resolve();
                }
            });
        });

        // Ensure the user is attached to the request
        if (!req.user) {
            ws.send(JSON.stringify({ error: 'User not found after authentication' }));
            ws.close();
            return;
        }

        const userId = req.user.id;

        ws.send(JSON.stringify({ progress: 0, message: "Starting roadmap creation..." }));

        // Listen for the first message containing the prompt
        ws.once('message', async (msg: WebSocket.Data) => {
            try {
                // Parse the incoming message
                const data = typeof msg === 'string' ? JSON.parse(msg) : JSON.parse(msg.toString());
                const { prompt } = data;

                if (!prompt || typeof prompt !== 'string') {
                    ws.send(JSON.stringify({ error: 'Invalid or missing "prompt"' }));
                    ws.close();
                    return;
                }

                // Start the roadmap creation process
                await createRoadmapWithStatusUpdates(prompt, userId, ws);

                ws.send(JSON.stringify({ progress: 100, message: "Roadmap creation complete" }));
                ws.close();
            } catch (error) {
                console.error('Error during roadmap creation:', error);
                ws.send(JSON.stringify({ error: 'Roadmap creation failed', details: error.message }));
                ws.close();
            }
        });

        // Optional: Handle cases where the client disconnects before sending a message
        ws.on('close', () => {
            console.log('WebSocket connection closed before receiving prompt.');
        });

    } catch (error) {
        // Authentication failed
        console.error('Authentication error:', error);
        // If not already handled, ensure the WebSocket is closed
        if (ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({ error: 'Authentication failed' }));
            ws.close();
        }
    }
});



i want to replace one post api with websocket and i wrote this code

but is this the write way???