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>
40 lines
1.9 KiB
TypeScript
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(),
|
|
});
|