All files / routes/pro/onboarding schemas.ts

100% Statements 4/4
100% Branches 2/2
100% Functions 3/3
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                          2x                   26x   26x       26x                                                                        
// Onboarding Step Validation Schemas
//
// Onboarding is one screen. The step 2-7 schemas that used to live here were
// deleted with the step 2-7 handlers in `steps.routes.ts` — nothing ever posted
// those steps. The fields they covered are now only reachable through the
// profile edit paths, which carry their own validation
// (`lib/validators/pro-profile.schema.ts` for the columns,
// `services/pro.validators.ts` for the `profileFields` JSON).
 
import { indianMobileSchema } from "@interioring/utils/validation/phone";
import { z } from "zod";
 
// Step 1: Simplified Business Info (name + slug + city + business type + whatsapp + logo)
export const step1Schema = z.object({
	businessName: z.string().min(2).max(100),
	slug: z
		.string()
		.min(3)
		.max(50)
		.regex(
			/^[a-z0-9-]+$/,
			"Slug must be lowercase alphanumeric with hyphens only",
		)
		.refine((val) => /^[a-z]/.test(val), "Must start with a letter")
		.refine(
			(val) => !val.startsWith("-") && !val.endsWith("-"),
			"Slug cannot start or end with a hyphen",
		)
		.refine(
			(val) => !val.includes("--"),
			"Slug cannot contain consecutive hyphens",
		),
	cityId: z.string(),
	businessTypeId: z.string().min(1, "Select a business type"),
	whatsapp: indianMobileSchema,
	logoUrl: z.string().optional().or(z.literal("")),
});
 
// Typed profileFields JSON column — covers all fields stored in pro.profileFields
export interface ProfileFields {
	factoryMade?: boolean;
	factoryType?: "own" | "partner";
	siteExecution?: boolean;
	labourOnly?: boolean;
	fullSiteExecution?: boolean;
	materialApproach?: "we_provide" | "customer_provides" | "combination";
	billingModel?: "sqft_rates" | "fixed_quote" | "combination";
	deliveryDaysMin?: number;
	deliveryDaysMax?: number | null;
	pricingModel?:
		| "per_sqft"
		| "fixed_quote"
		| "cost_plus"
		| "daily_rate"
		| "package_based";
	minProjectValue?: number;
	consultationFee?: "free" | "paid" | "adjustable";
	warrantyYears?: number;
	hasAfterSalesService?: boolean;
	hasShowroom?: boolean;
	provides3DDesign?: boolean;
}
 
// Type exports
export type Step1Data = z.infer<typeof step1Schema>;