Einbau Validation finished

This commit is contained in:
2024-08-03 12:16:04 +02:00
parent f58448679d
commit 4c1b1fbc87
19 changed files with 421 additions and 338 deletions

View File

@@ -1,28 +1,5 @@
// export interface User {
// id?: string;
// firstname: string;
// lastname: string;
// email: string;
// phoneNumber?: string;
// description?: string;
// companyName?: string;
// companyOverview?: string;
// companyWebsite?: string;
// companyLocation?: string;
// offeredServices?: string;
// areasServed?: AreasServed[];
// hasProfile?: boolean;
// hasCompanyLogo?: boolean;
// licensedIn?: LicensedIn[];
// gender?: 'male' | 'female';
// customerType?: 'buyer' | 'professional';
// customerSubType?: 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
// created?: Date;
// updated?: Date;
import { z } from 'zod';
// }
export interface UserData {
id?: string;
firstname: string;
@@ -49,45 +26,80 @@ export type Gender = 'male' | 'female';
export type CustomerType = 'buyer' | 'professional';
export type CustomerSubType = 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
export type ListingsCategory = 'commercialProperty' | 'business';
// export interface User {
// id: string; // UUID as a string
// firstname: string;
// lastname: string;
// email: string;
// phoneNumber?: string;
// description?: string;
// companyName?: string;
// companyOverview?: string;
// companyWebsite?: string;
// companyLocation?: string;
// offeredServices?: string;
// areasServed?: AreasServed[];
// hasProfile?: boolean;
// hasCompanyLogo?: boolean;
// licensedIn?: LicensedIn[];
// gender?: Gender;
// customerType?: CustomerType;
// customerSubType?: CustomerSubType;
// created?: Date;
// updated?: Date;
// latitude?: number;
// longitude?: number;
// }
// export interface AreasServed {
// county: string;
// state: string;
// }
// export interface LicensedIn {
// registerNo: string;
// state: string;
// }
// --------------------------------
//
// --------------------------------
export const GenderEnum = z.enum(['male', 'female']);
export const CustomerTypeEnum = z.enum(['buyer', 'professional']);
export const CustomerSubTypeEnum = z.enum(['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
export const ListingsCategoryEnum = z.enum(['commercialProperty', 'business']);
const PropertyTypeEnum = z.enum(['retail', 'land', 'industrial', 'office', 'mixedUse', 'multifamily', 'uncategorized']);
const TypeEnum = z.enum([
'automotive',
'industrialServices',
'foodAndRestaurant',
'realEstate',
'retail',
'oilfield',
'service',
'advertising',
'agriculture',
'franchise',
'professional',
'manufacturing',
'uncategorized',
]);
const USStates = z.enum([
'AL',
'AK',
'AZ',
'AR',
'CA',
'CO',
'CT',
'DE',
'FL',
'GA',
'HI',
'ID',
'IL',
'IN',
'IA',
'KS',
'KY',
'LA',
'ME',
'MD',
'MA',
'MI',
'MN',
'MS',
'MO',
'MT',
'NE',
'NV',
'NH',
'NJ',
'NM',
'NY',
'NC',
'ND',
'OH',
'OK',
'OR',
'PA',
'RI',
'SC',
'SD',
'TN',
'TX',
'UT',
'VT',
'VA',
'WA',
'WV',
'WI',
'WY',
]);
export const AreasServedSchema = z.object({
county: z.string().nonempty('County is required'),
state: z.string().nonempty('State is required'),
@@ -98,56 +110,6 @@ export const LicensedInSchema = z.object({
state: z.string().nonempty('State is required'),
});
// export const UserSchema = z
// .object({
// id: z.string().uuid('Invalid ID format. Must be a valid UUID').optional(),
// firstname: z.string().min(2, 'First name must be at least 2 characters long'),
// lastname: z.string().min(2, 'Last name must be at least 2 characters long'),
// email: z.string().email('Invalid email address'),
// phoneNumber: z.string().optional().nullable(),
// description: z.string().min(10, 'Description must be at least 10 characters long').optional().nullable(),
// companyName: z.string().optional().nullable(),
// companyOverview: z.string().min(10, 'Company overview must be at least 10 characters long').optional().nullable(),
// companyWebsite: z.string().url('Invalid company website URL').optional().nullable(),
// companyLocation: z.string().optional().nullable(), // Additional validation for US locations could be implemented here
// offeredServices: z.string().min(10, 'Offered services must be at least 10 characters long').optional().nullable(),
// areasServed: z.array(AreasServedSchema).optional().nullable(),
// hasProfile: z.boolean().optional().nullable(),
// hasCompanyLogo: z.boolean().optional().nullable(),
// licensedIn: z.array(LicensedInSchema).optional().nullable(),
// gender: GenderEnum.optional().nullable(),
// customerType: CustomerTypeEnum.optional().nullable(),
// customerSubType: CustomerSubTypeEnum.optional().nullable(),
// created: z.date().optional().nullable(),
// updated: z.date().optional().nullable(),
// latitude: z.number().optional().nullable(),
// longitude: z.number().optional().nullable(),
// })
// .refine(
// data => {
// if (data.customerType === 'professional') {
// return !!data.customerSubType && !!data.phoneNumber && !!data.companyOverview && !!data.description && !!data.offeredServices && !!data.companyLocation && data.areasServed && data.areasServed.length > 0;
// }
// return true;
// },
// {
// message: 'For professional customers, additional fields are required: customer subtype, phone number, company overview, description, offered services, company location, and at least one area served',
// path: ['customerType'],
// },
// )
// .refine(
// data => {
// if (data.customerType === 'professional') {
// return /\(\d{3}\) \d{3}-\d{4}$/.test(data.phoneNumber || '');
// }
// return true;
// },
// {
// message: 'Phone number must be in US format: +1 (XXX) XXX-XXXX',
// path: ['phoneNumber'],
// },
// );
const phoneRegex = /^\+1 \(\d{3}\) \d{3}-\d{4}$/;
export const UserSchema = z
@@ -238,64 +200,90 @@ export const UserSchema = z
export type AreasServed = z.infer<typeof AreasServedSchema>;
export type LicensedIn = z.infer<typeof LicensedInSchema>;
export type User = z.infer<typeof UserSchema>;
export interface BusinessListing {
id: string; // UUID as a string
email: string; // References users.email
type?: string;
title?: string;
description?: string;
city?: string;
state?: string; // 2-character state code
zipCode?: number;
county?: string;
price?: number; // double precision
favoritesForUser?: string[]; // Array of strings
draft?: boolean;
listingsCategory?: ListingsCategory;
realEstateIncluded?: boolean;
leasedLocation?: boolean;
franchiseResale?: boolean;
salesRevenue?: number; // double precision
cashFlow?: number; // double precision
supportAndTraining?: string;
employees?: number;
established?: number;
internalListingNumber?: number;
reasonForSale?: string;
brokerLicencing?: string;
internals?: string;
imageName?: string;
created?: Date;
updated?: Date;
visits?: number;
lastVisit?: Date;
latitude?: number; // double precision
longitude?: number; // double precision
}
export interface CommercialPropertyListing {
id: string; // UUID as a string
serialId: number; // Serial ID
email: string; // References users.email
type?: string;
title?: string;
description?: string;
city?: string;
state?: string; // 2-character state code
price?: number; // double precision
favoritesForUser?: string[]; // Array of strings
listingsCategory?: ListingsCategory;
hideImage?: boolean;
draft?: boolean;
zipCode?: number;
county?: string;
imageOrder?: string[]; // Array of strings
imagePath?: string;
created?: Date;
updated?: Date;
visits?: number;
lastVisit?: Date;
latitude?: number; // double precision
longitude?: number; // double precision
// embedding?: number[]; // Uncomment if needed for vector embedding
}
export const BusinessListingSchema = z.object({
id: z.string().uuid().optional(),
email: z.string().email(),
type: z.string().refine(val => TypeEnum.safeParse(val).success, {
message: 'Invalid type. Must be one of: ' + TypeEnum.options.join(', '),
}),
title: z.string().min(10),
description: z.string().min(10),
city: z.string(),
state: z.string().refine(val => USStates.safeParse(val).success, {
message: 'Invalid state. Must be a valid 2-letter US state code.',
}),
zipCode: z.number().int().positive().optional().nullable(),
county: z.string().optional().nullable(),
price: z.number().positive().max(100000000),
favoritesForUser: z.array(z.string()),
draft: z.boolean(),
listingsCategory: ListingsCategoryEnum,
realEstateIncluded: z.boolean().optional().nullable(),
leasedLocation: z.boolean().optional().nullable(),
franchiseResale: z.boolean().optional().nullable(),
salesRevenue: z.number().positive().max(100000000),
cashFlow: z.number().positive().max(100000000),
supportAndTraining: z.string().min(5),
employees: z.number().int().positive().max(100000).optional().nullable(),
established: z.number().int().min(1800).max(2030).optional().nullable(),
internalListingNumber: z.number().int().positive().optional().nullable(),
reasonForSale: z.string().min(5).optional().nullable(),
brokerLicencing: z.string().min(5).optional().nullable(),
internals: z.string().min(5).optional().nullable(),
imageName: z.string().optional().nullable(),
created: z.date(),
updated: z.date(),
visits: z.number().int().positive().optional().nullable(),
lastVisit: z.date().optional().nullable(),
latitude: z.number().optional().nullable(),
longitude: z.number().optional().nullable(),
});
export type BusinessListing = z.infer<typeof BusinessListingSchema>;
export const CommercialPropertyListingSchema = z
.object({
id: z.string().uuid().optional(),
serialId: z.number().int().positive().optional(),
email: z.string().email(),
//type: PropertyTypeEnum.optional(),
type: z.string().refine(val => PropertyTypeEnum.safeParse(val).success, {
message: 'Invalid type. Must be one of: ' + PropertyTypeEnum.options.join(', '),
}),
title: z.string().min(10),
description: z.string().min(10),
city: z.string(), // You might want to add a custom validation for valid US cities
state: z.string().refine(val => USStates.safeParse(val).success, {
message: 'Invalid state. Must be a valid 2-letter US state code.',
}), // You might want to add a custom validation for valid US states
price: z.number().positive().max(100000000),
favoritesForUser: z.array(z.string()),
listingsCategory: ListingsCategoryEnum,
draft: z.boolean(),
zipCode: z.number().int().positive().nullable().optional(), // You might want to add a custom validation for valid US zip codes
county: z.string().nullable().optional(), // You might want to add a custom validation for valid US counties
imageOrder: z.array(z.string()),
imagePath: z.string().nullable().optional(),
created: z.date(),
updated: z.date(),
visits: z.number().int().positive().nullable().optional(),
lastVisit: z.date().nullable().optional(),
latitude: z.number().nullable().optional(),
longitude: z.number().nullable().optional(),
})
.strict();
export type CommercialPropertyListing = z.infer<typeof CommercialPropertyListingSchema>;
export const SenderSchema = z.object({
name: z.string().min(6, { message: 'Name must be at least 6 characters long' }),
email: z.string().email({ message: 'Invalid email address' }),
phoneNumber: z.string().regex(/^(\+1|1)?[-.\s]?\(?[2-9]\d{2}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/, {
message: 'Invalid US phone number format',
}),
state: z.string().refine(val => USStates.safeParse(val).success, {
message: 'Invalid state. Must be a valid 2-letter US state code.',
}),
comments: z.string().min(10, { message: 'Comments must be at least 10 characters long' }),
});
export type Sender = z.infer<typeof SenderSchema>;