Files
iistwin/server/utils/validate-immutable-fields.ts
Ильяс Султанов 1f5ecb6da4 fix(number-fields): избегаем потери точности длинных чисел
- number-поля теперь рендерятся как text + inputMode=numeric,
  чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage

Closes: искажение расчётного счёта и других длинных числовых полей
2026-07-07 21:03:40 +03:00

73 lines
2.1 KiB
TypeScript

/**
* Проверка условной неизменности полей формы.
*/
import { isFieldImmutable } from "@shared/field-conditions";
import { buildFieldConditionContext } from "./field-condition-context";
export interface ValidateImmutableFieldsOptions {
task: { currentStatusId?: number | null; formId?: number; [key: string]: any };
formFields: Array<{
id: number;
code: string;
name: string;
type?: string;
options?: unknown;
immutableRules?: any;
autoProlongationLabel?: string | null;
}>;
changedFieldIds: number[];
existingFieldValues?: Array<{ fieldId: number; value: unknown }>;
organizationId: number;
storage: any;
isCreation?: boolean;
statuses?: Array<{ id: number; position: number; isFinal?: boolean | null }>;
users?: Array<{ id: number; firstName?: string | null; middleName?: string | null; lastName?: string | null; email?: string }>;
roles?: Array<{ id: number; name?: string }>;
}
export async function validateImmutableFields(
options: ValidateImmutableFieldsOptions
): Promise<string[]> {
const {
task,
formFields,
changedFieldIds,
existingFieldValues,
organizationId,
storage,
statuses: providedStatuses,
users: providedUsers,
roles: providedRoles,
} = options;
const fieldsWithRules = formFields.filter(
(f) => f.immutableRules && f.immutableRules.enabled && changedFieldIds.includes(f.id)
);
if (fieldsWithRules.length === 0) return [];
const ctxResult = await buildFieldConditionContext({
task,
formFields,
organizationId,
storage,
isCreation: options.isCreation,
statuses: providedStatuses,
existingFieldValues,
users: providedUsers,
roles: providedRoles,
});
const { fields, fieldValues, ...context } = ctxResult;
const errors: string[] = [];
for (const field of fieldsWithRules) {
const immutable = isFieldImmutable(field as any, task, fieldValues, fields, context);
if (immutable) {
errors.push(`Поле «${field.name}» не может быть изменено в текущем состоянии`);
}
}
return errors;
}