72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
import { z } from "zod/v4";
|
|
import { LIMITS } from "@/lib/limits";
|
|
|
|
const ymdRegex = /^\d{4}-\d{2}-\d{2}$/;
|
|
|
|
export const submitVerificationSchema = z.object({
|
|
fullName: z
|
|
.string()
|
|
.trim()
|
|
.min(2, "Nama lengkap minimal 2 karakter")
|
|
.max(LIMITS.MAX_NAME_LENGTH, `Nama maksimal ${LIMITS.MAX_NAME_LENGTH} karakter`),
|
|
nik: z
|
|
.string()
|
|
.trim()
|
|
.regex(/^\d{16}$/, "NIK harus 16 digit angka"),
|
|
birthDate: z
|
|
.string()
|
|
.trim()
|
|
.regex(ymdRegex, "Format tanggal lahir harus YYYY-MM-DD"),
|
|
address: z
|
|
.string()
|
|
.trim()
|
|
.min(5, "Alamat minimal 5 karakter")
|
|
.max(LIMITS.MAX_ADDRESS_LENGTH, `Alamat maksimal ${LIMITS.MAX_ADDRESS_LENGTH} karakter`),
|
|
ktpImageUrl: z
|
|
.string()
|
|
.trim()
|
|
.min(1, "Foto KTP wajib diisi")
|
|
.max(LIMITS.MAX_URL_LENGTH, "URL foto KTP terlalu panjang")
|
|
.pipe(z.url("URL foto KTP tidak valid")),
|
|
selfieUrl: z
|
|
.string()
|
|
.trim()
|
|
.min(1, "Foto selfie dengan KTP wajib diisi")
|
|
.max(LIMITS.MAX_URL_LENGTH, "URL foto selfie terlalu panjang")
|
|
.pipe(z.url("URL foto selfie tidak valid")),
|
|
bankName: z
|
|
.string()
|
|
.trim()
|
|
.min(2, "Nama bank minimal 2 karakter")
|
|
.max(LIMITS.MAX_BANK_NAME_LENGTH, `Nama bank maksimal ${LIMITS.MAX_BANK_NAME_LENGTH} karakter`),
|
|
bankAccountNumber: z
|
|
.string()
|
|
.trim()
|
|
.regex(/^[0-9-]+$/, "Nomor rekening hanya boleh angka")
|
|
.min(5, "Nomor rekening minimal 5 digit")
|
|
.max(LIMITS.MAX_BANK_ACCOUNT_NUMBER_LENGTH, "Nomor rekening terlalu panjang"),
|
|
bankAccountName: z
|
|
.string()
|
|
.trim()
|
|
.min(2, "Nama pemilik rekening minimal 2 karakter")
|
|
.max(LIMITS.MAX_NAME_LENGTH, `Nama pemilik rekening maksimal ${LIMITS.MAX_NAME_LENGTH} karakter`),
|
|
});
|
|
|
|
export const reviewVerificationSchema = z.object({
|
|
verificationId: z.string().min(1, "Verification ID wajib"),
|
|
decision: z.enum(["APPROVED", "REJECTED"], {
|
|
error: "Keputusan tidak valid",
|
|
}),
|
|
rejectionReason: z
|
|
.string()
|
|
.trim()
|
|
.max(LIMITS.MAX_REJECTION_REASON_LENGTH, "Alasan penolakan terlalu panjang")
|
|
.optional(),
|
|
}).refine(
|
|
(data) => data.decision !== "REJECTED" || (data.rejectionReason && data.rejectionReason.length > 0),
|
|
{ message: "Alasan penolakan wajib diisi jika menolak", path: ["rejectionReason"] }
|
|
);
|
|
|
|
export type SubmitVerificationInput = z.infer<typeof submitVerificationSchema>;
|
|
export type ReviewVerificationInput = z.infer<typeof reviewVerificationSchema>;
|