Files
setrip/server/repositories/organizer.repo.ts
T

115 lines
3.2 KiB
TypeScript

import { prisma } from "@/lib/prisma";
import { Prisma } from "@/app/generated/prisma/client";
export const organizerRepo = {
async findByUserId(userId: string) {
return prisma.organizerVerification.findUnique({ where: { userId } });
},
async findById(id: string) {
return prisma.organizerVerification.findUnique({ where: { id } });
},
async findByNikHash(nikHash: string) {
return prisma.organizerVerification.findUnique({ where: { nikHash } });
},
async upsertForUser(
userId: string,
data: Omit<Prisma.OrganizerVerificationUncheckedCreateInput, "id" | "userId" | "createdAt" | "updatedAt">
) {
return prisma.organizerVerification.upsert({
where: { userId },
create: { userId, ...data },
update: data,
});
},
async listByStatus(
status?: "PENDING" | "APPROVED" | "REJECTED",
filters?: {
dateFrom?: Date;
dateTo?: Date;
reviewerEmail?: string;
}
) {
const where: Prisma.OrganizerVerificationWhereInput = {};
if (status) where.status = status;
if (filters?.dateFrom || filters?.dateTo) {
where.createdAt = {
...(filters.dateFrom && { gte: filters.dateFrom }),
...(filters.dateTo && { lte: filters.dateTo }),
};
}
if (filters?.reviewerEmail) {
where.reviewedBy = { email: filters.reviewerEmail };
}
return prisma.organizerVerification.findMany({
where,
orderBy: { createdAt: "desc" },
include: {
user: { select: { id: true, name: true, email: true } },
reviewedBy: { select: { id: true, name: true, email: true } },
},
});
},
async countByStatus(status: "PENDING" | "APPROVED" | "REJECTED") {
return prisma.organizerVerification.count({ where: { status } });
},
/** Verifikasi terbaru (default PENDING) untuk preview di dashboard admin. */
async listRecent(status: "PENDING" | "APPROVED" | "REJECTED", limit = 3) {
return prisma.organizerVerification.findMany({
where: { status },
orderBy: { createdAt: "desc" },
take: limit,
select: {
id: true,
fullName: true,
createdAt: true,
user: { select: { id: true, name: true, email: true } },
},
});
},
/**
* Reopen pengajuan REJECTED ke PENDING. Simpan rejection reason lama
* sebagai catatan history (di-overwrite kalau di-reject lagi nanti).
*/
async reopen(id: string, reopenNote: string) {
return prisma.organizerVerification.update({
where: { id },
data: {
status: "PENDING",
reviewedById: null,
reviewedAt: null,
verifiedAt: null,
// Pertahankan rejectionReason lama di field, append note reopen.
rejectionReason: `[Dibuka kembali admin: ${reopenNote}]`,
},
});
},
async updateReview(
id: string,
data: {
status: "APPROVED" | "REJECTED";
rejectionReason?: string | null;
reviewedById: string;
}
) {
const now = new Date();
return prisma.organizerVerification.update({
where: { id },
data: {
status: data.status,
rejectionReason: data.rejectionReason ?? null,
reviewedById: data.reviewedById,
reviewedAt: now,
verifiedAt: data.status === "APPROVED" ? now : null,
},
});
},
};