Implement additional backend features and improve data models: Comments System: - Create Comment model with user and post relationships - Add comments routes: GET /api/posts/:postId/comments (paginated), POST (create), DELETE (own comments) - Update Post model with commentsCount field - Emit Socket.IO events for newComment and commentDeleted - Pagination support for comment lists - Authorization checks (users can only delete own comments) - 500 character limit on comments Image Upload System: - Implement Cloudinary configuration (config/cloudinary.js) - Add uploadImage() and deleteImage() helper functions - Image optimization: max 1000x1000, auto quality, auto format (WebP) - Integrate image upload in users routes (profile pictures) - Integrate image upload in posts routes (post images with add/update endpoints) - File validation: 5MB limit, JPG/PNG/GIF/WebP only - Automatic image deletion when removing posts/reports Data Consistency Improvements: - Add cascade deletes in Street model (remove from user, delete associated tasks) - Add cascade deletes in Task model (remove from user completedTasks) - Add cascade deletes in Post model (remove from user posts) - Update user relationships on save (adoptedStreets, completedTasks, posts, events) - Add proper indexes for performance (2dsphere for location, compound indexes) - Add virtual relationships and toJSON configurations Model Updates: - Street: Add cascade hooks, location 2dsphere index - Task: Add cascade hooks, compound indexes for queries - Post: Add imageUrl, cloudinaryPublicId, commentsCount fields - Event: Add participants tracking - Report: Add image upload support - User: Add earnedBadges virtual, profilePicture, cloudinaryPublicId 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
63 lines
1.3 KiB
JavaScript
63 lines
1.3 KiB
JavaScript
const mongoose = require("mongoose");
|
|
|
|
const PostSchema = new mongoose.Schema(
|
|
{
|
|
user: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: "User",
|
|
required: true,
|
|
index: true,
|
|
},
|
|
content: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
imageUrl: {
|
|
type: String,
|
|
},
|
|
cloudinaryPublicId: {
|
|
type: String,
|
|
},
|
|
likes: [
|
|
{
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: "User",
|
|
},
|
|
],
|
|
commentsCount: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
},
|
|
{
|
|
timestamps: true,
|
|
},
|
|
);
|
|
|
|
// Index for querying posts by creation date
|
|
PostSchema.index({ createdAt: -1 });
|
|
|
|
// Update user relationship when post is created
|
|
PostSchema.post("save", async function (doc) {
|
|
const User = mongoose.model("User");
|
|
|
|
// Add post to user's posts if not already there
|
|
await User.updateOne(
|
|
{ _id: doc.user },
|
|
{ $addToSet: { posts: doc._id } }
|
|
);
|
|
});
|
|
|
|
// Cascade cleanup when a post is deleted
|
|
PostSchema.pre("deleteOne", { document: true, query: false }, async function () {
|
|
const User = mongoose.model("User");
|
|
|
|
// Remove post from user's posts
|
|
await User.updateOne(
|
|
{ _id: this.user },
|
|
{ $pull: { posts: this._id } }
|
|
);
|
|
});
|
|
|
|
module.exports = mongoose.model("Post", PostSchema);
|