Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
759 changes: 759 additions & 0 deletions API_DOCUMENTATION.md

Large diffs are not rendered by default.

472 changes: 472 additions & 0 deletions PROJECT_SUMMARY.md

Large diffs are not rendered by default.

282 changes: 282 additions & 0 deletions SETUP_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
# Internship Training App - Setup Guide

## Quick Start

### Prerequisites
- Node.js v18+
- MongoDB (local or Atlas)
- npm or yarn

### Step 1: Backend Setup

```bash
# Navigate to backend directory
cd backend

# Install dependencies
npm install

# Create .env file (copy from .env.example)
cp .env.example .env

# Edit .env with your MongoDB URI and other configurations
# For local MongoDB:
# MONGODB_URI=mongodb://localhost:27017/internship-training

# Start the backend server
npm run dev
```

The backend API will be available at `http://localhost:5000`

### Step 2: Frontend Setup

```bash
# Navigate to frontend directory (in a new terminal)
cd frontend

# Install dependencies
npm install

# Create .env file (copy from .env.example)
cp .env.example .env

# Start the frontend development server
npm run dev
```

The frontend will be available at `http://localhost:3000`

## Running with Docker

```bash
# From the root directory
docker-compose up --build

# Stops services
docker-compose down
```

## Database Setup

### Option 1: Local MongoDB

```bash
# Install MongoDB Community Edition
# On macOS with Homebrew:
brew tap mongodb/brew
brew install mongodb-community

# Start MongoDB
brew services start mongodb-community

# Verify connection
mongosh
```

### Option 2: MongoDB Atlas (Cloud)

1. Go to https://www.mongodb.com/cloud/atlas
2. Create a free account
3. Create a cluster
4. Get connection string
5. Update MONGODB_URI in backend .env file

## Seed Data

To populate the database with initial data:

```bash
cd backend
npm run seed
```

This will create:
- 3 Career paths
- 6 Courses
- Modules and lessons for each course
- Sample quiz questions

## API Testing

### Using cURL

```bash
# Register
curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe"
}'

# Login
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'

# Get careers (no auth required)
curl http://localhost:5000/api/careers

# Get current user (requires token)
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://localhost:5000/api/auth/me
```

### Using Postman

1. Import the provided Postman collection
2. Set the `BASE_URL` variable to `http://localhost:5000`
3. Use the token from login response for authenticated endpoints

## Development Workflow

### Backend Development

```bash
# Start development server with hot reload
npm run dev

# Build TypeScript
npm run build

# Run tests
npm run test

# Lint code
npm run lint
```

### Frontend Development

```bash
# Start development server
npm run dev

# Build for production
npm run build

# Run tests
npm run test
```

## Troubleshooting

### MongoDB Connection Failed
- Ensure MongoDB is running
- Check MONGODB_URI in .env
- Verify connection string format

### CORS Errors
- Check CORS_ORIGIN in backend .env
- Ensure frontend URL matches CORS_ORIGIN
- Verify backend is running on the correct port

### Port Already in Use
```bash
# Backend (5000)
lsof -i :5000
kill -9 <PID>

# Frontend (3000)
lsof -i :3000
kill -9 <PID>
```

### Token Expired
- Clear browser localStorage
- Login again to get a new token

## Performance Tips

1. **Database Indexing**: Ensure MongoDB indexes are created for:
- users.email
- enrollments.user + enrollments.course
- progress.user + progress.course

2. **Caching**: Implement Redis for caching:
- Career listings
- Course metadata
- User sessions

3. **Pagination**: All list endpoints support pagination
- Use `?page=1&limit=20` parameters

4. **Lazy Loading**: Frontend components implement code splitting
- Routes are lazy loaded
- Components use React.lazy()

## Deployment

### Backend Deployment (Heroku)

```bash
# Install Heroku CLI
npm install -g heroku

# Login to Heroku
heroku login

# Create app
heroku create your-app-name

# Set environment variables
heroku config:set JWT_SECRET=your_secret_key
heroku config:set MONGODB_URI=your_mongodb_uri

# Deploy
git push heroku main
```

### Frontend Deployment (Vercel)

```bash
# Install Vercel CLI
npm i -g vercel

# Deploy
vercel
```

### Docker Deployment (AWS, GCP, Azure)

1. Build Docker images
2. Push to registry
3. Deploy using container orchestration

## Security Checklist

- [ ] Change JWT_SECRET before production
- [ ] Use HTTPS in production
- [ ] Set secure cookies
- [ ] Implement rate limiting
- [ ] Add request validation
- [ ] Use environment variables for secrets
- [ ] Enable CORS only for trusted domains
- [ ] Implement password strength requirements
- [ ] Add two-factor authentication
- [ ] Regular security audits

## Support

For issues or questions:
1. Check documentation
2. Search existing issues
3. Create a new issue with:
- Detailed description
- Steps to reproduce
- Error messages
- Environment details

## Additional Resources

- [Express.js Documentation](https://expressjs.com)
- [React Documentation](https://react.dev)
- [MongoDB Documentation](https://docs.mongodb.com)
- [TypeScript Documentation](https://www.typescriptlang.org/docs)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
24 changes: 24 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Database
MONGODB_URI=mongodb://localhost:27017/internship-training
MONGODB_TEST_URI=mongodb://localhost:27017/internship-training-test

# Server
PORT=5000
NODE_ENV=development

# JWT
JWT_SECRET=your_jwt_secret_key_change_in_production
JWT_EXPIRATION=7d

# CORS
CORS_ORIGIN=http://localhost:3000

# File Upload
MAX_FILE_SIZE=10485760
UPLOAD_DIR=./uploads

# Email (optional)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your_email@example.com
SMTP_PASSWORD=your_password
15 changes: 15 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

EXPOSE 5000

CMD ["npm", "start"]
48 changes: 48 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "internship-training-backend",
"version": "1.0.0",
"description": "Backend API for Internship Training App",
"main": "src/server.ts",
"scripts": {
"dev": "nodemon src/server.ts",
"build": "tsc",
"start": "node dist/server.js",
"lint": "eslint src --ext .ts",
"test": "jest",
"seed": "ts-node src/seeds/seed.ts"
},
"keywords": [
"internship",
"training",
"api"
],
"author": "",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.0.0",
"dotenv": "^16.0.3",
"bcryptjs": "^2.4.3",
"jsonwebtoken": "^9.0.0",
"cors": "^2.8.5",
"helmet": "^7.0.0",
"express-validator": "^7.0.0",
"multer": "^1.4.5-lts.1",
"axios": "^1.4.0"
},
"devDependencies": {
"@types/express": "^4.17.17",
"@types/node": "^20.0.0",
"@types/bcryptjs": "^2.4.2",
"@types/jsonwebtoken": "^9.0.2",
"typescript": "^5.0.0",
"nodemon": "^2.0.22",
"ts-node": "^10.9.1",
"eslint": "^8.40.0",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"jest": "^29.5.0",
"@types/jest": "^29.5.0",
"ts-jest": "^29.1.0"
}
}
23 changes: 23 additions & 0 deletions backend/src/config/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import mongoose from 'mongoose';
import { logger } from '../utils/logger';

export const connectDB = async (): Promise<void> => {
try {
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017/internship-training';
await mongoose.connect(uri);
logger.info('MongoDB connected successfully');
} catch (error) {
logger.error('MongoDB connection failed', error);
throw error;
}
};

export const disconnectDB = async (): Promise<void> => {
try {
await mongoose.disconnect();
logger.info('MongoDB disconnected');
} catch (error) {
logger.error('MongoDB disconnection failed', error);
throw error;
}
};
Loading