Files
permit-api/src/note/note.service.ts
2025-09-09 19:26:52 +05:30

149 lines
3.3 KiB
TypeScript

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 }],
});
}