| ```javascript |
| require('dotenv').config(); |
| const express = require('express'); |
| const mongoose = require('mongoose'); |
| const cors = require('cors'); |
| const path = require('path'); |
| const bcrypt = require('bcryptjs'); |
| const jwt = require('jsonwebtoken'); |
| const { v4: uuidv4 } = require('uuid'); |
| |
| const app = express(); |
| const PORT = process.env.PORT || 5000; |
| |
| // Middleware |
| app.use(cors()); |
| app.use(express.json()); |
| app.use(express.static(path.join(__dirname, 'public'))); |
| |
| // Database Connection |
| mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/tasksphere', { |
| useNewUrlParser: true, |
| useUnifiedTopology: true, |
| useCreateIndex: true |
| }).then(() => console.log('MongoDB connected')) |
| .catch(err => console.log(err)); |
| |
| // Models |
| const User = require('./models/User'); |
| const Department = require('./models/Department'); |
| const Task = require('./models/Task'); |
| |
| // Authentication Middleware |
| const authenticate = (req, res, next) => { |
| const token = req.header('x-auth-token'); |
| if (!token) return res.status(401).json({ message: 'No token, authorization denied' }); |
| |
| try { |
| const decoded = jwt.verify(token, process.env.JWT_SECRET); |
| req.user = decoded.user; |
| next(); |
| } catch (err) { |
| res.status(401).json({ message: 'Token is not valid' }); |
| } |
| }; |
| |
| // Routes |
| |
| // Auth Routes |
| app.post('/api/auth/register', async (req, res) => { |
| const { name, email, password, role } = req.body; |
| |
| try { |
| let user = await User.findOne({ email }); |
| if (user) return res.status(400).json({ message: 'User already exists' }); |
| |
| user = new User({ name, email, password, role }); |
| const salt = await bcrypt.genSalt(10); |
| user.password = await bcrypt.hash(password, salt); |
| |
| await user.save(); |
| |
| const payload = { user: { id: user.id } }; |
| jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '5h' }, (err, token) => { |
| if (err) throw err; |
| res.json({ token }); |
| }); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| app.post('/api/auth/login', async (req, res) => { |
| const { email, password } = req.body; |
| |
| try { |
| let user = await User.findOne({ email }); |
| if (!user) return res.status(400).json({ message: 'Invalid credentials' }); |
| |
| const isMatch = await bcrypt.compare(password, user.password); |
| if (!isMatch) return res.status(400).json({ message: 'Invalid credentials' }); |
| |
| const payload = { user: { id: user.id } }; |
| jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '5h' }, (err, token) => { |
| if (err) throw err; |
| res.json({ token }); |
| }); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| // Department Routes |
| app.get('/api/departments', authenticate, async (req, res) => { |
| try { |
| const departments = await Department.find().populate('manager', 'name'); |
| res.json(departments); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| app.post('/api/departments', authenticate, async (req, res) => { |
| const { name, description, manager } = req.body; |
| |
| try { |
| const department = new Department({ name, description, manager }); |
| await department.save(); |
| res.json(department); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| // Task Routes |
| app.get('/api/tasks', authenticate, async (req, res) => { |
| try { |
| const tasks = await Task.find() |
| .populate('department', 'name') |
| .populate('assignedTo', 'name') |
| .populate('createdBy', 'name'); |
| res.json(tasks); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| app.post('/api/tasks', authenticate, async (req, res) => { |
| const { title, description, department, assignedTo, dueDate, priority } = req.body; |
| |
| try { |
| const task = new Task({ |
| title, |
| description, |
| department, |
| assignedTo, |
| dueDate, |
| priority, |
| status: 'pending', |
| createdBy: req.user.id |
| }); |
| |
| await task.save(); |
| res.json(task); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| app.put('/api/tasks/:id', authenticate, async (req, res) => { |
| const { status, completedDate } = req.body; |
| |
| try { |
| let task = await Task.findById(req.params.id); |
| if (!task) return res.status(404).json({ message: 'Task not found' }); |
| |
| task.status = status || task.status; |
| if (status === 'completed') { |
| task.completedDate = completedDate || new Date(); |
| } |
| |
| await task.save(); |
| res.json(task); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| // User Routes |
| app.get('/api/users', authenticate, async (req, res) => { |
| try { |
| const users = await User.find().select('-password'); |
| res.json(users); |
| } catch (err) { |
| console.error(err.message); |
| res.status(500).send('Server error'); |
| } |
| }); |
| |
| // Serve static assets in production |
| if (process.env.NODE_ENV === 'production') { |
| app.use(express.static('client/build')); |
| app.get('*', (req, res) => { |
| res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html')); |
| }); |
| } |
| |
| app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); |
| ``` |