- Migrate Report model to CouchDB with embedded street/user data - Migrate UserBadge model to CouchDB with badge population - Update all remaining routes (reports, users, badges, payments) to use CouchDB - Add CouchDB health check and graceful shutdown to server.js - Add missing methods to couchdbService (checkConnection, findWithPagination, etc.) - Update Kubernetes deployment manifests for CouchDB support - Add comprehensive CouchDB setup documentation All core functionality now uses CouchDB as primary database while maintaining MongoDB for backward compatibility during transition period. 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
151 lines
3.6 KiB
JavaScript
151 lines
3.6 KiB
JavaScript
const express = require("express");
|
|
const Report = require("../models/Report");
|
|
const User = require("../models/User");
|
|
const Street = require("../models/Street");
|
|
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 page = parseInt(req.query.page) || 1;
|
|
const limit = Math.min(parseInt(req.query.limit) || 10, 100);
|
|
|
|
const result = await Report.findWithPagination({
|
|
page,
|
|
limit,
|
|
sort: { createdAt: -1 },
|
|
});
|
|
|
|
res.json({
|
|
reports: result.docs,
|
|
totalCount: result.totalDocs,
|
|
currentPage: result.page,
|
|
totalPages: result.totalPages,
|
|
hasNext: result.hasNextPage,
|
|
hasPrev: result.hasPrevPage,
|
|
});
|
|
}),
|
|
);
|
|
|
|
// Create a report with optional image
|
|
router.post(
|
|
"/",
|
|
auth,
|
|
upload.single("image"),
|
|
handleUploadError,
|
|
createReportValidation,
|
|
asyncHandler(async (req, res) => {
|
|
const { street: streetId, issue } = req.body;
|
|
|
|
// Get street and user data for embedding
|
|
const street = await Street.findById(streetId);
|
|
if (!street) {
|
|
return res.status(404).json({ msg: "Street not found" });
|
|
}
|
|
|
|
const user = await User.findById(req.user.id);
|
|
if (!user) {
|
|
return res.status(404).json({ msg: "User not found" });
|
|
}
|
|
|
|
const reportData = {
|
|
street: {
|
|
_id: street._id,
|
|
name: street.name,
|
|
},
|
|
user: {
|
|
_id: user._id,
|
|
name: user.name,
|
|
profilePicture: user.profilePicture,
|
|
},
|
|
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 report = await Report.create(reportData);
|
|
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._id !== 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",
|
|
);
|
|
|
|
const updatedReport = await Report.update(req.params.id, {
|
|
imageUrl: result.url,
|
|
cloudinaryPublicId: result.publicId,
|
|
});
|
|
|
|
res.json(updatedReport);
|
|
}),
|
|
);
|
|
|
|
// 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" });
|
|
}
|
|
|
|
const updatedReport = await Report.update(req.params.id, {
|
|
status: "resolved",
|
|
});
|
|
|
|
res.json(updatedReport);
|
|
}),
|
|
);
|
|
|
|
module.exports = router;
|