Source: index.js

/**
 * @fileoverview Express.js server for user authentication and post management
 * @description This server provides REST API endpoints for user registration, login, account deletion,
 * and basic post management functionality. It uses MongoDB for data persistence and JWT for authentication.
 * @author Your Name
 * @version 1.0.0
 */

const express = require('express');
const cors = require('cors');
const { connectToMongoDB, insertPost, getAllPosts, registerUser, LoginUser, deleteaUser } = require('./mongodb/mongodb');
require('dotenv').config();

/**
 * Express application instance
 * @type {express.Application}
 */
const app = express();

/**
 * Server port - defaults to 4000 if not specified in environment
 * @type {number}
 */
const PORT = process.env.PORT || 4000;

app.use(cors());
app.use(express.json());

/**
 * Initializes and starts the Express server
 * @async
 * @function startServer
 * @description Connects to MongoDB database and starts the Express server.
 * The server will only start if MongoDB connection is successful.
 * @throws {Error} If MongoDB connection fails, the process will exit with code 1
 * @returns {Promise<void>}
 */
const startServer = async () => {
  try {
    // Connect to MongoDB
    await connectToMongoDB();
    console.log('MongoDB connection established successfully');

    /**
     * POST /run-test - Test MongoDB connection
     * @name TestConnection
     * @route {POST} /run-test
     * @description Tests the MongoDB connection and returns the result
     * @returns {Object} 200 - Success response with connection result
     * @returns {Object} 500 - Error response if connection fails
     * @example
     * // Request body: {} (empty)
     * // Success response:
     * {
     *   "success": true,
     *   "result": "Connection successful"
     * }
     */
    app.post('/run-test', async (req, res) => {
      try {
        const result = await connectToMongoDB();
        res.status(200).json({ success: true, result });
      } catch (err) {
        console.error('Error running test:', err);
        res.status(500).json({ success: false, error: err.toString() });
      }
    });

    /**
     * POST /add-post - Add a new post
     * @name AddPost
     * @route {POST} /add-post
     * @description Adds a new post to the database
     * @param {Object} req.body - Post data
     * @param {string} req.body.title - Post title
     * @param {string} req.body.content - Post content
     * @param {string} req.body.author - Post author
     * @returns {Object} 200 - Success response with post creation result
     * @returns {Object} 500 - Error response if post creation fails
     * @example
     * // Request body:
     * {
     *   "title": "My First Post",
     *   "content": "This is the content of my post",
     *   "author": "John Doe"
     * }
     */
    app.post('/add-post', async (req, res) => {
      try {
        const postData = req.body;
        const result = await insertPost(postData);
        res.status(200).json({ success: true, result });
      } catch (err) {
        console.error('Error adding post:', err);
        res.status(500).json({ success: false, error: err.toString() });
      }
    });

    /**
     * GET /get-posts - Retrieve all posts
     * @name GetPosts
     * @route {GET} /get-posts
     * @description Retrieves all posts from the database
     * @returns {Object} 200 - Success response with array of posts
     * @returns {Object} 500 - Error response if retrieval fails
     * @example
     * // Success response:
     * {
     *   "success": true,
     *   "result": [
     *     {
     *       "_id": "...",
     *       "title": "Post Title",
     *       "content": "Post content",
     *       "author": "Author Name"
     *     }
     *   ]
     * }
     */
    app.get('/get-posts', async (req, res) => {
      try {
        const result = await getAllPosts();
        res.status(200).json({ success: true, result });
      } catch (err) {
        console.error('Error getting posts:', err);
        res.status(500).json({ success: false, error: err.toString() });
      }
    });

    /**
     * POST /register - User registration endpoint
     * @name RegisterUser
     * @route {POST} /register
     * @description Registers a new user with username, email, and password
     * @param {Object} req.body - User registration data
     * @param {string} req.body.username - User's chosen username
     * @param {string} req.body.email - User's email address
     * @param {string} req.body.password - User's password (will be hashed)
     * @returns {Object} 201 - Success response with user data
     * @returns {Object} 400 - Error response for validation failures or existing user
     * @example
     * // Request body:
     * {
     *   "username": "johndoe",
     *   "email": "john@example.com",
     *   "password": "SecurePassword123"
     * }
     * // Success response:
     * {
     *   "success": true,
     *   "message": "User registered successfully",
     *   "user": {
     *     "id": "...",
     *     "username": "johndoe",
     *     "email": "john@example.com"
     *   }
     * }
     */
    app.post('/register', async (req, res) => {
      try {
        const { username, email, password } = req.body;
        
        if (!username || !email || !password) {
          return res.status(400).json({ 
            success: false, 
            error: 'Please provide username, email, and password' 
          });
        }

        const result = await registerUser(username, email, password);
        res.status(201).json({ 
          success: true, 
          message: 'User registered successfully',
          user: {
            id: result._id,
            username: result.username,
            email: result.email
          }
        });
      } catch (err) {
        console.error('Error registering user:', err);
        res.status(400).json({ 
          success: false, 
          error: err.message 
        });
      }
    });

    /**
     * POST /delete-user - Delete user account
     * @name DeleteUser
     * @route {POST} /delete-user
     * @description Deletes a user account after verifying credentials
     * @param {Object} req.body - User credentials for deletion
     * @param {string} req.body.email - User's email address
     * @param {string} req.body.password - User's password for verification
     * @returns {Object} 200 - Success response confirming deletion
     * @returns {Object} 400 - Error response for missing credentials
     * @returns {Object} 500 - Error response for deletion failures
     * @example
     * // Request body:
     * {
     *   "email": "john@example.com",
     *   "password": "SecurePassword123"
     * }
     */
    app.post('/delete-user', async (req, res) => {
      try {
        const { email, password } = req.body;
        if (!email || !password) {
          return res.status(400).json({ 
            success: false, 
            error: 'Please provide email and password' 
          });
        }

        const result = await deleteaUser(email, password);
        res.status(200).json({ 
          success: true, 
          message: 'User deleted successfully' 
        });
      } catch (err) {
        console.error('Error deleting user:', err);
        res.status(500).json({ 
          success: false, 
          error: err.message 
        });
      }
    });

    /**
     * POST /login - User authentication endpoint
     * @name LoginUser
     * @route {POST} /login
     * @description Authenticates a user with email and password
     * @param {Object} req.body - User login credentials
     * @param {string} req.body.email - User's email address
     * @param {string} req.body.password - User's password
     * @returns {Object} 200 - Success response with user data and JWT token
     * @returns {Object} 400 - Error response for missing credentials
     * @returns {Object} 401 - Error response for invalid credentials
     * @example
     * // Request body:
     * {
     *   "email": "john@example.com",
     *   "password": "SecurePassword123"
     * }
     * // Success response:
     * {
     *   "success": true,
     *   "message": "Login successful",
     *   "user": {
     *     "username": "johndoe",
     *     "email": "john@example.com",
     *     "token": "jwt_token_here"
     *   }
     * }
     */
    app.post('/login', async (req, res) => {
      try {
        const { email, password } = req.body;
        
        if (!email || !password) {
          return res.status(400).json({ 
            success: false, 
            error: 'Please provide email and password' 
          });
        }

        const user = await LoginUser(email, password);
        res.status(200).json({ 
          success: true, 
          message: 'Login successful',
          user: user
        });
      } catch (err) {
        console.error('Error logging in user:', err);
        res.status(401).json({ 
          success: false, 
          error: err.message 
        });
      }
    });

    // Start server only after MongoDB connection is established
    app.listen(PORT, () => {
      console.log(`Server listening on http://localhost:${PORT}`);
    });

  } catch (error) {
    console.error('Failed to connect to MongoDB:', error);
    console.error('Server will not start until MongoDB connection is established');
    process.exit(1);
  }
};

// Start the server only if this file is run directly (not imported for testing)
if (require.main === module) {
  startServer();
}

// Export the app for testing
module.exports = app;