import { Request, Response } from 'express'; import { AuthenticatedRequest } from '../middleware/auth.middleware'; import * as projectService from '../services/project.service'; import { CreateProjectInput, UpdateProjectInput, ProjectStatusType } from '../validators/project.validator'; /** * GET /projects * List all projects with pagination and optional filtering * Query params: page, pageSize, status, area_name, search */ export async function getAll(req: Request, res: Response): Promise { try { const page = parseInt(req.query.page as string, 10) || 1; const pageSize = Math.min(parseInt(req.query.pageSize as string, 10) || 10, 100); const filters: projectService.ProjectFilters = {}; if (req.query.status) { filters.status = req.query.status as ProjectStatusType; } if (req.query.area_name) { filters.area_name = req.query.area_name as string; } if (req.query.search) { filters.search = req.query.search as string; } const result = await projectService.getAll(filters, { page, pageSize }); res.status(200).json({ success: true, data: result.data, pagination: result.pagination, }); } catch (error) { console.error('Error fetching projects:', error); res.status(500).json({ success: false, error: 'Failed to fetch projects', }); } } /** * GET /projects/:id * Get a single project by ID */ export async function getById(req: Request, res: Response): Promise { try { const { id } = req.params; const project = await projectService.getById(id); if (!project) { res.status(404).json({ success: false, error: 'Project not found', }); return; } res.status(200).json({ success: true, data: project, }); } catch (error) { console.error('Error fetching project:', error); res.status(500).json({ success: false, error: 'Failed to fetch project', }); } } /** * POST /projects * Create a new project * Requires authentication */ export async function create(req: AuthenticatedRequest, res: Response): Promise { try { const userId = req.user?.id; if (!userId) { res.status(401).json({ success: false, error: 'Authentication required', }); return; } const data = req.body as CreateProjectInput; const project = await projectService.create(data, userId); res.status(201).json({ success: true, data: project, }); } catch (error) { console.error('Error creating project:', error); res.status(500).json({ success: false, error: 'Failed to create project', }); } } /** * PUT /projects/:id * Update an existing project * Requires authentication */ export async function update(req: AuthenticatedRequest, res: Response): Promise { try { const { id } = req.params; const data = req.body as UpdateProjectInput; const project = await projectService.update(id, data); if (!project) { res.status(404).json({ success: false, error: 'Project not found', }); return; } res.status(200).json({ success: true, data: project, }); } catch (error) { console.error('Error updating project:', error); res.status(500).json({ success: false, error: 'Failed to update project', }); } } /** * DELETE /projects/:id * Delete a project * Requires admin role */ export async function deleteProject(req: AuthenticatedRequest, res: Response): Promise { try { const { id } = req.params; // First check if project exists const project = await projectService.getById(id); if (!project) { res.status(404).json({ success: false, error: 'Project not found', }); return; } const deleted = await projectService.deleteProject(id); if (!deleted) { res.status(500).json({ success: false, error: 'Failed to delete project', }); return; } res.status(200).json({ success: true, data: { message: 'Project deleted successfully' }, }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to delete project'; // Handle dependency error if (message.includes('Cannot delete project')) { res.status(409).json({ success: false, error: message, }); return; } console.error('Error deleting project:', error); res.status(500).json({ success: false, error: 'Failed to delete project', }); } } /** * GET /projects/:id/stats * Get project statistics */ export async function getStats(req: Request, res: Response): Promise { try { const { id } = req.params; const stats = await projectService.getStats(id); if (!stats) { res.status(404).json({ success: false, error: 'Project not found', }); return; } res.status(200).json({ success: true, data: stats, }); } catch (error) { console.error('Error fetching project stats:', error); res.status(500).json({ success: false, error: 'Failed to fetch project statistics', }); } }