Skip to content

Tanzeebul-Tamim/MTB-Coaching-Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MTB Coaching Logo MTB-Coaching - Server End

Welcome to the server-side repository of the Professional Mountain Biking Coaching Network website. This backend powers the API, database, authentication, transactional emails, and all server-side logic for the platform.


πŸ“š Table of Contents


πŸš€ Features

  • RESTful CRUD operations for users, instructors, classes, and bookings
  • MongoDB database integration for persistent data storage
  • Environment-based configuration for secure deployment
  • Search, filter, and sort for instructors and courses
  • Transactional emails (enrollment, payment receipts) via Nodemailer & Mailgun
  • Date and time formatting with Moment.js
  • Handlebars for dynamic HTML email templates
  • Automated and manual endpoints for demo data freshness (see below)

🧰 Packages & Technologies Used


Full list of Packages & Technologies Used (Click to expand)

Core Framework & Server

  • Node.js: JavaScript runtime for building scalable server-side applications
  • Express.js: Fast and minimalist web framework for Node.js

Database & Data Handling

  • MongoDB: NoSQL database used for storing application data
  • Moment.js: Utility for formatting and manipulating dates

Email & Communication

  • Nodemailer: Library for sending emails from the server
  • Mailgun: Email API service used as a transport for Nodemailer
  • Handlebars: Templating engine for formatting dynamic HTML email bodies

Deployment & Monitoring

  • Render: Cloud platform for deploying and hosting the backend server
  • UptimeRobot: Monitoring tool to ensure the backend is always up and running

πŸ“ Project Structure

MTB-Coaching-Server/
β”œβ”€β”€ public/                         # Static assets (images, logos, etc.)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ routes/                     # API route handlers
β”‚   β”‚   β”œβ”€β”€ bookings.js             # Booking and payment-related endpoints
β”‚   β”‚   β”œβ”€β”€ classes.js              # Class-related endpoints
β”‚   β”‚   β”œβ”€β”€ instructors.js          # Instructor-related endpoints
β”‚   β”‚   └── users.js                # User-related endpoints
β”‚   β”œβ”€β”€ app.js                      # Express app configuration
β”‚   β”œβ”€β”€ email.service.js            # Email sending logic
β”‚   └── server.js                   # Server startup and environment config
β”œβ”€β”€ scripts/
β”‚   └── updateClassDate.js          # Script to randomize instructor class dates for demo freshness
β”œβ”€β”€ templates/
β”‚   └── paymentConfirmation.html    # HTML template for payment confirmation emails
β”œβ”€β”€ .env.example                    # Example environment variables
β”œβ”€β”€ .gitignore                      # Git ignored files
β”œβ”€β”€ LICENSE                         # MIT license
β”œβ”€β”€ package-lock.json               # NPM lockfile
β”œβ”€β”€ package.json                    # Project metadata and dependencies
└── README.md                       # Project documentation (this file)

βœ… Prerequisites

  • Node.js (v18 or higher recommended)
  • npm (comes with Node.js)
  • MongoDB (Atlas or local instance)
  • A .env file with required environment variables

πŸ”§ Installation, Configuration & Running Locally

  1. Clone the repository:

    git clone https://github.com/Tanzeebul-Tamim/MTB-Coaching-Server
    cd MTB-Coaching-Server
  2. Install dependencies:

    npm install
  3. Set up Environment Variables:

    • Rename the .env.example file in the project root to .env and fill in your credentials:

      PORT=5000
      DB_USER=yourDatabaseUser
      DB_PASS=yourSecureDbPassword
      PAYMENT_SECRET_KEY=sk_test_YourPaymentSecretKeyHere
      EMAIL_PRIVATE_KEY=yourEmailPrivateKey
      EMAIL_DOMAIN=mg.yourdomain.com
      MAIL_SENDER=verified_sender@example.com
      ADMIN_SECRET=your_admin_secret_here
    • Guide & Configuration Details (Click to expand)
      • PORT (Server Port):

        The port your server will listen on (commonly 5000 or 8000).

      • DB_USER (Database Username):

        Username credential for your database (used in connection string or DB config).

      • DB_PASS (Database Password):

        Corresponding password for the DB_USER.

      • PAYMENT_SECRET_KEY (Payment Gateway Secret Key):

        Your Stripe payment processor’s private/secret key .

      • EMAIL_PRIVATE_KEY (Email Private Key):

        The private key from your Nodemailer email service provider.

      • EMAIL_DOMAIN (Email Domain):

        Domain or subdomain configured for sending emails.

      • MAIL_SENDER (Sender Email Address):

        The verified sender address used by your mailer - Nodemailer to send emails from the application. This email must be authorized in your email service configuration.

        πŸ“Œ Note: In development, you can use a test email. In production, make sure this is a verified and authenticated sender (especially for services like Mailgun, SendGrid, etc.).


    ⚠️ Caution:
    Never commit your .env file to version control (GitHub, Git, etc.) as it contains sensitive credentials. Always keep this file private and add .env to your .gitignore.

  4. Start the server:

    npm start

πŸ“‘ API Endpoints

Easily integrate with the MTB Coaching Network backend using these RESTful API endpoints.

❕ NB:
Several endpoints require query or request body parameters for correct operation. If you do not provide the required parameters, you may receive empty results or errors.

Click to expand for a full list of available API endpoints and usage examples
  • Users

    • PUT /users/:email:

      Save or update a user in the database. Expects user data in the request body.

      Required Request Body Parameters:

      • name (string): Full name of the user.
      • role (string): User's role in the system, such as student or instructor

      Example:
      PUT /users/john@example.com

      Body:
      { "name": "John Doe", "role": "Student" }

    • GET /users/:email:

      Get a specific user by email.

      Example:
      GET /users/john@example.com


  • Instructors

    • GET /instructors?count=<number>&search=<string>:

      Get a list of all instructors.
      Optional query parameters:

      • count (number): Limits the number of instructors returned. If omitted, returns all.
      • search (string): Case-insensitive search by instructor name. If omitted, returns all.

      Example:
      GET /instructors?count=5&search=Alex

    • GET /instructors/total:

      Get the total number of instructor accounts registered.

    • GET /instructors/top:

      Get the top 6 instructors (by total students) and a list of all instructors with their total students.

    • GET /instructor/total/:id:

      Get the number of total students of a specific instructor.

      Example:
      GET /instructor/total/6653e1b2c1a2b3d4e5f6a7b8

    • GET /instructor/students/:id/:idx:

      Get the student list of a specific course of a specific instructor (idx represents course-index).

      Example:
      GET /instructor/students/6653e1b2c1a2b3d4e5f6a7b8/0

    • GET /instructor/:id:

      Get a single instructor by MongoDB ObjectId.

      Example:
      GET /instructor/6653e1b2c1a2b3d4e5f6a7b8

    • PUT /instructor/updateStudentCount:

      Update an instructor's class student count.

      Required Request Body Parameters:

      • instructorId (string): The unique identifier of the instructor.
      • classIndex (number): The index of the class to update.

      Example:
      PUT /instructor/updateStudentCount

      Body:
      { "instructorId": "6653e1b2c1a2b3d4e5f6a7b8", "classIndex": 0 }


  • Classes

    • GET /classes/total:

      Get the total number of classes.

    • GET /classes/top:

      Get the top 6 classes (by total students).

    • GET /classes?count=<number>&search=<string>:

      Get all classes.

      Query parameters:

      • count (number): Limits the number of classes returned. If omitted, returns empty array.
      • search (string): Case-insensitive search, filters by class name. If omitted, returns all.

      πŸ“Œ Note:
      count is required & search is optional.

      Examples:
      GET /classes?count=10
      GET /classes?count=5&search=Beginner


  • Bookings

    • PUT /book-class:

      Post a booking. Expects booking details in the request body.

      Required Request Body Parameters:

      • studentId (string): The unique identifier of the student.
      • instructorId (string): The unique identifier of the instructor.
      • studentEmail (string): Email address of the student.
      • studentName (string): Name of the student.
      • classIndex (number): The index of the class to update.
      • paymentStatus (string): ndicates whether the student has completed payment (paid or unpaid).
      • transactionId (string): The unique Stripe transaction ID associated with the payment.
      • date (string): Timestamp of the payment, stored as an ISO date string in MongoDB.

      Example:
      PUT /book-class

      Body:

         {
            "classIndex": 1,
            "instructorId": "664fd275e708c848f468d0cd",
            "studentId": "8b1bba74f6764dd8a92a1111",
            "date": "2023-06-02T01:50:00.000Z",
            "paymentStatus": "paid",
            "studentEmail": "kunderwood@yahoo.com",
            "studentName": "James Aguilar",
            "transactionId": "pi_Nc9zs7Xqr6LXS9W7aCgRr4Uz"
         }
      
    • GET /book-class/:studentId:

      Get all bookings for a user by their studentId.

      Example:
      GET /book-class/6653e1b2c1a2b3d4e5f6a7b8

    • GET /book-class/:loggedId/:studentId/:itemId:

      Get a specific booking by studentId and booking itemId.

      ⚠️ Security Note:
      The loggedId parameter represents the currently logged-in user's ID. The server compares loggedId with studentId to ensure that users can only access their own bookings. If the IDs do not match, access is denied. This mechanism prevents users from viewing or manipulating bookings that do not belong to them, enforcing user-level access control.

      Example:
      GET /book-class/6653e1b2c1a2b3d4e5f6a7b8/6653e1b2c1a2b3d4e5f6a7b8/6653e1b2c1a2b3d4e5f6a7c0

    • DELETE /book-class/:studentId:

      Delete a specific booking by studentId and itemId.

      Required Request Body Parameters:

      • instructorId (string): The unique identifier of the instructor.
      • classIndex (number): The index of the class to update.

      Example:
      DELETE /book-class/6653e1b2c1a2b3d4e5f6a7b8

      Body:
      { "instructorId": "6653e1b2c1a2b3d4e5f6a7b8", "classIndex": 0 }

    • DELETE /booking/:studentId:

      Delete all unpaid bookings for a user by studentId.

      Example:
      DELETE /booking/6653e1b2c1a2b3d4e5f6a7b8

    • POST /create-payment-intent:

      Create a Stripe payment intent. Expects { price } in the request body.

      Required Request Body Parameters:

      • price (number): The amount to be charged for the payment intent.

      Example:
      POST /create-payment-intent

      Body:
      { "price": 99.99 }


πŸ§ͺ Testing the API

  • Use Postman, Insomnia, or your browser (for GET requests) to test endpoints.
  • For endpoints requiring query parameters, always include them in the URL.
  • For POST/PUT endpoints, provide the required JSON body.
  • The server responds with JSON data for all endpoints.

❕ NB: For more details on request/response formats, see the source code in src/routes/.


πŸ“¨ Email System

This server uses Nodemailer with Mailgun and Handlebars templating to send transactional emails, such as:

  • Enrollment confirmations
  • Payment receipts

⚠️ Note on Email Testing:
Due to the use of a Mailgun sandbox domain (part of the free-tier setup), emails can only be sent to pre-authorized recipients. This means only specified test addresses (e.g., mine) will successfully receive emails. Other users will not receive them unless added as authorized recipients.

To evaluate the email system:

Transaction Confirmation Email Example


πŸ”„ Demo Data Freshness

To keep the course list always fresh (so courses don't all end up as "ended" after a while), the backend provides a way to randomize instructor class dates:

  • Procedure: Run scripts/updateClassDate.js manually or run npm run refresh to randomize all instructor class dates in the database. This simulates a real, active site with a mix of "ongoing", "upcoming", and "ended" courses.
  • Purpose: Ensures the UI always displays a realistic mix of course statuses for demo/testing.

πŸ’» Checkout the Client End

Visit the front-end repository of the website.


🌐 Live Deployment

The API is deployed on Render and can be accessed at this URL.

⚠️ Note on Free Hosting (Render):
The backend is hosted on Render’s free plan. The server will β€œspin down” after inactivity, so the first request after a while may take up to 50 seconds to respond. Subsequent requests will be fast. This is normal for free-tier hosting.


🟒 Uptime Monitoring

The server’s uptime is monitored by UptimeRobot. View real-time status here.

Note on Uptime Monitoring:
Uptime is monitored continuously using UptimeRobot, so if the server ever β€œspins down” unexpectedly, we’ll know right away.


🀝 Contributing

Have ideas to improve this API? Found a bug? Let’s make it better together! Open an issue or submit a pull request.


πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

About

This repository hosts the server-side codebase for the "Professional Mountain Biking Coaching Network" website. Serving as the backend component of the project, it encompasses the logic, APIs, user authentication and database interactions necessary to power the website's functionality.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors