add notification routes

This commit is contained in:
2025-02-05 13:52:04 +05:30
parent 8559aab3da
commit 2d62e9712b
8 changed files with 193 additions and 1 deletions

View File

@@ -0,0 +1,44 @@
import { FastifyRequest, FastifyReply } from "fastify";
import { PageQueryParams } from "../pagination";
import { listNotifications, updateNotification } from "./notification.service";
import { UpdateNotificationInput } from "./notification.schema";
export async function listNotificationsHandler(
req: FastifyRequest,
res: FastifyReply
) {
const queryParams = req.query as PageQueryParams;
try {
const notificationList = await listNotifications(
queryParams,
req.user.tenantId
);
return res.code(200).send(notificationList);
} catch (err) {
return err;
}
}
export async function updateNotificationHandler(
req: FastifyRequest,
res: FastifyReply
) {
const input = req.body as UpdateNotificationInput;
const { notifId } = req.params as { notifId: string };
try {
const updatedNotification = await updateNotification(
notifId,
input,
req.user.tenantId
);
if (!updatedNotification)
return res.code(404).send({ error: "resource not found" });
return res.code(200).send(updatedNotification);
} catch (err) {
return err;
}
}

View File

@@ -0,0 +1,33 @@
import { FastifyInstance } from "fastify";
import { $notification } from "./notification.schema";
import {
listNotificationsHandler,
updateNotificationHandler,
} from "./notification.controller";
export async function notificationRoutes(fastify: FastifyInstance) {
fastify.get(
"/",
{
schema: {
querystring: $notification("pageQueryParams"),
},
config: { requiredClaims: ["notification:read"] },
preHandler: [fastify.authorize],
},
listNotificationsHandler
);
fastify.patch(
"/:notifId",
{
schema: {
params: { type: "object", properties: { notifId: { type: "string" } } },
body: $notification("updateNotificationInput"),
},
config: { requiredClaims: ["notification:write"] },
preHandler: [fastify.authorize],
},
updateNotificationHandler
);
}

View File

@@ -0,0 +1,50 @@
import { buildJsonSchemas } from "fastify-zod";
import mongoose from "mongoose";
import { z } from "zod";
import { pageQueryParams } from "../pagination";
const notificationSchema = new mongoose.Schema({
pid: {
type: String,
unique: true,
},
tenantId: String,
permitNumber: String,
permitLink: String,
status: String,
changes: Object,
county: {
type: mongoose.Types.ObjectId,
ref: "organization",
},
client: {
type: mongoose.Types.ObjectId,
ref: "organization",
},
createdAt: Date,
updatedAt: Date,
});
export const notificationFields = Object.keys(notificationSchema.paths).filter(
(path) => path !== "__v"
);
export const notificationModel = mongoose.model(
"notification",
notificationSchema
);
const updateNotificationInput = z.object({
status: z.string(),
});
export type UpdateNotificationInput = z.infer<typeof updateNotificationInput>;
export const { schemas: notificationSchemas, $ref: $notification } =
buildJsonSchemas(
{
updateNotificationInput,
pageQueryParams,
},
{ $id: "notification" }
);

View File

@@ -0,0 +1,57 @@
import { getFilterObject, getSortObject, PageQueryParams } from "../pagination";
import {
notificationFields,
notificationModel,
UpdateNotificationInput,
} from "./notification.schema";
export async function updateNotification(
notifId: string,
input: UpdateNotificationInput,
tenantId: string
) {
return await notificationModel.findOneAndUpdate(
{ $and: [{ tenantId: tenantId }, { pid: notifId }] },
{
...input,
updatedAt: new Date(),
},
{ new: true }
);
}
export async function listNotifications(
params: PageQueryParams,
tenantId: string
) {
const page = params.page || 1;
const pageSize = params.pageSize || 10;
const sortObj = getSortObject(params, notificationFields);
const filterObj = getFilterObject(params, notificationFields);
const notifications = await notificationModel.aggregate([
{ $match: { $and: [{ tenantId: tenantId }, ...filterObj] } },
{
$facet: {
metadata: [{ $count: "count" }],
data: [
{ $skip: (page - 1) * pageSize },
{ $limit: pageSize },
{ $sort: sortObj },
],
},
},
]);
if (notifications[0].data.length === 0)
return { orgs: [], metadata: { count: 0, page, pageSize } };
return {
orgs: notifications[0].data,
metadata: {
count: notifications[0].metadata[0].count,
page,
pageSize,
},
};
}

View File

@@ -8,6 +8,7 @@ import { fileRoutes } from "./file/file.route";
import { rtsRoutes } from "./rts/rts.route";
import { taskRoutes } from "./task/task.route";
import { realTimeRoutes } from "./realtime/realtime.route";
import { notificationRoutes } from "./notification/notification.route";
export default async function routes(fastify: FastifyInstance) {
fastify.addHook("preHandler", authHandler);
@@ -18,5 +19,6 @@ export default async function routes(fastify: FastifyInstance) {
fastify.register(fileRoutes, { prefix: "/files" });
fastify.register(rtsRoutes, { prefix: "/rts" });
fastify.register(taskRoutes, { prefix: "/tasks" });
fastify.register(notificationRoutes, { prefix: "/notifications" });
fastify.register(realTimeRoutes);
}

View File

@@ -14,6 +14,7 @@ import { oauth } from "./oauth";
import { authRoutes } from "./auth/auth.route";
import { rtsSchemas } from "./rts/rts.schema";
import { taskSchemas } from "./task/task.schema";
import { notificationSchemas } from "./notification/notification.schema";
const app = fastify({ logger: true });
@@ -41,6 +42,7 @@ for (const schema of [
...fileSchemas,
...rtsSchemas,
...taskSchemas,
...notificationSchemas,
]) {
app.addSchema(schema);
}

View File

@@ -19,4 +19,6 @@ export type Claim =
| "rts:delete"
| "task:read"
| "task:write"
| "task:delete";
| "task:delete"
| "notification:read"
| "notification:write";

View File

@@ -24,6 +24,8 @@ export const rules: Record<
"task:read",
"task:write",
"task:delete",
"notification:read",
"notification:write",
],
hiddenFields: {
orgs: ["__v"],