A modern Learning Management System (LMS) built by the Student Web Committee for hosting educational modules, quizzes, progress tracking, and leaderboards.
- Tech Stack
- Project Structure
- Getting Started
- Development
- API Documentation
- Contributing
- Troubleshooting
- Runtime: Node.js
- Framework: Express.js
- Database: MongoDB (Cloud: MongoDB Atlas)
- Authentication: Google OAuth 2.0 + JWT
- Package Manager: npm
- Framework: React 19
- Router: React Router DOM v7
- Build Tool: Vite
- Styling: Tailwind CSS
- Animations: Framer Motion
- Package Manager: npm
Hackstack-Portal/
├── backend/
│ ├── config/
│ │ └── db.js # Database connection config
│ ├── controllers/ # Business logic
│ │ ├── authController.js
│ │ ├── dashboardController.js
│ │ ├── leaderboardController.js
│ │ ├── moduleController.js
│ │ ├── notificationController.js
│ │ ├── progressController.js
│ │ ├── quizController.js
│ │ └── userController.js
│ ├── middleware/ # Express middleware
│ │ ├── adminAuthMiddleware.js
│ │ └── authMiddleware.js
│ ├── models/ # MongoDB schemas
│ │ ├── AdminWhitelist.js
│ │ ├── Leaderboard.js
│ │ ├── Module.js
│ │ ├── Notification.js
│ │ ├── Progress.js
│ │ ├── Quiz.js
│ │ └── User.js
│ ├── routes/ # API endpoints
│ │ ├── adminRoutes.js
│ │ ├── authRoutes.js
│ │ ├── dashboardRoutes.js
│ │ ├── leaderboardRoutes.js
│ │ ├── moduleRoutes.js
│ │ ├── notificationRoutes.js
│ │ ├── progressRoutes.js
│ │ ├── quizRoutes.js
│ │ ├── userRoutes.js
│ │ └── whitelistRoutes.js
│ ├── scripts/ # Utility scripts
│ ├── utils/ # Helper functions
│ ├── .env.example # Environment template
│ ├── Dockerfile
│ ├── docker-compose.yml # Docker configuration
│ ├── package.json
│ └── server.js # Express server entry point
│
├── frontend/
│ ├── adminportal/ # Admin portal pages and API helpers
│ ├── src/
│ │ ├── assets/ # Images, icons, etc.
│ │ ├── components/ # Shared and UI components
│ │ ├── context/
│ │ ├── pages/ # Page components
│ │ ├── services/ # API clients
│ │ ├── utils/
│ │ ├── App.jsx # Main app + routing
│ │ ├── main.jsx # React entry point
│ │ └── index.css
│ ├── public/ # Static assets
│ ├── .env.example # Environment template
│ ├── Dockerfile
│ ├── docker-compose.yml # Docker configuration
│ ├── vite.config.js
│ ├── package.json
│ └── index.html
│
├── .gitignore
├── CONTRIBUTING.md # Contribution guidelines
└── README.md # This file
- Node.js (v18 or higher)
- npm (v8 or higher)
- MongoDB Account (MongoDB Atlas recommended - free tier available)
- Google OAuth Client (for authentication)
git clone <repository-url>
cd Hackstack-Portal- Go to Google Cloud Console → APIs & Services → Credentials
- Click Create Credentials → OAuth client ID (configure the consent screen first if prompted)
- Choose Web application and fill in:
- Name: Hackstack Portal
- Authorized JavaScript origins:
http://localhost:5173 - Authorized redirect URI:
http://localhost:5173/api/auth/google/callback
- Copy your Client ID and Client Secret
- Go to MongoDB Atlas
- Create a free account and cluster
- Create a database user with a strong password
- Get your connection URI (looks like:
mongodb+srv://username:password@cluster.mongodb.net/hackstack)
cd backend
# Install dependencies
npm install
# Create .env file
cp .env.example .env
# Edit .env with your credentials:
# - MONGO_URI: Your MongoDB connection string
# - JWT_SECRET: Generate a random secret (e.g., openssl rand -hex 32)
# - GOOGLE_CLIENT_ID: Your Google OAuth Client ID
# - GOOGLE_CLIENT_SECRET: Your Google OAuth Client Secret
# - FRONTEND_URL: http://localhost:5173 (for development)
# Start the server
npm run devServer runs on http://localhost:5000
cd ../frontend
# Install dependencies
npm install
# Create .env file
cp .env.example .env
# Verify VITE_API_URL=/api (Vite proxies /api → backend, stripping the prefix)
# Start the development server
npm run devFrontend runs on http://localhost:5173
- Navigate to
http://localhost:5173/hackstack/login - Click "Continue with Google"
- You should be redirected to login and then to the dashboard
- ✅ If you see the dashboard, authentication is working!
cd backend
# Start development server (no hot reload; restart after changes)
npm run dev
# Note: Test suite not yet implementedcd frontend
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build locally
npm run preview
# Run linting
npm run lintBackend (.env):
MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/hackstack
JWT_SECRET=your_random_secret_here
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
OAUTH_CALLBACK_URL=http://localhost:5173
FRONTEND_URL=http://localhost:5173
PORT=5000
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change_me
ALLOWED_ADMIN_GOOGLE_EMAILS=admin1@example.com,admin2@example.com
ALLOWED_ADMIN_GOOGLE_IDS=1234567890,0987654321Frontend (.env):
VITE_API_URL=/api
Note: The endpoint tables below show paths as requested through the frontend dev server (
/api/...). The Vite development server proxies these requests by catching the/apiprefix and stripping it before sending the request to the backend. In the backend codebase, the routers are actually mounted at the root (/auth,/modules,/quizzes, etc.).
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/auth/admin/login |
Admin username/password login, returns JWT | ❌ |
| GET | /api/auth/google |
Redirect to Google OAuth | ❌ |
| GET | /api/auth/google/callback |
OAuth callback handler | ❌ |
| GET | /api/auth/me |
Get current user | ✅ |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/modules |
List all modules | ❌ |
| GET | /api/modules/:slug |
Get module by slug | ❌ |
| POST | /api/modules/:id/register |
Register for module | ✅ |
| POST | /api/modules |
Create module | ✅ Admin |
| PUT | /api/modules/:id |
Update module | ✅ Admin |
| DELETE | /api/modules/:id |
Delete module | ✅ Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/quizzes |
List all quizzes | ❌ |
| GET | /api/quizzes/:id |
Get quiz by ID | ❌ |
| POST | /api/quizzes/:id/submit |
Submit quiz answers | ✅ |
| POST | /api/quizzes |
Create quiz | ✅ Admin |
| PATCH | /api/quizzes/:id |
Update quiz | ✅ Admin |
| DELETE | /api/quizzes/:id |
Delete quiz | ✅ Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/progress |
List progress records | ❌ |
| GET | /api/progress/:id |
Get progress record | ❌ |
| PATCH | /api/progress/:id |
Update progress | ✅ |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/users |
List all users | ❌ |
| GET | /api/users/:id |
Get user by ID | ❌ |
| POST | /api/users |
Create user | ❌ |
| PATCH | /api/users/:id |
Update user | ❌ |
| DELETE | /api/users/:id |
Delete user | ❌ |
All admin endpoints require auth + admin middleware:
GET /api/admin/modules- List modulesPOST /api/admin/modules- Create modulePUT /api/admin/modules/:id- Update moduleDELETE /api/admin/modules/:id- Delete module- Similar endpoints for
/admin/quizzes,/admin/progress,/admin/users
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/dashboard |
Get the logged-in user's dashboard data | ✅ |
-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes and test thoroughly
-
Lint your code:
# Frontend (the backend has no lint script yet) cd frontend && npm run lint
-
Commit with clear messages:
git add . git commit -m "feat: describe your changes"
-
Push your branch:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub with a clear description
- JavaScript: Use ES6+ syntax
- React: Use functional components with hooks
- Naming: Use camelCase for variables/functions, PascalCase for components
- Imports: Organize imports (React, third-party, local)
- Comments: Add comments for complex logic
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install# Backend (Port 5000)
lsof -i :5000
kill -9 <PID>
# Frontend (Port 5173)
lsof -i :5173
kill -9 <PID>- Verify connection URI in
.env - Check MongoDB Atlas IP whitelist (add your IP or 0.0.0.0)
- Ensure database user has correct credentials
- Test connection:
mongo "your-connection-string"
- Verify Client ID and Client Secret in
.env - Check OAuth redirect URL matches
http://localhost:5173/api/auth/google/callback - Ensure FRONTEND_URL is correctly set
- Verify
FRONTEND_URLin backend.envmatches your frontend URL - Check that CORS middleware in
server.jsallows your frontend domain
# Rebuild Vite cache
rm -rf frontend/node_modules/.vite
npm run dev- Complete Dashboard component
- Module detail pages with content rendering
- Quiz taking interface
- Progress tracking dashboard
- Leaderboard implementation
- Admin panel UI
- User profile pages
- Notification system
- Test suite (Jest + Supertest for backend, Vitest for frontend)
- API documentation (Swagger/OpenAPI)
- Production deployment guide