149 lines
3.3 KiB
TypeScript
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 }],
|
|
});
|
|
}
|