- Replace mongoose Post model with CouchDB-based class using couchdbService - Replace mongoose Comment model with CouchDB-based class using couchdbService - Update posts route to use new CouchDB models with embedded user data - Update comments route to use new CouchDB models with embedded user/post data - Maintain all existing API endpoints and functionality - Add like/unlike functionality for posts - Handle image uploads with Cloudinary integration - Preserve Socket.IO events for real-time updates - Use denormalized structure for better performance with embedded data 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
194 lines
4.9 KiB
JavaScript
194 lines
4.9 KiB
JavaScript
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; |