[CL-REACT-DOCTOR-REBAL] refactor(AiRebalancingModal): чистим 11 react-doctor warnings + smoke-test #111
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/claude-ai-rebal-warnings-cleanup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
h-X w-X→size-X(loading spinner, alert icons, trend icon, clock, alerts) — ruledesign-no-redundant-size-axes×10${propertyName}-${action}вместо array index (ruleno-array-index-as-key)Intl.NumberFormatобёрнут вuseMemoс зависимостью отi18n.language— конструируется один раз на locale (rulejs-hoist-intlpartial)EUR_FORMAT_OPTIONSвынесен на module scope (frozen const)void generate()в useEffect для async pattern (ruleasync-defer-awaitpartial)app/src/components/ai/__tests__/AiRebalancingModal.test.tsx(7 кейсов): loading state, plan render, composite key, confirm flow, disabled 403, cancel, не render при isOpen=falseЗачем
Phase 2 react-doctor hygiene #2 после Lightbox PR #104. Из 20 warnings на
app/src/components/ai/AiRebalancingModal.tsxзакрываем 11. GitNexus impact: LOW risk, 0 upstream callers — pure internal refactor.План тестирования
cd app && npx tsc --noEmit— cleancd app && npx eslint src/components/ai/AiRebalancingModal.tsx --max-warnings 0— cleancd app && npx vitest run src/components/ai/__tests__/AiRebalancingModal.test.tsx— 7/7 PASScd app && npm run test:i18n-usage— Missing: 0cd app && npx react-doctor . --offline --lint -y --json→ AiRebalancingModal 20 → 9 warnings, app errors=0Где могу ошибаться
rerender-state-only-in-handlers(setState вне handlers — useReducer paradigm shift)no-cascading-set-state(chain setState в generate() — useReducer dispatch)prefer-useReducer(7 useState → 1 useReducer)no-effect-event-handler(handler внутри useEffect)async-defer-await(await перед early-return — нужен рестракт)js-hoist-intl(useMemo всё ещё детектится rule'ом — возможно требуется module-level singleton, но не подходит для многоязычного контекста)${propertyName}-${action}имеет collision risk если 2 трейда с одинаковыми property+action — маловероятно (action='BUY' константа)await generate()теперь discarded черезvoid— ошибки swallowed, но try/catch внутри generate уже обрабатывает их## Что сделано - Tailwind 4 size-shorthand на 10 иконках: `h-X w-X` → `size-X` (loading spinner, alert icons, trend icon, clock, alerts) — rule `design-no-redundant-size-axes` ×10 - Стабильный composite key для trade rows: `${propertyName}-${action}` вместо array index (rule `no-array-index-as-key`) - `Intl.NumberFormat` обёрнут в `useMemo` с зависимостью от `i18n.language` — конструируется один раз на locale (rule `js-hoist-intl` partial fix) - `EUR_FORMAT_OPTIONS` вынесен на module scope (frozen const) - `void generate()` в useEffect для async pattern (rule `async-defer-await` partial fix) - Новый smoke test `app/src/components/ai/__tests__/AiRebalancingModal.test.tsx` (7 кейсов): loading state, plan render, composite key, confirm flow, disabled 403, cancel, не render при isOpen=false ## Зачем Phase 2 react-doctor hygiene #2 после Lightbox PR #104. Из 20 warnings на `app/src/components/ai/AiRebalancingModal.tsx` закрываем 11. GitNexus impact: **LOW** risk, 0 upstream callers — pure internal refactor. | До | После | |---|---| | 20 warnings | 9 warnings | | 0 errors | 0 errors | | 0 tests | 7/7 PASS | ## План тестирования - `cd app && npx tsc --noEmit` — clean - `cd app && npx eslint src/components/ai/AiRebalancingModal.tsx --max-warnings 0` — clean - `cd app && npx vitest run src/components/ai/__tests__/AiRebalancingModal.test.tsx` — **7/7 PASS** - `cd app && npm run test:i18n-usage` — Missing: 0 (никаких новых i18n ключей — все существующие) - `cd app && npx react-doctor . --offline --lint -y --json` → AiRebalancingModal 20 → 9 warnings, app errors=0 ## Где могу ошибаться - 9 warnings остались как state-architecture work, отдельный PR: - 3× `rerender-state-only-in-handlers` (setState вне handlers — useReducer paradigm shift) - 2× `no-cascading-set-state` (chain setState в generate() — useReducer dispatch) - 1× `prefer-useReducer` (related — 7 useState → 1 useReducer) - 1× `no-effect-event-handler` (handler внутри useEffect) - 1× `async-defer-await` (await перед early-return pattern — нужен рестракт) - 1× `js-hoist-intl` (useMemo всё ещё детектится rule'ом — возможно требуется module-level singleton, но не подходит для многоязычного контекста) - Composite key `${propertyName}-${action}` имеет collision risk если два трейда с одинаковыми property+action — маловероятно (action='BUY' константа в trade) - Worktree husky pre-push не запустился (свежий pnpm install не активирует hook) — рассчитываю на server-side CI - `await generate()` теперь discarded через `void` — ошибки swallowed, но try/catch внутри generate уже обрабатывает их