const express = require("express"); const Report = require("../models/Report"); const auth = require("../middleware/auth"); const { asyncHandler } = require("../middleware/errorHandler"); const { createReportValidation, reportIdValidation, } = require("../middleware/validators/reportValidator"); const { upload, handleUploadError } = require("../middleware/upload"); const { uploadImage, deleteImage } = require("../config/cloudinary"); const router = express.Router(); // Get all reports (with pagination) router.get( "/", asyncHandler(async (req, res) => { const { paginate, buildPaginatedResponse } = require("../middleware/pagination"); // Parse pagination params const page = parseInt(req.query.page) || 1; const limit = Math.min(parseInt(req.query.limit) || 10, 100); const skip = (page - 1) * limit; const reports = await Report.find() .sort({ createdAt: -1 }) .skip(skip) .limit(limit) .populate("street", ["name"]) .populate("user", ["name", "profilePicture"]); const totalCount = await Report.countDocuments(); res.json(buildPaginatedResponse(reports, totalCount, page, limit)); }), ); // Create a report with optional image router.post( "/", auth, upload.single("image"), handleUploadError, createReportValidation, asyncHandler(async (req, res) => { const { street, issue } = req.body; const reportData = { street, user: req.user.id, issue, }; // Upload image if provided if (req.file) { const result = await uploadImage( req.file.buffer, "adopt-a-street/reports", ); reportData.imageUrl = result.url; reportData.cloudinaryPublicId = result.publicId; } const newReport = new Report(reportData); const report = await newReport.save(); // Populate user and street data await report.populate([ { path: "user", select: "name profilePicture" }, { path: "street", select: "name" }, ]); res.json(report); }), ); // Add image to existing report router.post( "/:id/image", auth, upload.single("image"), handleUploadError, reportIdValidation, asyncHandler(async (req, res) => { const report = await Report.findById(req.params.id); if (!report) { return res.status(404).json({ msg: "Report not found" }); } // Verify user owns the report if (report.user.toString() !== req.user.id) { return res.status(403).json({ msg: "Not authorized" }); } if (!req.file) { return res.status(400).json({ msg: "No image file provided" }); } // Delete old image if exists if (report.cloudinaryPublicId) { await deleteImage(report.cloudinaryPublicId); } // Upload new image const result = await uploadImage( req.file.buffer, "adopt-a-street/reports", ); report.imageUrl = result.url; report.cloudinaryPublicId = result.publicId; await report.save(); res.json(report); }), ); // Resolve a report router.put( "/:id", auth, reportIdValidation, asyncHandler(async (req, res) => { const report = await Report.findById(req.params.id); if (!report) { return res.status(404).json({ msg: "Report not found" }); } report.status = "resolved"; await report.save(); res.json(report); }), ); module.exports = router;