Files
setrip/features/refund/schemas.ts
T
2026-05-11 13:04:20 +07:00

58 lines
1.6 KiB
TypeScript

import { z } from "zod/v4";
import { LIMITS } from "@/lib/limits";
const reasonValues = [
"USER_CANCELLATION",
"ORGANIZER_CANCELLED",
"TRIP_ISSUE",
"ADMIN_ADJUSTMENT",
"DISPUTE_RESOLVED",
"OTHER",
] as const;
const reporterValues = ["PARTICIPANT", "ORGANIZER"] as const;
const refundNote = z
.string()
.trim()
.min(3, "Isi catatan minimal 3 karakter")
.max(
LIMITS.MAX_REFUND_NOTE_LENGTH,
`Catatan maksimal ${LIMITS.MAX_REFUND_NOTE_LENGTH} karakter`
);
export const createRefundSchema = z.object({
bookingId: z.string().trim().min(1, "Booking ID wajib"),
reason: z.enum(reasonValues, { error: "Alasan tidak valid" }),
reportedBy: z.enum(reporterValues, { error: "Pelapor tidak valid" }),
reportNote: refundNote,
/** Kosong = full remaining. Angka positif (IDR) untuk partial. */
amount: z
.string()
.trim()
.optional()
.transform((v) => (v && v.length > 0 ? Number(v.replace(/[^\d]/g, "")) : undefined))
.refine(
(n) => n === undefined || (Number.isInteger(n) && n > 0),
"Nominal harus bilangan bulat positif"
),
});
export const refundDecisionSchema = z.object({
refundId: z.string().trim().min(1, "Refund ID wajib"),
decision: z.enum(["APPROVE", "REJECT", "SUCCEEDED", "FAILED"], {
error: "Keputusan tidak valid",
}),
adminNote: z
.string()
.trim()
.max(
LIMITS.MAX_REFUND_NOTE_LENGTH,
`Catatan maksimal ${LIMITS.MAX_REFUND_NOTE_LENGTH} karakter`
)
.optional(),
});
export type CreateRefundInput = z.infer<typeof createRefundSchema>;
export type RefundDecisionInput = z.infer<typeof refundDecisionSchema>;