fix(submissions): resolve Mongoose populate error for hybrid BlogPost model
- BlogPost uses native MongoDB (not Mongoose), causing MissingSchemaError
- Removed all .populate('blogPostId') calls that tried to reference non-existent Mongoose model
- Manually fetch blog post data in controllers when needed
- Updated getSubmissions, getSubmissionById, getSubmissionByBlogPost, exportSubmission
- Updated SubmissionTracking static methods: getByStatus, getByPublication
- Standalone submissions (like Le Monde) now display without errors
This commit is contained in:
parent
7f865fbe70
commit
6626cbc7e1
2 changed files with 81 additions and 15 deletions
|
|
@ -81,24 +81,44 @@ async function getSubmissions(req, res) {
|
||||||
if (status) query.status = status;
|
if (status) query.status = status;
|
||||||
if (publicationId) query.publicationId = publicationId;
|
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)
|
const submissions = await SubmissionTracking.find(query)
|
||||||
.populate({
|
|
||||||
path: 'blogPostId',
|
|
||||||
select: 'title slug',
|
|
||||||
options: { strictPopulate: false } // Allow null blogPostId
|
|
||||||
})
|
|
||||||
.populate('createdBy', 'email')
|
.populate('createdBy', 'email')
|
||||||
.sort({ submittedAt: -1, createdAt: -1 })
|
.sort({ submittedAt: -1, createdAt: -1 })
|
||||||
.limit(parseInt(limit, 10))
|
.limit(parseInt(limit, 10))
|
||||||
.skip(parseInt(offset, 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);
|
const total = await SubmissionTracking.countDocuments(query);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
count: submissions.length,
|
count: submissionsWithBlogData.length,
|
||||||
total,
|
total,
|
||||||
data: submissions
|
data: submissionsWithBlogData
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Submissions] Get submissions error:', error);
|
console.error('[Submissions] Get submissions error:', error);
|
||||||
|
|
@ -118,7 +138,6 @@ async function getSubmissionById(req, res) {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
||||||
const submission = await SubmissionTracking.findById(id)
|
const submission = await SubmissionTracking.findById(id)
|
||||||
.populate('blogPostId', 'title slug content')
|
|
||||||
.populate('createdBy', 'email')
|
.populate('createdBy', 'email')
|
||||||
.populate('lastUpdatedBy', 'email')
|
.populate('lastUpdatedBy', 'email')
|
||||||
.populate('notes.author', '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({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
data: submission
|
data: submissionObj
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Submissions] Get submission by ID error:', error);
|
console.error('[Submissions] Get submission by ID error:', error);
|
||||||
|
|
@ -282,7 +319,6 @@ async function getSubmissionByBlogPost(req, res) {
|
||||||
const { blogPostId } = req.params;
|
const { blogPostId } = req.params;
|
||||||
|
|
||||||
const submission = await SubmissionTracking.findOne({ blogPostId })
|
const submission = await SubmissionTracking.findOne({ blogPostId })
|
||||||
.populate('blogPostId', 'title slug content')
|
|
||||||
.populate('createdBy', 'email')
|
.populate('createdBy', 'email')
|
||||||
.populate('lastUpdatedBy', '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({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
data: submission
|
data: submissionObj
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Submissions] Get by blog post error:', error);
|
console.error('[Submissions] Get by blog post error:', error);
|
||||||
|
|
@ -370,8 +422,7 @@ async function exportSubmission(req, res) {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { format = 'json' } = req.query;
|
const { format = 'json' } = req.query;
|
||||||
|
|
||||||
const submission = await SubmissionTracking.findById(id)
|
const submission = await SubmissionTracking.findById(id);
|
||||||
.populate('blogPostId', 'title content');
|
|
||||||
|
|
||||||
if (!submission) {
|
if (!submission) {
|
||||||
return res.status(404).json({
|
return res.status(404).json({
|
||||||
|
|
@ -383,6 +434,21 @@ async function exportSubmission(req, res) {
|
||||||
const language = req.query.language || 'en';
|
const language = req.query.language || 'en';
|
||||||
const packageData = submission.exportPackage(language);
|
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') {
|
if (format === 'json') {
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
|
|
|
||||||
|
|
@ -218,20 +218,20 @@ SubmissionTrackingSchema.virtual('submissionDurationDays').get(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get submissions by status
|
* 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) {
|
SubmissionTrackingSchema.statics.getByStatus = async function(status) {
|
||||||
return await this.find({ status })
|
return await this.find({ status })
|
||||||
.populate('blogPostId', 'title slug')
|
|
||||||
.populate('createdBy', 'email')
|
.populate('createdBy', 'email')
|
||||||
.sort({ submittedAt: -1 });
|
.sort({ submittedAt: -1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get submissions for a specific publication
|
* 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) {
|
SubmissionTrackingSchema.statics.getByPublication = async function(publicationId) {
|
||||||
return await this.find({ publicationId })
|
return await this.find({ publicationId })
|
||||||
.populate('blogPostId', 'title slug')
|
|
||||||
.sort({ submittedAt: -1 });
|
.sort({ submittedAt: -1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue