perbaikan batas akses pengelola rumah ibadab sesuai dengan yang dipilih

This commit is contained in:
2026-06-03 10:28:15 +07:00
parent 435b714d86
commit 8393e05f96
9 changed files with 336 additions and 49 deletions
+53 -10
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { createRouter, publicQuery } from "./middleware";
import { createRouter, authedQuery } from "./middleware";
import {
findAllDistributions,
findDistributionById,
@@ -8,6 +8,8 @@ import {
} from "./queries/distributions";
import { findRecipientById } from "./queries/recipients";
import { createActivityLog } from "./queries/activityLogs";
import { findPlaceIdsByManagerId } from "./queries/placesOfWorship";
import { TRPCError } from "@trpc/server";
async function logActivitySafe(payload: Parameters<typeof createActivityLog>[0]) {
try {
@@ -18,18 +20,35 @@ async function logActivitySafe(payload: Parameters<typeof createActivityLog>[0])
}
export const distributionRouter = createRouter({
list: publicQuery
list: authedQuery
.input(
z.object({
placeOfWorshipId: z.number().optional(),
recipientId: z.number().optional(),
}).optional()
)
.query(async ({ input }) => {
return findAllDistributions(input?.placeOfWorshipId, input?.recipientId);
.query(async ({ input, ctx }) => {
if (ctx.user.role === "manager") {
const placeIds = await findPlaceIdsByManagerId(ctx.user.id);
if (placeIds.length === 0) return [];
if (input?.placeOfWorshipId) {
if (!placeIds.includes(input.placeOfWorshipId)) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Anda tidak berwenang mengakses data distribusi ini.",
});
}
return findAllDistributions([input.placeOfWorshipId], input?.recipientId);
}
return findAllDistributions(placeIds, input?.recipientId);
}
return findAllDistributions(
input?.placeOfWorshipId ? [input.placeOfWorshipId] : undefined,
input?.recipientId
);
}),
create: publicQuery
create: authedQuery
.input(
z.object({
placeOfWorshipId: z.number().min(1),
@@ -42,7 +61,17 @@ export const distributionRouter = createRouter({
notes: z.string().optional(),
})
)
.mutation(async ({ input }) => {
.mutation(async ({ input, ctx }) => {
if (ctx.user.role === "manager") {
const placeIds = await findPlaceIdsByManagerId(ctx.user.id);
if (!placeIds.includes(input.placeOfWorshipId)) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Anda hanya berwenang mencatat distribusi bantuan untuk rumah ibadah yang Anda kelola.",
});
}
}
const created = await createDistribution({
...input,
amount: input.amount.toString(),
@@ -53,7 +82,7 @@ export const distributionRouter = createRouter({
if (created) {
const recipient = await findRecipientById(created.recipientId);
await logActivitySafe({
userId: input.distributedBy ?? null,
userId: ctx.user.id,
action: "CREATE",
entityType: "distribution",
entityId: created.id,
@@ -66,15 +95,29 @@ export const distributionRouter = createRouter({
return created;
}),
delete: publicQuery
delete: authedQuery
.input(z.object({ id: z.number() }))
.mutation(async ({ input }) => {
.mutation(async ({ input, ctx }) => {
const target = await findDistributionById(input.id);
if (!target) {
throw new TRPCError({ code: "NOT_FOUND", message: "Data tidak ditemukan." });
}
if (ctx.user.role === "manager") {
const placeIds = await findPlaceIdsByManagerId(ctx.user.id);
if (!placeIds.includes(target.placeOfWorshipId)) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Anda tidak berwenang menghapus data distribusi ini.",
});
}
}
await deleteDistribution(input.id);
if (target) {
await logActivitySafe({
userId: target.distributedBy ?? null,
userId: ctx.user.id,
action: "DELETE",
entityType: "distribution",
entityId: target.id,