Skip to content

Kumar-Amitesh/CryptoPulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 

Repository files navigation

🚀 CryptoPulse

CryptoPulse is a high-performance backend for a cryptocurrency tracking application. It consists of two main services: an api-server (a RESTful API for user management, watchlists, and data retrieval) and a work-server (a background worker that continuously fetches data from the CoinGecko API). The services are decoupled via a Redis cache, ensuring the API remains fast and responsive while data is kept up-to-date by the worker.


🧠 Table of Contents


📌 Project Overview

CryptoPulse is built with Node.js, Express, MongoDB, and Redis. The api-server handles all client-facing requests, managing user authentication (JWT & Google OAuth), profile settings, and watchlist modifications. All cryptocurrency data is served directly from a Redis cache to ensure low latency.

The work-server runs on a schedule (node-cron) to populate and refresh this Redis cache by fetching data from the CoinGecko API. It fetches the top 500 coins for general display and intelligently fetches any other specific coins that users have added to their watchlists.


📁 Folder Structure

CryptoPulse/
│
├── api-server/          # REST API server
│   ├── src/
│   │   ├── config/         # Database & Redis configs
│   │   ├── controllers/    # Request handlers (logic)
│   │   ├── middleware/     # Auth, validation, file handling
│   │   ├── models/         # Mongoose schemas
│   │   ├── routes/         # API route definitions
│   │   ├── utils/          # Utilities (logger, cloudinary, etc.)
│   │   ├── app.js          # Express app configuration
│   │   ├── index.js        # Main entry point
│   │   └── constants.js    # App constants
│   ├── logs/              # Winston log files (gitignored)
│   ├── public/            # Static files/uploads
│   └── package.json       # Dependencies
│
└── work-server/         # Background worker service
    ├── src/
    │   ├── config/         # Database & Redis configs
    │   ├── models/         # Mongoose schemas
    │   ├── utils/          # Axios instance
    │   ├── index.js        # Cron jobs and data fetching logic
    │   └── constants.js    # Worker constants
    └── package.json       # Dependencies

🔧 Features

🧩 api-server

  • Authentication: Secure user registration and login with JWT (access/refresh tokens) and Google OAuth 2.0 integration.
  • User Management: Update user profiles, change passwords, and upload avatars to Cloudinary.
  • Crypto Data: Blazing-fast paginated coin data and single-coin lookups, read directly from the Redis cache.
  • Watchlist Management: Authenticated users can add, remove, and view coins on their personal watchlist.
  • Security: Hardened with helmet, cors, express-rate-limit for request limiting, and express-validator for input sanitization.
  • Logging: Robust multi-transport logging (console, file) using winston for error, warn, and http levels.

⏱ work-server

  • Scheduled Jobs: Uses node-cron to run data-fetching tasks automatically on a defined schedule.
  • Efficient Caching: Fetches and caches the top 500 coins (ranked by market cap) from the CoinGecko API to serve the main dashboard pages.
  • Dynamic Watchlist Fetching: Intelligently queries the database for all unique coins on user watchlists and fetches any that are not already in the cache (e.g., coins ranked #501+), ensuring all user-requested data is available.

🚀 Getting Started

✅ Prerequisites


🔐 Environment Variables

Create a .env file in the root CryptoPulse/ folder with the following:

# MongoDB
MONGO_URI=mongodb://your_mongo_host:27017/your_db_name

# Redis
REDIS_HOST=your_redis_host
REDIS_PORT=your_redis_port
REDIS_USERNAME=your_redis_username
REDIS_PASSWORD=your_redis_password

# Cloudinary (for avatar uploads)
CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secret

# CoinGecko API (for work-server)
CoinGecko_URL_COIN=https://your_coingecko_api_url
CoinGecko_API_KEY=your_coingecko_api_key

# Google OAuth2
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=http://your_api_url/api/v1/users/auth/google/callback

# JWT Secrets
ACCESS_TOKEN_SECRET=your_access_token_secret
ACCESS_TOKEN_EXPIRY=your_access_token_expiry
REFRESH_TOKEN_SECRET=your_refresh_token_secret
REFRESH_TOKEN_EXPIRY=your_refresh_token_expiry

# Server Configuration
CORS_ORIGIN=http://your_frontend_origin # e.g., http://localhost:3000
PORT=5000 # Port for api-server

📦 Installation

  1. Install dependencies for both servers

    # API server
    cd api-server
    npm install
    
    # Worker server
    cd ../work-server
    npm install
  2. Start MongoDB and Redis Ensure both services are running on your local machine or are accessible.

  3. Run the API server

    cd ../api-server
    node src/index.js
  4. Run the worker server (in a separate terminal)

    cd ../work-server
    node index.js

📡 API Endpoints

(Auth) = Requires a valid JWT access token.

👤 User Routes

Base: /api/v1/users

Method Endpoint Description
POST /register Register a new user. (Expects multipart/form-data for avatar)
POST /login Login with email or username and password.
GET /auth/google Redirects to Google's consent screen for OAuth.
GET /auth/google/callback Callback URL for Google to complete the auth process.
GET /logout (Auth) Logs out the user and clears refresh token.
POST /refresh-token Get a new access token using a valid refresh token.
POST /change-password (Auth) Change the user's password.
GET /current-user (Auth) Fetch the currently logged-in user's profile.
POST /update-account (Auth) Update user's fullName and email.
POST /update-avatar (Auth) Update user's avatar. (Expects multipart/form-data)

📊 Data Routes

Base: /api/v1/coins

Method Endpoint Description
GET / Get a paginated list of coins. Query: ?page=1 or ?page=2.
GET /:id Get detailed data for a single coin by ID (e.g., bitcoin).

⭐ Watchlist Routes

Base: /api/v1/watchlist

Method Endpoint Description
GET / (Auth) Get all coin data for items on the user's watchlist.
POST / (Auth) Add a coin to the watchlist. Body: { "coinId": "cardano" }.
DELETE /:coinId (Auth) Remove a coin from the watchlist (e.g., /api/v1/watchlist/cardano).

📝 Logging

  • Logs are managed via Winston and saved to api-server/logs/.
  • error.log: All error level messages.
  • warn.log: All warn level messages.
  • http.log: All http level messages (request logs).
  • combined.log: Full log aggregation.

⏲ Background Jobs (work-server)

The work-server operates independently to keep the Redis cache fresh. It runs two primary jobs on a schedule:

  1. Top 500 Coins (Runs Every 2 Minutes)

    • Fetches the top 500 coins (2 pages, 250 coins each) from the CoinGecko API.
    • Caches each coin's data individually (e.g., coin:bitcoin -> {...data}).
    • Saves the list of IDs for each page (e.g., page:1 -> ["bitcoin", "ethereum", ...]). This is used by the GET /api/v1/coins endpoint.
  2. Watchlist Coins (Runs Every 5 Minutes)

    • Queries the MongoDB Watchlist collection for all unique coinIds across all users.
    • Checks Redis to see which of these coins are not currently cached (i.e., coins ranked #501+).
    • Fetches data for only the missing coins from CoinGecko in batches.
    • Caches the newly fetched coin data in Redis, where it can be retrieved by the GET /api/v1/watchlist endpoint.

🤝 Contributing

Contributions, issues, and feature requests are welcome!

  1. Fork the repo
  2. Create a new branch (git checkout -b feature-name)
  3. Commit your changes (git commit -m 'Add feature')
  4. Push to the branch (git push origin feature-name)
  5. Open a pull request

About

CryptoPulse is a backend API for a cryptocurrency data platform that provides real-time market data aggregation, secure user authentication (including Google OAuth), and efficient caching using Redis.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors