tambah fitur riwayat aktifitas
This commit is contained in:
@@ -2,9 +2,20 @@ import { z } from "zod";
|
|||||||
import { createRouter, publicQuery } from "./middleware";
|
import { createRouter, publicQuery } from "./middleware";
|
||||||
import {
|
import {
|
||||||
findAllDistributions,
|
findAllDistributions,
|
||||||
|
findDistributionById,
|
||||||
createDistribution,
|
createDistribution,
|
||||||
deleteDistribution,
|
deleteDistribution,
|
||||||
} from "./queries/distributions";
|
} from "./queries/distributions";
|
||||||
|
import { findRecipientById } from "./queries/recipients";
|
||||||
|
import { createActivityLog } from "./queries/activityLogs";
|
||||||
|
|
||||||
|
async function logActivitySafe(payload: Parameters<typeof createActivityLog>[0]) {
|
||||||
|
try {
|
||||||
|
await createActivityLog(payload);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("[activity] failed to write distribution activity", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const distributionRouter = createRouter({
|
export const distributionRouter = createRouter({
|
||||||
list: publicQuery
|
list: publicQuery
|
||||||
@@ -32,18 +43,45 @@ export const distributionRouter = createRouter({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return createDistribution({
|
const created = await createDistribution({
|
||||||
...input,
|
...input,
|
||||||
amount: input.amount.toString(),
|
amount: input.amount.toString(),
|
||||||
distributedBy: input.distributedBy ?? null,
|
distributedBy: input.distributedBy ?? null,
|
||||||
notes: input.notes ?? null,
|
notes: input.notes ?? null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (created) {
|
||||||
|
const recipient = await findRecipientById(created.recipientId);
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: input.distributedBy ?? null,
|
||||||
|
action: "CREATE",
|
||||||
|
entityType: "distribution",
|
||||||
|
entityId: created.id,
|
||||||
|
details: recipient
|
||||||
|
? `Distribusi ${created.aidType} ke ${recipient.name}`
|
||||||
|
: `Distribusi ${created.aidType}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return created;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
delete: publicQuery
|
delete: publicQuery
|
||||||
.input(z.object({ id: z.number() }))
|
.input(z.object({ id: z.number() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
|
const target = await findDistributionById(input.id);
|
||||||
await deleteDistribution(input.id);
|
await deleteDistribution(input.id);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: target.distributedBy ?? null,
|
||||||
|
action: "DELETE",
|
||||||
|
entityType: "distribution",
|
||||||
|
entityId: target.id,
|
||||||
|
details: `Menghapus distribusi ${target.aidType}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ import {
|
|||||||
updatePlace,
|
updatePlace,
|
||||||
deletePlace,
|
deletePlace,
|
||||||
} from "./queries/placesOfWorship";
|
} from "./queries/placesOfWorship";
|
||||||
|
import { createActivityLog } from "./queries/activityLogs";
|
||||||
|
|
||||||
|
async function logActivitySafe(payload: Parameters<typeof createActivityLog>[0]) {
|
||||||
|
try {
|
||||||
|
await createActivityLog(payload);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("[activity] failed to write place activity", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const placeOfWorshipRouter = createRouter({
|
export const placeOfWorshipRouter = createRouter({
|
||||||
list: publicQuery
|
list: publicQuery
|
||||||
@@ -43,12 +52,24 @@ export const placeOfWorshipRouter = createRouter({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return createPlace({
|
const created = await createPlace({
|
||||||
...input,
|
...input,
|
||||||
latitude: input.latitude.toString(),
|
latitude: input.latitude.toString(),
|
||||||
longitude: input.longitude.toString(),
|
longitude: input.longitude.toString(),
|
||||||
managerId: input.managerId ?? null,
|
managerId: input.managerId ?? null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (created) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: input.managerId ?? null,
|
||||||
|
action: "CREATE",
|
||||||
|
entityType: "place_of_worship",
|
||||||
|
entityId: created.id,
|
||||||
|
details: `Menambahkan ${created.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return created;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
update: publicQuery
|
update: publicQuery
|
||||||
@@ -70,17 +91,42 @@ export const placeOfWorshipRouter = createRouter({
|
|||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const { id, ...data } = input;
|
const { id, ...data } = input;
|
||||||
|
const beforeUpdate = await findPlaceById(id);
|
||||||
const updateData: Record<string, unknown> = { ...data };
|
const updateData: Record<string, unknown> = { ...data };
|
||||||
if (data.latitude !== undefined) updateData.latitude = data.latitude.toString();
|
if (data.latitude !== undefined) updateData.latitude = data.latitude.toString();
|
||||||
if (data.longitude !== undefined) updateData.longitude = data.longitude.toString();
|
if (data.longitude !== undefined) updateData.longitude = data.longitude.toString();
|
||||||
if (data.managerId === undefined) delete updateData.managerId;
|
if (data.managerId === undefined) delete updateData.managerId;
|
||||||
return updatePlace(id, updateData);
|
const updated = await updatePlace(id, updateData);
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: data.managerId ?? beforeUpdate?.managerId ?? null,
|
||||||
|
action: "UPDATE",
|
||||||
|
entityType: "place_of_worship",
|
||||||
|
entityId: updated.id,
|
||||||
|
details: `Memperbarui rumah ibadah ${updated.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
delete: publicQuery
|
delete: publicQuery
|
||||||
.input(z.object({ id: z.number() }))
|
.input(z.object({ id: z.number() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
|
const target = await findPlaceById(input.id);
|
||||||
await deletePlace(input.id);
|
await deletePlace(input.id);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: target.managerId ?? null,
|
||||||
|
action: "DELETE",
|
||||||
|
entityType: "place_of_worship",
|
||||||
|
entityId: target.id,
|
||||||
|
details: `Menghapus rumah ibadah ${target.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
+60
-3
@@ -9,6 +9,15 @@ import {
|
|||||||
verifyRecipient,
|
verifyRecipient,
|
||||||
deleteRecipient,
|
deleteRecipient,
|
||||||
} from "./queries/recipients";
|
} from "./queries/recipients";
|
||||||
|
import { createActivityLog } from "./queries/activityLogs";
|
||||||
|
|
||||||
|
async function logActivitySafe(payload: Parameters<typeof createActivityLog>[0]) {
|
||||||
|
try {
|
||||||
|
await createActivityLog(payload);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("[activity] failed to write recipient activity", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const recipientRouter = createRouter({
|
export const recipientRouter = createRouter({
|
||||||
list: publicQuery
|
list: publicQuery
|
||||||
@@ -54,7 +63,7 @@ export const recipientRouter = createRouter({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return createRecipient({
|
const created = await createRecipient({
|
||||||
...input,
|
...input,
|
||||||
latitude: input.latitude?.toString() ?? null,
|
latitude: input.latitude?.toString() ?? null,
|
||||||
longitude: input.longitude?.toString() ?? null,
|
longitude: input.longitude?.toString() ?? null,
|
||||||
@@ -66,6 +75,18 @@ export const recipientRouter = createRouter({
|
|||||||
notes: input.notes ?? null,
|
notes: input.notes ?? null,
|
||||||
status: "pending",
|
status: "pending",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (created) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: input.registeredBy ?? null,
|
||||||
|
action: "CREATE",
|
||||||
|
entityType: "recipient",
|
||||||
|
entityId: created.id,
|
||||||
|
details: `Mendaftarkan ${created.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return created;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
update: publicQuery
|
update: publicQuery
|
||||||
@@ -88,10 +109,23 @@ export const recipientRouter = createRouter({
|
|||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const { id, ...data } = input;
|
const { id, ...data } = input;
|
||||||
|
const beforeUpdate = await findRecipientById(id);
|
||||||
const updateData: Record<string, unknown> = { ...data };
|
const updateData: Record<string, unknown> = { ...data };
|
||||||
if (data.latitude !== undefined) updateData.latitude = data.latitude.toString();
|
if (data.latitude !== undefined) updateData.latitude = data.latitude.toString();
|
||||||
if (data.longitude !== undefined) updateData.longitude = data.longitude.toString();
|
if (data.longitude !== undefined) updateData.longitude = data.longitude.toString();
|
||||||
return updateRecipient(id, updateData);
|
const updated = await updateRecipient(id, updateData);
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: beforeUpdate?.registeredBy ?? null,
|
||||||
|
action: "UPDATE",
|
||||||
|
entityType: "recipient",
|
||||||
|
entityId: updated.id,
|
||||||
|
details: `Memperbarui data ${updated.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
verify: publicQuery
|
verify: publicQuery
|
||||||
@@ -104,13 +138,36 @@ export const recipientRouter = createRouter({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return verifyRecipient(input.id, input.status, input.verifiedBy, input.rejectionReason);
|
const verified = await verifyRecipient(input.id, input.status, input.verifiedBy, input.rejectionReason);
|
||||||
|
if (verified) {
|
||||||
|
const statusText = input.status === "active" ? "Diterima" : "Ditolak";
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: input.verifiedBy,
|
||||||
|
action: "VERIFY",
|
||||||
|
entityType: "recipient",
|
||||||
|
entityId: verified.id,
|
||||||
|
details: `Memverifikasi ${verified.name} - ${statusText}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return verified;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
delete: publicQuery
|
delete: publicQuery
|
||||||
.input(z.object({ id: z.number() }))
|
.input(z.object({ id: z.number() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
|
const target = await findRecipientById(input.id);
|
||||||
await deleteRecipient(input.id);
|
await deleteRecipient(input.id);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
await logActivitySafe({
|
||||||
|
userId: target.registeredBy ?? null,
|
||||||
|
action: "DELETE",
|
||||||
|
entityType: "recipient",
|
||||||
|
entityId: target.id,
|
||||||
|
details: `Menghapus penerima ${target.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user