refactor: enforce frontend view model boundaries
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s

This commit is contained in:
2026-09-28 18:48:23 +03:00
parent 5b69003516
commit ca0ad4f824
287 changed files with 8558 additions and 4538 deletions
@@ -0,0 +1,31 @@
import { z } from "zod";
import { validationMessage } from "@/shared/i18n";
import { moscowDate, parseDraftDate } from "./period";
const draftDate = z
.string()
.refine(value => parseDraftDate(value) !== null, {
error: validationMessage("income.validation.date"),
})
.refine(
(value) => {
const date = parseDraftDate(value);
return !date || date <= moscowDate(new Date());
},
{ error: validationMessage("income.validation.future") },
);
const incomeFormSchema = z.object({ from: draftDate, to: draftDate }).refine(
({ from, to }) => {
const start = parseDraftDate(from);
const end = parseDraftDate(to);
return !start || !end || start <= end;
},
{ path: ["to"], ...validationMessage("income.validation.period")({}) },
);
export { incomeFormSchema };
+13 -3
View File
@@ -7,12 +7,14 @@ const datePattern = /^\d{4}-\d{2}-\d{2}$/;
function formatDraftDate(value: string): string {
const [year, month, day] = value.split("-", DATE_PART_COUNT);
return `${day}.${month}.${year}`;
}
function isDate(value: string): boolean {
if (!datePattern.test(value)) return false;
const parsed = new Date(`${value}T00:00:00Z`);
return (
Number.isFinite(parsed.valueOf())
&& parsed.toISOString().slice(0, ISO_DATE_LENGTH) === value
@@ -26,19 +28,27 @@ function moscowDate(value: Date): string {
timeZone: "Europe/Moscow",
year: "numeric",
}).formatToParts(value);
const part = (type: string) =>
parts.find(item => item.type === type)?.value;
return `${part("year")}-${part("month")}-${part("day")}`;
}
function parseDraftDate(value: string): null | string {
if (!/^\d{2}\.\d{2}\.\d{4}$/.test(value)) return /* eslint-disable-line unicorn/no-null -- Mantine date fields use null for an incomplete or invalid date. */ null;
if (!/^\d{2}\.\d{2}\.\d{4}$/.test(value))
// eslint-disable-next-line unicorn/no-null -- Mantine date fields use null for an incomplete or invalid date.
return null;
const [day, month, year] = value.split(".", DATE_PART_COUNT);
const date = `${year}-${month}-${day}`;
return isDate(date) ? date : /* eslint-disable-line unicorn/no-null -- Mantine date fields use null for an incomplete or invalid date. */ null;
return isDate(date)
? date
: null; // eslint-disable-line unicorn/no-null -- Mantine date fields use null for an incomplete or invalid date.
}
export { formatDraftDate,
export {
formatDraftDate,
type IncomePeriod as IncomeForm,
type IncomePeriod,
isDate,