update role claims, refactor getUniqueValues

This commit is contained in:
2025-05-16 17:25:39 +05:30
parent 4028c05d5f
commit c73d57410a
15 changed files with 114 additions and 191 deletions

View File

@@ -5,12 +5,8 @@ import {
deleteNoteHandler, deleteNoteHandler,
updateNoteHandler, updateNoteHandler,
} from "./note.controller"; } from "./note.controller";
import { Claim } from "../utils/claims";
export async function noteRoutes( export async function noteRoutes(fastify: FastifyInstance) {
fastify: FastifyInstance,
claims: { read: Claim; write: Claim; delete: Claim }
) {
fastify.post( fastify.post(
"/:resourceId/notes", "/:resourceId/notes",
{ {
@@ -20,7 +16,7 @@ export async function noteRoutes(
properties: { resourceId: { type: "string" } }, properties: { resourceId: { type: "string" } },
}, },
}, },
config: { requiredClaims: [claims.write] }, config: { requiredClaims: ["note:write"] },
preHandler: [fastify.authorize], preHandler: [fastify.authorize],
}, },
createNoteHandler createNoteHandler
@@ -35,7 +31,7 @@ export async function noteRoutes(
properties: { resourceId: { type: "string" } }, properties: { resourceId: { type: "string" } },
}, },
}, },
config: { requiredClaims: [claims.read] }, config: { requiredClaims: ["note:read"] },
preHandler: [fastify.authorize], preHandler: [fastify.authorize],
}, },
listNotesHandler listNotesHandler
@@ -53,7 +49,7 @@ export async function noteRoutes(
}, },
}, },
}, },
config: { requiredClaims: [claims.write] }, config: { requiredClaims: ["note:write"] },
preHandler: [fastify.authorize], preHandler: [fastify.authorize],
}, },
updateNoteHandler updateNoteHandler
@@ -71,7 +67,7 @@ export async function noteRoutes(
}, },
}, },
}, },
config: { requiredClaims: [claims.write] }, config: { requiredClaims: ["note:delete"] },
preHandler: [fastify.authorize], preHandler: [fastify.authorize],
}, },
deleteNoteHandler deleteNoteHandler

View File

@@ -6,8 +6,8 @@ import {
listNotificationsHandler, listNotificationsHandler,
updateNotificationHandler, updateNotificationHandler,
} from "./notification.controller"; } from "./notification.controller";
import { getUniqueValuesNotification } from "./notification.service";
import { noteRoutes } from "../note/note.route"; import { noteRoutes } from "../note/note.route";
import { getUniqueFields } from "../unique";
export async function notificationRoutes(fastify: FastifyInstance) { export async function notificationRoutes(fastify: FastifyInstance) {
fastify.post( fastify.post(
@@ -95,9 +95,10 @@ export async function notificationRoutes(fastify: FastifyInstance) {
const { field } = req.params as { field: string }; const { field } = req.params as { field: string };
try { try {
const uniqueValues = await getUniqueValuesNotification( const uniqueValues = await getUniqueFields(
field, field,
req.user.tenantId "notifications",
req.user
); );
return res.code(200).send(uniqueValues); return res.code(200).send(uniqueValues);
} catch (err) { } catch (err) {
@@ -106,9 +107,5 @@ export async function notificationRoutes(fastify: FastifyInstance) {
} }
); );
await noteRoutes(fastify, { await noteRoutes(fastify);
read: "rts:read",
write: "rts:write",
delete: "rts:delete",
});
} }

View File

@@ -139,29 +139,3 @@ export async function deleteNotification(notifId: string, tenantId: string) {
$and: [{ tenantId: tenantId }, { pid: notifId }], $and: [{ tenantId: tenantId }, { pid: notifId }],
}); });
} }
export async function getUniqueValuesNotification(
field: string,
tenenatId: string
) {
let values = await notificationModel.distinct(field, { tenantId: tenenatId });
let matchedValues = [];
if (field === "county.name") {
matchedValues = await orgModel.find().where("name").in(values).exec();
} else if (field === "client") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

View File

@@ -4,7 +4,6 @@ import {
createPermit, createPermit,
deletePermit, deletePermit,
getPermit, getPermit,
getUniqueValuesPermit,
listPermits, listPermits,
searchPermit, searchPermit,
updatePermit, updatePermit,
@@ -103,17 +102,3 @@ export async function searchPermitHandler(
return err; return err;
} }
} }
export async function getUniqueFieldValuesPermit(
req: FastifyRequest,
res: FastifyReply
) {
const { field } = req.params as { field: string };
try {
const uniqueValues = await getUniqueValuesPermit(field, req.user.tenantId);
return res.code(200).send(uniqueValues);
} catch (err) {
return err;
}
}

View File

@@ -1,9 +1,7 @@
import { FastifyInstance } from "fastify"; import { FastifyInstance } from "fastify";
import { import {
createPermitHandler,
deletePermitHandler, deletePermitHandler,
getPermitHandler, getPermitHandler,
getUniqueFieldValuesPermit,
listPermitsHandler, listPermitsHandler,
searchPermitHandler, searchPermitHandler,
updatePermitHandler, updatePermitHandler,
@@ -11,6 +9,7 @@ import {
import { $permit } from "./permit.schema"; import { $permit } from "./permit.schema";
import { hideFields } from "../auth"; import { hideFields } from "../auth";
import { noteRoutes } from "../note/note.route"; import { noteRoutes } from "../note/note.route";
import { getUniqueFields } from "../unique";
export async function permitRoutes(fastify: FastifyInstance) { export async function permitRoutes(fastify: FastifyInstance) {
/* fastify.post( /* fastify.post(
@@ -109,14 +108,19 @@ export async function permitRoutes(fastify: FastifyInstance) {
config: { requiredClaims: ["permit:read"] }, config: { requiredClaims: ["permit:read"] },
preHandler: [fastify.authorize], preHandler: [fastify.authorize],
}, },
getUniqueFieldValuesPermit async (req, res) => {
const { field } = req.params as { field: string };
try {
const uniqueValues = await getUniqueFields(field, "permits", req.user);
return res.code(200).send(uniqueValues);
} catch (err) {
return err;
}
}
); );
await noteRoutes(fastify, { await noteRoutes(fastify);
read: "permit:read",
write: "permit:write",
delete: "permit:delete",
});
fastify.addHook("onSend", hideFields("permits")); fastify.addHook("onSend", hideFields("permits"));
} }

View File

@@ -324,26 +324,3 @@ export async function searchPermit(
}, },
}; };
} }
export async function getUniqueValuesPermit(field: string, tenenatId: string) {
let values = await permitModel.distinct(field, { tenantId: tenenatId });
let matchedValues = [];
if (field === "county.name") {
matchedValues = await orgModel.find().where("name").in(values).exec();
} else if (field === "client") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

View File

@@ -2,12 +2,12 @@ import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { PageQueryParams } from "../pagination"; import { PageQueryParams } from "../pagination";
import { import {
getProcessedPermit, getProcessedPermit,
getUniqueValuesProcessed,
listProcessedPermits, listProcessedPermits,
updateProcessed, updateProcessed,
} from "./processed.service"; } from "./processed.service";
import { $processed, UpdateProcessedInput } from "./processed.schema"; import { $processed, UpdateProcessedInput } from "./processed.schema";
import { noteRoutes } from "../note/note.route"; import { noteRoutes } from "../note/note.route";
import { getUniqueFields } from "../unique";
export async function processedRoutes(fastify: FastifyInstance) { export async function processedRoutes(fastify: FastifyInstance) {
fastify.get( fastify.get(
@@ -120,9 +120,10 @@ export async function processedRoutes(fastify: FastifyInstance) {
const { field } = req.params as { field: string }; const { field } = req.params as { field: string };
try { try {
const uniqueValues = await getUniqueValuesProcessed( const uniqueValues = await getUniqueFields(
field, field,
req.user.tenantId "processed",
req.user
); );
return res.code(200).send(uniqueValues); return res.code(200).send(uniqueValues);
} catch (err) { } catch (err) {
@@ -131,9 +132,5 @@ export async function processedRoutes(fastify: FastifyInstance) {
} }
); );
await noteRoutes(fastify, { await noteRoutes(fastify);
read: "permit:read",
write: "permit:write",
delete: "permit:delete",
});
} }

View File

@@ -155,29 +155,3 @@ export async function listProcessedPermits(
}, },
}; };
} }
export async function getUniqueValuesProcessed(
field: string,
tenenatId: string
) {
let values = await processedModel.distinct(field, { tenantId: tenenatId });
let matchedValues = [];
if (field === "county.name") {
matchedValues = await orgModel.find().where("name").in(values).exec();
} else if (field === "client") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

View File

@@ -10,7 +10,7 @@ import {
} from "./rts.controller"; } from "./rts.controller";
import { hideFields } from "../auth"; import { hideFields } from "../auth";
import { noteRoutes } from "../note/note.route"; import { noteRoutes } from "../note/note.route";
import { getUniqueValuesRTS } from "./rts.service"; import { getUniqueFields } from "../unique";
export async function rtsRoutes(fastify: FastifyInstance) { export async function rtsRoutes(fastify: FastifyInstance) {
fastify.post( fastify.post(
@@ -114,7 +114,7 @@ export async function rtsRoutes(fastify: FastifyInstance) {
const { field } = req.params as { field: string }; const { field } = req.params as { field: string };
try { try {
const uniqueValues = await getUniqueValuesRTS(field, req.user.tenantId); const uniqueValues = await getUniqueFields(field, "rts", req.user);
return res.code(200).send(uniqueValues); return res.code(200).send(uniqueValues);
} catch (err) { } catch (err) {
return err; return err;
@@ -122,11 +122,7 @@ export async function rtsRoutes(fastify: FastifyInstance) {
} }
); );
await noteRoutes(fastify, { await noteRoutes(fastify);
read: "rts:read",
write: "rts:write",
delete: "rts:delete",
});
fastify.addHook("onSend", hideFields("rts")); fastify.addHook("onSend", hideFields("rts"));
} }

View File

@@ -209,28 +209,3 @@ export async function newUpload(
} }
); );
} }
export async function getUniqueValuesRTS(field: string, tenenatId: string) {
let values = await rtsModel.distinct(field, { tenantId: tenenatId });
let matchedValues = [];
if (field === "county") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "client") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "createdBy") {
matchedValues = await userModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

View File

@@ -10,7 +10,7 @@ import {
updateTaskHandler, updateTaskHandler,
} from "./task.controller"; } from "./task.controller";
import { noteRoutes } from "../note/note.route"; import { noteRoutes } from "../note/note.route";
import { getUniqueValuesTasks } from "./task.service"; import { getUniqueFields } from "../unique";
export async function taskRoutes(fastify: FastifyInstance) { export async function taskRoutes(fastify: FastifyInstance) {
fastify.post( fastify.post(
@@ -126,10 +126,7 @@ export async function taskRoutes(fastify: FastifyInstance) {
const { field } = req.params as { field: string }; const { field } = req.params as { field: string };
try { try {
const uniqueValues = await getUniqueValuesTasks( const uniqueValues = await getUniqueFields(field, "task", req.user);
field,
req.user.tenantId
);
return res.code(200).send(uniqueValues); return res.code(200).send(uniqueValues);
} catch (err) { } catch (err) {
return err; return err;
@@ -137,9 +134,5 @@ export async function taskRoutes(fastify: FastifyInstance) {
} }
); );
await noteRoutes(fastify, { await noteRoutes(fastify);
read: "task:read",
write: "task:write",
delete: "task:delete",
});
} }

View File

@@ -251,28 +251,3 @@ export async function newUpload(
} }
); );
} }
export async function getUniqueValuesTasks(field: string, tenenatId: string) {
let values = await taskModel.distinct(field, { tenantId: tenenatId });
let matchedValues = [];
if (field === "county") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "client") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "createdBy") {
matchedValues = await userModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

65
src/unique.ts Normal file
View File

@@ -0,0 +1,65 @@
import { orgModel } from "./organization/organization.schema";
import { userModel } from "./user/user.schema";
import { permitModel } from "./permit/permit.schema";
import { processedModel } from "./processed/processed.schema";
import { notificationModel } from "./notification/notification.schema";
import { rtsModel } from "./rts/rts.schema";
import { taskModel } from "./task/task.schema";
import { AuthenticatedUser } from "./auth";
type Collection =
| "users"
| "permits"
| "organizations"
| "processed"
| "notifications"
| "rts"
| "task";
const modelMap = {
users: userModel,
permits: permitModel,
organizations: orgModel,
processed: processedModel,
notifications: notificationModel,
rts: rtsModel,
task: taskModel,
};
export async function getUniqueFields(
field: string,
collection: Collection,
user: AuthenticatedUser
) {
const model = modelMap[collection];
if (!model) throw new Error("invalid collection");
let values = await model.distinct(field, { tenantId: user.tenantId });
let matchedValues = [];
if (field === "county.name") {
matchedValues = await orgModel.find().where("name").in(values).exec();
} else if (field === "county") {
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "client") {
if (user.role == "client") {
values = [user.orgId];
}
matchedValues = await orgModel.find().where("_id").in(values).exec();
} else if (field === "createdBy") {
matchedValues = await userModel.find().where("_id").in(values).exec();
} else if (field === "assignedTo") {
matchedValues = await userModel.find().where("_id").in(values).exec();
}
if (matchedValues.length > 0) {
const newValues = {};
for (const item of matchedValues) {
newValues[item.id] = item.name;
}
return newValues;
}
return values;
}

View File

@@ -28,4 +28,7 @@ export type Claim =
| "mail:all" | "mail:all"
| "view:read" | "view:read"
| "view:write" | "view:write"
| "view:delete"; | "view:delete"
| "note:read"
| "note:write"
| "note:delete";

View File

@@ -33,6 +33,9 @@ export const rules: Record<
"view:read", "view:read",
"view:write", "view:write",
"view:delete", "view:delete",
"note:read",
"note:write",
"note:delete",
], ],
hiddenFields: { hiddenFields: {
orgs: ["__v"], orgs: ["__v"],
@@ -67,6 +70,9 @@ export const rules: Record<
"view:read", "view:read",
"view:write", "view:write",
"view:delete", "view:delete",
"note:read",
"note:write",
"note:delete",
], ],
hiddenFields: { hiddenFields: {
orgs: ["__v"], orgs: ["__v"],
@@ -94,6 +100,9 @@ export const rules: Record<
"view:read", "view:read",
"view:write", "view:write",
"view:delete", "view:delete",
"note:read",
"note:write",
"note:delete",
], ],
hiddenFields: { hiddenFields: {
orgs: ["__v"], orgs: ["__v"],
@@ -114,6 +123,9 @@ export const rules: Record<
"view:read", "view:read",
"view:write", "view:write",
"view:delete", "view:delete",
"note:read",
"note:write",
"note:delete",
], ],
hiddenFields: { hiddenFields: {
orgs: ["__v"], orgs: ["__v"],