admin roadmap filter & search, user management, reopen rejected, system health

This commit is contained in:
2026-05-18 19:45:14 +07:00
parent c52b12daad
commit 6e02f2f0d7
36 changed files with 2013 additions and 339 deletions
+32
View File
@@ -78,6 +78,38 @@ export const organizerService = {
return v?.status === "APPROVED";
},
/**
* Buka kembali verifikasi yang REJECTED ke PENDING. Dipakai admin saat
* organizer kirim foto/data baru via email/WA dan ingin di-review ulang
* tanpa drop & recreate row.
*
* - `rejectionReason` lama disimpan di field — kalau di-reject lagi nanti,
* field-nya di-overwrite (audit trail via auditLog Phase 4 di roadmap).
* - Reset `reviewedById`, `reviewedAt` supaya muncul lagi di tab PENDING.
*/
async reopenVerification(input: {
verificationId: string;
adminId: string;
note: string;
}) {
const verification = await organizerRepo.findById(input.verificationId);
if (!verification) {
throw new Error("Pengajuan tidak ditemukan");
}
if (verification.status !== "REJECTED") {
throw new Error("Hanya pengajuan REJECTED yang bisa dibuka kembali");
}
const trimmedNote = input.note.trim();
if (trimmedNote.length < 10) {
throw new Error("Catatan reopen wajib min 10 karakter untuk audit");
}
if (trimmedNote.length > 500) {
throw new Error("Catatan reopen maksimal 500 karakter");
}
return organizerRepo.reopen(input.verificationId, trimmedNote);
},
/** Reveal NIK plaintext. Caller must enforce authorization (owner or admin). */
decryptNik(nikEncrypted: string): string {
return decryptString(nikEncrypted);