diff --git a/src/controllers/submissions.controller.js b/src/controllers/submissions.controller.js index f2452e8c..5a7421a8 100644 --- a/src/controllers/submissions.controller.js +++ b/src/controllers/submissions.controller.js @@ -81,24 +81,44 @@ async function getSubmissions(req, res) { if (status) query.status = status; if (publicationId) query.publicationId = publicationId; + // NOTE: BlogPost is a native MongoDB class, not a Mongoose model, + // so we can't use .populate() for blogPostId. Fetch blog post data separately if needed. const submissions = await SubmissionTracking.find(query) - .populate({ - path: 'blogPostId', - select: 'title slug', - options: { strictPopulate: false } // Allow null blogPostId - }) .populate('createdBy', 'email') .sort({ submittedAt: -1, createdAt: -1 }) .limit(parseInt(limit, 10)) .skip(parseInt(offset, 10)); + // Manually fetch blog post titles for submissions that have blogPostId + const submissionsWithBlogData = await Promise.all( + submissions.map(async (submission) => { + const submissionObj = submission.toObject(); + + if (submissionObj.blogPostId) { + try { + const blogPost = await BlogPost.findById(submissionObj.blogPostId); + if (blogPost) { + submissionObj.blogPost = { + title: blogPost.title, + slug: blogPost.slug + }; + } + } catch (err) { + console.error(`[Submissions] Error fetching blog post ${submissionObj.blogPostId}:`, err.message); + } + } + + return submissionObj; + }) + ); + const total = await SubmissionTracking.countDocuments(query); res.json({ success: true, - count: submissions.length, + count: submissionsWithBlogData.length, total, - data: submissions + data: submissionsWithBlogData }); } catch (error) { console.error('[Submissions] Get submissions error:', error); @@ -118,7 +138,6 @@ async function getSubmissionById(req, res) { const { id } = req.params; const submission = await SubmissionTracking.findById(id) - .populate('blogPostId', 'title slug content') .populate('createdBy', 'email') .populate('lastUpdatedBy', 'email') .populate('notes.author', 'email'); @@ -130,9 +149,27 @@ async function getSubmissionById(req, res) { }); } + const submissionObj = submission.toObject(); + + // Manually fetch blog post data if blogPostId exists + if (submissionObj.blogPostId) { + try { + const blogPost = await BlogPost.findById(submissionObj.blogPostId); + if (blogPost) { + submissionObj.blogPost = { + title: blogPost.title, + slug: blogPost.slug, + content: blogPost.content + }; + } + } catch (err) { + console.error(`[Submissions] Error fetching blog post:`, err.message); + } + } + res.json({ success: true, - data: submission + data: submissionObj }); } catch (error) { console.error('[Submissions] Get submission by ID error:', error); @@ -282,7 +319,6 @@ async function getSubmissionByBlogPost(req, res) { const { blogPostId } = req.params; const submission = await SubmissionTracking.findOne({ blogPostId }) - .populate('blogPostId', 'title slug content') .populate('createdBy', 'email') .populate('lastUpdatedBy', 'email'); @@ -293,9 +329,25 @@ async function getSubmissionByBlogPost(req, res) { }); } + const submissionObj = submission.toObject(); + + // Manually fetch blog post data + try { + const blogPost = await BlogPost.findById(blogPostId); + if (blogPost) { + submissionObj.blogPost = { + title: blogPost.title, + slug: blogPost.slug, + content: blogPost.content + }; + } + } catch (err) { + console.error(`[Submissions] Error fetching blog post:`, err.message); + } + res.json({ success: true, - data: submission + data: submissionObj }); } catch (error) { console.error('[Submissions] Get by blog post error:', error); @@ -370,8 +422,7 @@ async function exportSubmission(req, res) { const { id } = req.params; const { format = 'json' } = req.query; - const submission = await SubmissionTracking.findById(id) - .populate('blogPostId', 'title content'); + const submission = await SubmissionTracking.findById(id); if (!submission) { return res.status(404).json({ @@ -383,6 +434,21 @@ async function exportSubmission(req, res) { const language = req.query.language || 'en'; const packageData = submission.exportPackage(language); + // Add blog post data if blogPostId exists + if (submission.blogPostId) { + try { + const blogPost = await BlogPost.findById(submission.blogPostId); + if (blogPost) { + packageData.blogPost = { + title: blogPost.title, + content: blogPost.content + }; + } + } catch (err) { + console.error(`[Submissions] Error fetching blog post:`, err.message); + } + } + if (format === 'json') { res.json({ success: true, diff --git a/src/models/SubmissionTracking.model.js b/src/models/SubmissionTracking.model.js index 75b6d6d2..d1e438b2 100644 --- a/src/models/SubmissionTracking.model.js +++ b/src/models/SubmissionTracking.model.js @@ -218,20 +218,20 @@ SubmissionTrackingSchema.virtual('submissionDurationDays').get(function() { /** * Get submissions by status + * NOTE: BlogPost is a native MongoDB class, not Mongoose model, so we can't populate it */ SubmissionTrackingSchema.statics.getByStatus = async function(status) { return await this.find({ status }) - .populate('blogPostId', 'title slug') .populate('createdBy', 'email') .sort({ submittedAt: -1 }); }; /** * Get submissions for a specific publication + * NOTE: BlogPost is a native MongoDB class, not Mongoose model, so we can't populate it */ SubmissionTrackingSchema.statics.getByPublication = async function(publicationId) { return await this.find({ publicationId }) - .populate('blogPostId', 'title slug') .sort({ submittedAt: -1 }); };