Files
marketplace/server/src/validators/rental.ts
delta-lynx-89e8 dbbbbd26f4 Add rental system: listings, bookings, payments, payouts, reviews
Full rental marketplace with 6 categories (apartment, house, car, motorcycle, bicycle, ebike).
Booking workflow: create → confirm → pay → active → complete → payout.
Landlord dashboard, admin moderation, availability calendar, Stripe Connect payouts.
14 QA bugs found and fixed including validator schemas, API response types, HTTP methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:33:29 -08:00

40 lines
1.9 KiB
TypeScript

import { z } from 'zod';
export const createRentalSchema = z.object({
title: z.string().min(3).max(100),
description: z.string().min(10).max(5000),
category: z.enum(['APARTMENT', 'HOUSE', 'CAR', 'MOTORCYCLE', 'BICYCLE', 'EBIKE']),
location: z.string().min(1).max(200),
dailyPrice: z.number().positive().optional(),
monthlyPrice: z.number().positive().optional(),
depositAmount: z.number().min(0).optional(),
details: z.record(z.any()).optional(),
amenities: z.array(z.string()).optional(),
rules: z.array(z.string()).optional(),
cancellationPolicy: z.enum(['FLEXIBLE', 'MODERATE', 'STRICT']).optional(),
minDays: z.number().int().positive().optional(),
maxDays: z.number().int().positive().optional(),
minMonths: z.number().int().positive().optional(),
maxMonths: z.number().int().positive().optional(),
}).refine(data => data.dailyPrice || data.monthlyPrice, {
message: 'At least one price (daily or monthly) is required',
});
export const updateRentalSchema = z.object({
title: z.string().min(3).max(100).optional(),
description: z.string().min(10).max(5000).optional(),
category: z.enum(['APARTMENT', 'HOUSE', 'CAR', 'MOTORCYCLE', 'BICYCLE', 'EBIKE']).optional(),
location: z.string().min(1).max(200).optional(),
dailyPrice: z.number().positive().nullable().optional(),
monthlyPrice: z.number().positive().nullable().optional(),
depositAmount: z.number().min(0).nullable().optional(),
details: z.record(z.any()).optional(),
amenities: z.array(z.string()).optional(),
rules: z.array(z.string()).optional(),
cancellationPolicy: z.enum(['FLEXIBLE', 'MODERATE', 'STRICT']).optional(),
minDays: z.number().int().positive().nullable().optional(),
maxDays: z.number().int().positive().nullable().optional(),
minMonths: z.number().int().positive().nullable().optional(),
maxMonths: z.number().int().positive().nullable().optional(),
});