import express from 'express'; import cors from 'cors'; import { Low } from 'lowdb'; import { JSONFile } from 'lowdb/node'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const dataDir = join(__dirname, 'data'); import { mkdirSync } from 'fs'; mkdirSync(dataDir, { recursive: true }); const dbFile = join(dataDir, 'db.json'); const adapter = new JSONFile(dbFile); const defaultData = { members: [], projects: [], tasks: [] }; const db = new Low(adapter, defaultData); await db.read(); await db.write(); const app = express(); app.use(cors()); app.use(express.json()); // Member CRUD app.get('/api/members', (req, res) => { res.json(db.data.members); }); app.post('/api/members', (req, res) => { const member = { id: Date.now().toString(), ...req.body }; db.data.members.push(member); db.write(); res.status(201).json(member); }); app.delete('/api/members/:id', (req, res) => { db.data.members = db.data.members.filter(m => m.id !== req.params.id); db.write(); res.status(204).end(); }); app.put('/api/members/:id', async (req, res) => { const idx = db.data.members.findIndex(m => m.id === req.params.id); if (idx === -1) return res.status(404).json({ error: 'Member not found' }); db.data.members[idx] = { ...db.data.members[idx], ...req.body, id: req.params.id }; await db.write(); res.json(db.data.members[idx]); }); // Project CRUD app.get('/api/projects', (req, res) => { res.json(db.data.projects); }); app.post('/api/projects', (req, res) => { const project = { id: Date.now().toString(), members: [], ...req.body }; db.data.projects.push(project); db.write(); res.status(201).json(project); }); app.put('/api/projects/:id', async (req, res) => { const idx = db.data.projects.findIndex(p => p.id === req.params.id); const updated = { ...req.body, id: req.params.id }; if (idx === -1) db.data.projects.push(updated); else db.data.projects[idx] = updated; await db.write(); res.json(updated); }); app.delete('/api/projects/:id', (req, res) => { db.data.projects = db.data.projects.filter(p => p.id !== req.params.id); db.write(); res.status(204).end(); }); // Assign member to project app.post('/api/projects/:projectId/members/:memberId', (req, res) => { const project = db.data.projects.find(p => p.id === req.params.projectId); if (!project) return res.status(404).json({ error: 'Project not found' }); if (!project.members.includes(req.params.memberId)) { project.members.push(req.params.memberId); db.write(); } res.json(project); }); // Tasks (assign to member in project) app.post('/api/projects/:projectId/tasks', (req, res) => { const { title, description, memberId } = req.body; const project = db.data.projects.find(p => p.id === req.params.projectId); if (!project) return res.status(404).json({ error: 'Project not found' }); if (!project.members.includes(memberId)) return res.status(400).json({ error: 'Member not assigned to project' }); const task = { id: Date.now().toString(), projectId: project.id, memberId, title, description, status: 'todo' }; db.data.tasks.push(task); db.write(); res.status(201).json(task); }); app.get('/api/projects/:projectId/tasks', (req, res) => { const tasks = db.data.tasks.filter(t => t.projectId === req.params.projectId); res.json(tasks); }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => console.log(`Backend running on port ${PORT}`));