fix(companies): align optional numeric fields with API validation
continuous-integration/drone/push Build is passing

Make employee_count, annual_revenue, and founded_year truly optional in
the create company form and payload. Add field validation docs and
Cypress e2e coverage for dashboard and notifications.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
AmirReza Jamali
2026-06-16 11:47:45 +03:30
parent 2fec8bb84c
commit 169708e49d
8 changed files with 678 additions and 18 deletions
@@ -25,6 +25,35 @@ const FieldError = ({ message }: { message?: string }) =>
<p className="mt-1.5 text-sm font-medium text-error">{message}</p>
) : null;
const optionalNumber = (value: unknown) => {
if (value === "" || value === null || value === undefined) return undefined;
return Number(value);
};
const optionalNumberRange = ({
min,
max,
integer = false,
}: {
min: number;
max: number;
integer?: boolean;
}) => {
return (value: unknown) => {
const numberValue = optionalNumber(value);
if (numberValue === undefined) return true;
if (!Number.isFinite(numberValue)) return "Enter a valid number";
if (integer && !Number.isInteger(numberValue)) {
return "This field must be a whole number";
}
if (numberValue < min) return FormErrorMessages.min(min);
if (numberValue > max) return FormErrorMessages.max(max);
return true;
};
};
const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
const {
errors,
@@ -223,8 +252,12 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
>
<InputGroup
{...register("employee_count", {
min: { value: 1, message: FormErrorMessages.min(1) },
max: { value: 100000, message: FormErrorMessages.max(100000) },
setValueAs: optionalNumber,
validate: optionalNumberRange({
min: 1,
max: 100000,
integer: true,
}),
})}
errors={errors}
label="Employee count"
@@ -233,11 +266,11 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
/>
<InputGroup
{...register("annual_revenue", {
min: { value: 0, message: FormErrorMessages.min(0) },
max: {
value: 999999999999,
message: FormErrorMessages.max(999999999999),
},
setValueAs: optionalNumber,
validate: optionalNumberRange({
min: 0,
max: 999999999999,
}),
})}
errors={errors}
label="Annual revenue"
@@ -246,8 +279,12 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
/>
<InputGroup
{...register("founded_year", {
min: { value: 1800, message: FormErrorMessages.min(1800) },
max: { value: 2100, message: FormErrorMessages.max(2100) },
setValueAs: optionalNumber,
validate: optionalNumberRange({
min: 1800,
max: 2100,
integer: true,
}),
})}
errors={errors}
label="Founded year"
@@ -46,12 +46,19 @@ const useCreateCompanyPresenter = ({ defaultValues, editMode, id }: IProps) => {
const { mutate: updateCompany, isPending: isUpdating } = useUpdateCompany(
id as string,
);
const optionalNumber = (value: unknown) => {
if (value === "" || value === null || value === undefined) return undefined;
return Number(value);
};
const onSubmit: SubmitHandler<ICreateCompanyCredentials> = (data) => {
const formattedData = {
...data,
founded_year: data.founded_year ? +data.founded_year : 0,
employee_count: data.employee_count ? +data.employee_count : 0,
annual_revenue: data.annual_revenue ? +data.annual_revenue : 0,
founded_year: optionalNumber(data.founded_year),
employee_count: optionalNumber(data.employee_count),
annual_revenue: optionalNumber(data.annual_revenue),
document_file_ids: data.document_file_ids ?? [],
tags: {
keywords: data?.tags?.keywords?.length ? data?.tags?.keywords : [],
+3 -3
View File
@@ -35,9 +35,9 @@ export interface ICreateCompanyCredentials {
website: string;
type: string;
description: string;
founded_year: number;
employee_count: number;
annual_revenue: number;
founded_year?: number | string;
employee_count?: number | string;
annual_revenue?: number | string;
currency: string;
industry: string;
language: string;
+3 -3
View File
@@ -35,9 +35,9 @@ export interface ICreateCompanyCredentials {
website: string;
type: string;
description: string;
founded_year: number;
employee_count: number;
annual_revenue: number;
founded_year?: number | string;
employee_count?: number | string;
annual_revenue?: number | string;
currency: string;
industry: string;
language: string;