Presentation-компоненты содержали SVG, обработчики в JSX, локальные схемы Zod и сложные условные выражения. PR переносит эти обязанности к явным владельцам и закрепляет требования к читаемости без изменения API-контрактов.
Изменения
SVG и анимации перенесены из application src в @wealthledger/icons. Каждая иконка — цельный декларативный SVG; геометрия не собирается в runtime. Реестр использует английские ключи, названия категорий API остаются данными с нормализацией и fallback.
Обработчики и состояние форм вынесены в ViewModel, схемы — в отдельные *.schema.ts. VM полей карты композирует hooks даты и платёжной системы. Сохранены validation, idempotency и обработка конфликтов версий.
Условные props получили именованные значения, крупные тернарники заменены явными ветками, добавлены интервалы между JSX siblings и смысловыми блоками. Короткий JSX не обрамляется лишними скобками.
ESLint контролирует callbacks/тернарники в props, helpers внутри компонентов, размещение SVG и схем, optional trailing parameters, сложные union-типы и длину строк 80 символов. Строки, template/regex literals, URL и комментарии исключены из max-len; generated artifacts исключены из форматирования.
unicorn/no-null отключён для сохранения контрактов API, React и Mantine; массовые локальные suppressions удалены. Известные названия банков вынесены в BankName.
Семантические требования к именам, владельцам логики, цельным SVG и композиции VM закреплены в guardrails. Storybook допускает UI-only/form-context VM, сохраняя запрет транзитивного доступа к application API/auth/query providers.
Новых зависимостей нет. Значительная часть diff — форматирование существующих исходников, тестов и stories под новые правила.
Проверки
npm ci выполнен; полный npm run verify после доработок — успешно: 58 test files, 379 tests, 8 ESLint regression checks; TypeScript, OpenAPI, coverage thresholds, Knip, оба dependency graph и обе сборки пройдены.
Chromium на собранном Storybook после доработок: 26 иконок операций, hover-анимации, reduced motion, клавиатурный выбор платёжной системы и viewport 375 px; без runtime exceptions.
Первоначальный Chromium smoke также проверил навигацию приложения, tooltip и смену валюты структуры портфеля на синтетических данных.
Сравнение runtime AST подтвердило, что очистка suppressions и скобок не меняет исполняемый код. Геометрия и порядок path сохранены для всех 26 SVG.
Pre-commit: Gitleaks, ESLint, dependency checks и commitlint; git diff --check.
Presentation-компоненты содержали SVG, обработчики в JSX, локальные схемы Zod и сложные условные выражения. PR переносит эти обязанности к явным владельцам и закрепляет требования к читаемости без изменения API-контрактов.
## Изменения
- SVG и анимации перенесены из application `src` в `@wealthledger/icons`. Каждая иконка — цельный декларативный SVG; геометрия не собирается в runtime. Реестр использует английские ключи, названия категорий API остаются данными с нормализацией и fallback.
- Обработчики и состояние форм вынесены в ViewModel, схемы — в отдельные `*.schema.ts`. VM полей карты композирует hooks даты и платёжной системы. Сохранены validation, idempotency и обработка конфликтов версий.
- Условные props получили именованные значения, крупные тернарники заменены явными ветками, добавлены интервалы между JSX siblings и смысловыми блоками. Короткий JSX не обрамляется лишними скобками.
- ESLint контролирует callbacks/тернарники в props, helpers внутри компонентов, размещение SVG и схем, optional trailing parameters, сложные union-типы и длину строк 80 символов. Строки, template/regex literals, URL и комментарии исключены из max-len; generated artifacts исключены из форматирования.
- `unicorn/no-null` отключён для сохранения контрактов API, React и Mantine; массовые локальные suppressions удалены. Известные названия банков вынесены в `BankName`.
- Семантические требования к именам, владельцам логики, цельным SVG и композиции VM закреплены в guardrails. Storybook допускает UI-only/form-context VM, сохраняя запрет транзитивного доступа к application API/auth/query providers.
Новых зависимостей нет. Значительная часть diff — форматирование существующих исходников, тестов и stories под новые правила.
## Проверки
- `npm ci` выполнен; полный `npm run verify` после доработок — успешно: 58 test files, 379 tests, 8 ESLint regression checks; TypeScript, OpenAPI, coverage thresholds, Knip, оба dependency graph и обе сборки пройдены.
- Chromium на собранном Storybook после доработок: 26 иконок операций, hover-анимации, reduced motion, клавиатурный выбор платёжной системы и viewport 375 px; без runtime exceptions.
- Первоначальный Chromium smoke также проверил навигацию приложения, tooltip и смену валюты структуры портфеля на синтетических данных.
- Сравнение runtime AST подтвердило, что очистка suppressions и скобок не меняет исполняемый код. Геометрия и порядок path сохранены для всех 26 SVG.
- Pre-commit: Gitleaks, ESLint, dependency checks и commitlint; `git diff --check`.
возможно лучше использовать внутри дополнительные хуки, в которых будет инкапсулировано поведение по смыслу, например все on* действия вынести в отдельный хук, который в хуке useBankCardFieldsVm будет просто отдавать наружу детали и т.д
возможно так будет понятнее логика + сделать в виде guardrails
возможно лучше использовать внутри дополнительные хуки, в которых будет инкапсулировано поведение по смыслу, например все on* действия вынести в отдельный хук, который в хуке useBankCardFieldsVm будет просто отдавать наружу детали и т.д
возможно так будет понятнее логика + сделать в виде guardrails
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Presentation-компоненты содержали SVG, обработчики в JSX, локальные схемы Zod и сложные условные выражения. PR переносит эти обязанности к явным владельцам и закрепляет требования к читаемости без изменения API-контрактов.
Изменения
srcв@wealthledger/icons. Каждая иконка — цельный декларативный SVG; геометрия не собирается в runtime. Реестр использует английские ключи, названия категорий API остаются данными с нормализацией и fallback.*.schema.ts. VM полей карты композирует hooks даты и платёжной системы. Сохранены validation, idempotency и обработка конфликтов версий.unicorn/no-nullотключён для сохранения контрактов API, React и Mantine; массовые локальные suppressions удалены. Известные названия банков вынесены вBankName.Новых зависимостей нет. Значительная часть diff — форматирование существующих исходников, тестов и stories под новые правила.
Проверки
npm ciвыполнен; полныйnpm run verifyпосле доработок — успешно: 58 test files, 379 tests, 8 ESLint regression checks; TypeScript, OpenAPI, coverage thresholds, Knip, оба dependency graph и обе сборки пройдены.git diff --check.@@ -10,3 +10,3 @@severity: "error",to: {path: String.raw`^src/(shared/api|features/auth|app/routes|app/ui)/|^src/(entities|features)/[^/]+/api/|\.vm\.ts$|^src/pages/[^/]+/ui/.*Page\.tsx$|node_modules/(@tanstack/react-query|openapi-fetch|openapi-react-query)/`,path: String.raw`^src/(shared/api|features/auth|app/routes|app/ui)/|^src/(entities|features)/[^/]+/api/|^src/pages/[^/]+/ui/.*Page\.tsx$|node_modules/(@tanstack/react-query|openapi-fetch|openapi-react-query)/`,можно ли упростить ? без использования String.raw ?
@@ -0,0 +42,4 @@"M3 7a14 14 0 0 1 18 0 M6 11a9 9 0 0 1 12 0 M9 15a4 4 0 0 1 6 0 M12 19h.01",wine:"M7 3h10v5a5 5 0 0 1-10 0V3Z M7 7h10v1a5 5 0 0 1-10 0V7Z M12 13v8 M8 21h8",} as const;не нужно так, svg должны быть целостными, а не разбиты по кускам, чтобы собираться в рантайме
@@ -98,0 +111,4 @@): (<DocumentTitle title={t("navigation.accounts")} />);для компонентов, которые помещаются в 1 строку не обязательно добавлять скобки
@@ -21,3 +21,2 @@const card: BankCard = (/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */{/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */слишком часто отключаем это правило, его нужно или совсем выключить или же правильно писать код, чтобы не дизейблить правило
@@ -4,2 +8,4 @@variant: OperationIconProps["variant"];};const categoryIcons: Record<string, OperationIcon> = {эту логику нужно переработать, потому что svg должны быть целостными, а не собираться в рантайме
также ключи в виде русских слов это порнография
@@ -42,0 +38,4 @@"Сбербанк","Т-Банк","Альфа-Банк","ВТБ",названия банков должны быть вынесены в отдельный enum
@@ -0,0 +7,4 @@import { bankDateInputValue } from "../../model/form-validation";import { type BankCardValues, bankDateSchema } from "../../model/form.schema";function useBankCardFieldsVm() {возможно лучше использовать внутри дополнительные хуки, в которых будет инкапсулировано поведение по смыслу, например все on* действия вынести в отдельный хук, который в хуке useBankCardFieldsVm будет просто отдавать наружу детали и т.д
возможно так будет понятнее логика + сделать в виде guardrails