import { createAlert } from "../alert/alert.service"; import { AuthenticatedUser } from "../auth"; import { generateId } from "../utils/id"; import { extractExpressions, modelMap } from "../utils/tags"; import { CreateNoteInput, noteModel } from "./note.schema"; export async function createNote( input: CreateNoteInput, resourceId: string, resourceType: string, user: AuthenticatedUser ) { const userIds = extractExpressions(input.content); const taggedUsers = userIds.map((item) => { return { userId: item, taggedAt: new Date(), }; }); const newNote = await noteModel.create({ tenantId: user.tenantId, pid: generateId(), resourceId: resourceId, content: input.content, createdAt: new Date(), createdBy: user.userId, }); if ( userIds.length > 0 && [ "permits", "processed", "rts", "tasks", "ctasks", "payments", "notifications", ].includes(resourceType) ) { const model = modelMap[resourceType]; const obj = await model.findOne({ pid: resourceId }); if (!obj.taggedUsers) { await model.updateOne( { pid: resourceId }, { $set: { taggedUsers: taggedUsers, assignedTo: userIds[0] } } ); } else { for (const user of taggedUsers) { const userIndex = obj.taggedUsers.findIndex( (item) => item.userId == user.userId ); if (userIndex != -1) obj.taggedUsers[userIndex].taggedAt = new Date(); else obj.taggedUsers.push(user); } obj.assignedTo = userIds[0]; obj.markModified("taggedUsers", "assignedTo"); await obj.save(); } for (const id of userIds) { if (id == user.userId) continue; await createAlert( user.tenantId, "You are tagged in a note", "user", id, resourceId, resourceType ); } } return newNote.populate({ path: "createdBy", select: "pid name avatar" }); } export async function updateNote( input: CreateNoteInput, resourceId: string, noteId: string, tenantId: string ) { return await noteModel .findOneAndUpdate( { $and: [ { pid: noteId }, { tenantId: tenantId }, { resourceId: resourceId }, ], }, { ...input }, { new: true } ) .populate({ path: "createdBy", select: "pid name avatar" }); } export async function listNotes(resourceId: string, tenantId: string) { return await noteModel.aggregate([ { $match: { $and: [{ resourceId: resourceId }, { tenantId: tenantId }] }, }, { $lookup: { from: "users", localField: "createdBy", foreignField: "_id", as: "user", }, }, { $project: { _id: 1, pid: 1, resourceId: 1, content: 1, createdAt: 1, createdBy: { $let: { vars: { user: { $arrayElemAt: ["$user", 0] } }, in: { _id: "$$user._id", pid: "$$user.pid", name: "$$user.name", avatar: "$$user.avatar", }, }, }, }, }, ]); } export async function deleteNote( resourceId: string, noteId: string, tenantId: string ) { return await noteModel.deleteOne({ $and: [{ pid: noteId }, { tenantId: tenantId }, { resourceId: resourceId }], }); }