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>;
|