const couchdbService = require("../services/couchdbService"); class Post { static async create(postData) { const { user, content, imageUrl, cloudinaryPublicId } = postData; // Get user data for embedding const userDoc = await couchdbService.findUserById(user); if (!userDoc) { throw new Error("User not found"); } const post = { _id: `post_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, type: "post", user: { userId: user, name: userDoc.name, profilePicture: userDoc.profilePicture || "" }, content, imageUrl, cloudinaryPublicId, likes: [], likesCount: 0, commentsCount: 0, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; const createdPost = await couchdbService.create(post); // Update user's posts array userDoc.posts.push(createdPost._id); userDoc.stats.postsCreated = userDoc.posts.length; await couchdbService.update(user, userDoc); return createdPost; } static async findById(postId) { return await couchdbService.getById(postId); } static async find(query = {}) { const couchQuery = { selector: { type: "post", ...query } }; return await couchdbService.find(couchQuery); } static async findAll(options = {}) { const { skip = 0, limit = 20, sort = { createdAt: -1 } } = options; const query = { selector: { type: "post" }, sort: Object.keys(sort).map(key => [key, sort[key] === -1 ? "desc" : "asc"]), skip, limit }; return await couchdbService.find(query); } static async countDocuments() { const query = { selector: { type: "post" }, fields: ["_id"] }; const docs = await couchdbService.find(query); return docs.length; } static async updatePost(postId, updateData) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } const updatedPost = { ...post, ...updateData, updatedAt: new Date().toISOString() }; return await couchdbService.update(postId, updatedPost); } static async deletePost(postId) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } // Remove post from user's posts array if (post.user && post.user.userId) { const userDoc = await couchdbService.findUserById(post.user.userId); if (userDoc) { userDoc.posts = userDoc.posts.filter(id => id !== postId); userDoc.stats.postsCreated = userDoc.posts.length; await couchdbService.update(post.user.userId, userDoc); } } return await couchdbService.delete(postId); } static async addLike(postId, userId) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } if (!post.likes.includes(userId)) { post.likes.push(userId); post.likesCount = post.likes.length; post.updatedAt = new Date().toISOString(); await couchdbService.update(postId, post); } return post; } static async removeLike(postId, userId) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } const likeIndex = post.likes.indexOf(userId); if (likeIndex > -1) { post.likes.splice(likeIndex, 1); post.likesCount = post.likes.length; post.updatedAt = new Date().toISOString(); await couchdbService.update(postId, post); } return post; } static async incrementCommentsCount(postId) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } post.commentsCount = (post.commentsCount || 0) + 1; post.updatedAt = new Date().toISOString(); return await couchdbService.update(postId, post); } static async decrementCommentsCount(postId) { const post = await couchdbService.getById(postId); if (!post) { throw new Error("Post not found"); } post.commentsCount = Math.max(0, (post.commentsCount || 0) - 1); post.updatedAt = new Date().toISOString(); return await couchdbService.update(postId, post); } static async findByUserId(userId, options = {}) { const { skip = 0, limit = 20 } = options; const query = { selector: { type: "post", "user.userId": userId }, sort: [["createdAt", "desc"]], skip, limit }; return await couchdbService.find(query); } // Legacy compatibility methods for mongoose-like interface static async populate(posts, fields) { // In CouchDB, user data is already embedded in posts // This method is for compatibility with existing code if (fields && fields.includes("user")) { // User data is already embedded, so just return posts as-is return posts; } return posts; } } module.exports = Post;