Внедрить ESLint с анализом типов и проверками под стек WealthLedger: добавить на frontend и расширить существующий профиль backend. Эта issue в workspace координирует работу в двух самостоятельных репозиториях; зависимости и конфигурации принадлежат каждому из них.
На frontend изначально использовался Biome; backend уже использует ESLint и typescript-eslint recommendedTypeChecked.
Согласованные ограничения
От Biome отказались. Первоначальное ограничение «Biome пока не удаляем» (28.09.2026) отменено: форматирование JS/TS/TSX перешло к ESLint Stylistic, сортировка — к Perfectionist, accessibility — к соответствующим ESLint-плагинам. Biome удалён на frontend коммитом 72d7835; frontend/README.md описывает действующее состояние. Возврат Biome не планируется.
Prettier нигде не добавляем. Существующая установка Prettier на backend не является предметом этой задачи; её удаление или перенастройка отдельно не согласованы.
Основа — свежий стабильный ESLint. На момент выбора, 28.09.2026, latest — 10.11.0.
Указанные версии проверены по npm metadata, но совместная установка и запуск ещё не выполнялись. Перед реализацией повторно проверить latest, Node/TypeScript и peer dependencies; закрепить совместимые exact versions и lockfile.
Не использовать --force / --legacy-peer-deps для обхода несовместимости.
Не создавать общий конфиг-пакет в root и не расширять root CI: он остаётся только для commitlint.
Не подключать все строгие пресеты целиком. Каждое дополнительное правило должно давать полезный сигнал; исключить дублирование проверок.
eslint.config.mjs присутствует в обоих; lint подключён к verify. Дальнейшие delivery areas — в комментариях Issue.
## Цель и область
Внедрить ESLint с анализом типов и проверками под стек WealthLedger: добавить на frontend и расширить существующий профиль backend. Эта issue в workspace координирует работу в двух самостоятельных репозиториях; зависимости и конфигурации принадлежат каждому из них.
На frontend изначально использовался Biome; backend уже использует ESLint и typescript-eslint recommendedTypeChecked.
## Согласованные ограничения
- **От Biome отказались.** Первоначальное ограничение «Biome пока не удаляем» (28.09.2026) отменено: форматирование JS/TS/TSX перешло к ESLint Stylistic, сортировка — к Perfectionist, accessibility — к соответствующим ESLint-плагинам. Biome удалён на frontend коммитом `72d7835`; `frontend/README.md` описывает действующее состояние. Возврат Biome не планируется.
- **Prettier нигде не добавляем.** Существующая установка Prettier на backend не является предметом этой задачи; её удаление или перенастройка отдельно не согласованы.
- Основа — свежий стабильный ESLint. На момент выбора, 28.09.2026, latest — **10.11.0**.
- Указанные версии проверены по npm metadata, но совместная установка и запуск ещё не выполнялись. Перед реализацией повторно проверить latest, Node/TypeScript и peer dependencies; закрепить совместимые exact versions и lockfile.
- Не использовать `--force` / `--legacy-peer-deps` для обхода несовместимости.
- Не создавать общий конфиг-пакет в root и не расширять root CI: он остаётся только для commitlint.
- Не подключать все строгие пресеты целиком. Каждое дополнительное правило должно давать полезный сигнал; исключить дублирование проверок.
## 1. Добавляем сразу
Существующие пакеты backend обновляем/переиспользуем.
| Пакет | Проверенная версия | Область | Назначение |
| --- | --- | --- | --- |
| eslint | 10.11.0 | Frontend и backend | Движок |
| @eslint/js | 10.0.1 | Frontend и backend | Официальные recommended-правила JavaScript |
| typescript-eslint | 8.70.1 | Frontend и backend | Анализ типов, Promise, небезопасные операции |
| globals | 17.12.0 | Frontend и backend | Окружения браузера, Node и тестов |
| eslint-plugin-unicorn | 76.0.0 | Frontend и backend | Выбранные проверки ошибок |
## Фактическое состояние на 2026-10-17
`develop` обоих репозиториев содержит согласованные версии:
```
frontend: eslint 10.11.0, @eslint/js 10.0.1, typescript-eslint 8.70.1, globals 17.12.0, eslint-plugin-unicorn 76.0.0
backend: eslint 10.11.0, @eslint/js 10.0.1, typescript-eslint 8.70.1, globals 17.12.0
```
`eslint.config.mjs` присутствует в обоих; `lint` подключён к `verify`. Дальнейшие delivery areas — в комментариях Issue.
Тело Issue содержало ограничение «Biome пока не удаляем», принятое 28.09.2026. Фактически от Biome отказались: frontend перешёл на ESLint Stylistic + Perfectionist, Biome удалён коммитом 72d7835. Решение принято и подтверждено владельцем — ограничение в теле Issue устарело, а не нарушено.
Тело Issue обновлено: пункт про сохранение Biome заменён на фактическое решение. Это единственное расхождение, требовавшее правки.
Проверка остальных упоминаний Biome
Проверены все вхождения на develop во всех пяти репозиториях:
$ git grep -rn -i biome origin/develop
Файл
Тип
Статус
frontend/README.md:98
live doc
Корректен: «Biome удалён; Prettier не используется»
frontend/CHANGELOG.md:251
историческая запись
Корректна для своей версии, не правится
docs/code-quality-review.md (4 вхождения)
отчёт от 27.09.2026
Корректен для своей даты: Biome тогда присутствовал
audits/2026-10-11/reports/10-*.md
dated audit, read-only
Корректен: «Biome сейчас отсутствует; возвращать его не обосновано»
.ai/migrations/conventions-v1/audit.md
dated audit, read-only
Перечисление прочитанных источников, фактов о текущем состоянии не утверждает
specs/openspec/changes/archive/**
archived change, read-only
Корректен для своего периода
Ни один live-документ не утверждает, что Biome используется. Dated audits и архивы — read-only по root AGENTS, правке не подлежат.
Версии совпадают с согласованными в теле Issue. eslint.config.mjs присутствует в обоих репозиториях, lint подключён к verify.
Issue остаётся открытой: закрытие относится к её delivery areas целиком, а не к этому расхождению.
## Разрешение расхождения по Biome
Тело Issue содержало ограничение «**Biome пока не удаляем**», принятое 28.09.2026. Фактически от Biome отказались: frontend перешёл на ESLint Stylistic + Perfectionist, Biome удалён коммитом `72d7835`. Решение принято и подтверждено владельцем — ограничение в теле Issue устарело, а не нарушено.
Тело Issue обновлено: пункт про сохранение Biome заменён на фактическое решение. Это единственное расхождение, требовавшее правки.
## Проверка остальных упоминаний Biome
Проверены все вхождения на `develop` во всех пяти репозиториях:
```
$ git grep -rn -i biome origin/develop
```
| Файл | Тип | Статус |
| --- | --- | --- |
| `frontend/README.md:98` | live doc | Корректен: «Biome удалён; Prettier не используется» |
| `frontend/CHANGELOG.md:251` | историческая запись | Корректна для своей версии, не правится |
| `docs/code-quality-review.md` (4 вхождения) | отчёт от 27.09.2026 | Корректен для своей даты: Biome тогда присутствовал |
| `audits/2026-10-11/reports/10-*.md` | dated audit, read-only | Корректен: «Biome сейчас отсутствует; возвращать его не обосновано» |
| `.ai/migrations/conventions-v1/audit.md` | dated audit, read-only | Перечисление прочитанных источников, фактов о текущем состоянии не утверждает |
| `specs/openspec/changes/archive/**` | archived change, read-only | Корректен для своего периода |
Ни один live-документ не утверждает, что Biome используется. Dated audits и архивы — read-only по root AGENTS, правке не подлежат.
## Фактическое состояние ESLint на `develop`
```
$ git show origin/develop:package.json | grep -E '"(eslint|typescript-eslint|@eslint/js|globals|eslint-plugin-unicorn)"'
frontend: eslint 10.11.0, @eslint/js 10.0.1, typescript-eslint 8.70.1, globals 17.12.0, eslint-plugin-unicorn 76.0.0
backend: eslint 10.11.0, @eslint/js 10.0.1, typescript-eslint 8.70.1, globals 17.12.0
```
Версии совпадают с согласованными в теле Issue. `eslint.config.mjs` присутствует в обоих репозиториях, `lint` подключён к `verify`.
Issue остаётся открытой: закрытие относится к её delivery areas целиком, а не к этому расхождению.
codex-bot
changed title from chore: внедрить ESLint 10 и проверки качества frontend/backend, сохранив Biome to chore: внедрить ESLint 10 и проверки качества frontend/backend2026-10-17 19:42:12 +03:00
Status update (backend part). Work paused; no PR merged, branch discarded, develop untouched.
What was measured
eslint-plugin-unicorn@76.0.0 with recommended on backend: ~1250 findings in ~147 files before tuning.
Disabled with reasons: no-null (Prisma/DTO contracts), name-replacements and consistent-boolean-name (renames would touch Nest DI names, DTO class names in openapi.json and API field names), prefer-set-methods (ES2023 lib has no Set.union), explicit-length-check (conflicts with the no-magic-numbers policy in test/eslint-config.cjs).
Autofix alone broke types in 3 places (prefer-math-min-max on Date, prefer-array-index-of on narrowed union, Set.union) and rewrote ~90 files. Those were fixed with narrow eslint-disable comments, not reverted in bulk.
Remaining after tuning: ~286 findings in src (prefer-await 50, no-array-callback-reference 35, no-array-sort 30, max-nested-calls 26, consistent-class-member-order 23, and others).
Why not merged
Manual fixes in src were delegated to subagents. Two of them changed behaviour (TbankSyncService.status rewrote the state branch and access.local ordering; it also referenced a non-existent method). Those edits were discarded. Given backend#119 (sync consistency), manual changes to sync code must not be bundled with lint.
Disabling the remaining rules for src would violate "не отключать правила массово ради зелёного lint".
Decision
Close this PR-scope for backend now. Recreate as a separate Issue with groups (test/spec noise, async structure, class member order, sort) to be done after backend#119 lands.
Frontend part of main#18 is not verified here: frontend already has unicorn (preset with no-null and name-replacements configured), so the remaining AC check is a verification run, not new code.
Not verified: npm run verify and test:e2e on an unlint'ed branch (not run because the change was discarded).
Status update (backend part). Work paused; no PR merged, branch discarded, `develop` untouched.
## What was measured
- `eslint-plugin-unicorn@76.0.0` with `recommended` on backend: ~1250 findings in ~147 files before tuning.
- Disabled with reasons: `no-null` (Prisma/DTO contracts), `name-replacements` and `consistent-boolean-name` (renames would touch Nest DI names, DTO class names in openapi.json and API field names), `prefer-set-methods` (ES2023 lib has no `Set.union`), `explicit-length-check` (conflicts with the `no-magic-numbers` policy in `test/eslint-config.cjs`).
- Autofix alone broke types in 3 places (`prefer-math-min-max` on `Date`, `prefer-array-index-of` on narrowed union, `Set.union`) and rewrote ~90 files. Those were fixed with narrow `eslint-disable` comments, not reverted in bulk.
- Remaining after tuning: ~286 findings in `src` (prefer-await 50, no-array-callback-reference 35, no-array-sort 30, max-nested-calls 26, consistent-class-member-order 23, and others).
## Why not merged
- Manual fixes in `src` were delegated to subagents. Two of them changed behaviour (`TbankSyncService.status` rewrote the `state` branch and `access.local` ordering; it also referenced a non-existent method). Those edits were discarded. Given backend#119 (sync consistency), manual changes to sync code must not be bundled with lint.
- Disabling the remaining rules for `src` would violate "не отключать правила массово ради зелёного lint".
## Decision
- Close this PR-scope for backend now. Recreate as a separate Issue with groups (test/spec noise, async structure, class member order, sort) to be done after backend#119 lands.
- Frontend part of main#18 is not verified here: frontend already has unicorn (preset with `no-null` and `name-replacements` configured), so the remaining AC check is a verification run, not new code.
Not verified: `npm run verify` and `test:e2e` on an unlint'ed branch (not run because the change was discarded).
Frontend verification (no code changes needed; frontend develop ad93725).
Commands and results (Node 24.22.1 via nvm)
npm ci: OK.
npm run lint (eslint . --max-warnings=0, ESLint 10.13.0): exit 0.
npm run typecheck (tsc -b --noEmit after build:packages): exit 0.
npm run test:lint: exit 0.
npm run openapi:check: exit 0, no contract drift.
npm run verify (full): first run failed on 3 flaky unit tests (screen-sync.test.tsx, OperationForm.test.tsx, StockPage.test.tsx). They pass in isolation (24/24) and in two subsequent full vitest run --coverage runs (580/580). Not a lint regression. Not investigated further in this Issue; the flakiness itself is a separate concern.
Then individually: knip, depcruise (both configs), tsc -b, vite build, storybook build: all exit 0.
AC check (frontend)
ESLint 10 + typescript-eslint + globals + unicorn: configured and in use.
unicorn.configs.recommended enabled; the only off rule specific to unicorn is no-null (with a reason in config).
No blanket disabling: eslint-disable count in src/packages is 68 (per-site, not new in this Issue).
User-facing strings in TSX (non-test): no hard-coded Russian text found; the single Cyrillic match is a bank-name regexp in entities/bank-card/ui/BankCardFace/BankCardFace.tsx:58-62 (matching, not UI copy).
Backend
Not done. Tracked in WealthLedger/backend#161 (split from this Issue): enabling unicorn on backend with staged fixes, after backend#119.
Status
Frontend part: verified. Backend part: open (backend#161). Keeping this Issue open until backend#161 is resolved or explicitly split out.
Not verified: verify as one green run in CI (only locally, with the flaky-test caveat above). Frontend CI status on a PR was not checked because no PR was created.
Frontend verification (no code changes needed; frontend develop `ad93725`).
## Commands and results (Node 24.22.1 via nvm)
- `npm ci`: OK.
- `npm run lint` (`eslint . --max-warnings=0`, ESLint 10.13.0): exit 0.
- `npm run typecheck` (`tsc -b --noEmit` after `build:packages`): exit 0.
- `npm run test:lint`: exit 0.
- `npm run openapi:check`: exit 0, no contract drift.
- `npm run verify` (full): first run failed on 3 flaky unit tests (`screen-sync.test.tsx`, `OperationForm.test.tsx`, `StockPage.test.tsx`). They pass in isolation (24/24) and in two subsequent full `vitest run --coverage` runs (580/580). Not a lint regression. Not investigated further in this Issue; the flakiness itself is a separate concern.
- Then individually: `knip`, depcruise (both configs), `tsc -b`, `vite build`, `storybook build`: all exit 0.
## AC check (frontend)
- ESLint 10 + typescript-eslint + globals + unicorn: configured and in use.
- `unicorn.configs.recommended` enabled; the only off rule specific to unicorn is `no-null` (with a reason in config).
- No blanket disabling: `eslint-disable` count in `src`/`packages` is 68 (per-site, not new in this Issue).
- User-facing strings in TSX (non-test): no hard-coded Russian text found; the single Cyrillic match is a bank-name regexp in `entities/bank-card/ui/BankCardFace/BankCardFace.tsx:58-62` (matching, not UI copy).
## Backend
Not done. Tracked in WealthLedger/backend#161 (split from this Issue): enabling unicorn on backend with staged fixes, after backend#119.
## Status
Frontend part: verified. Backend part: open (backend#161). Keeping this Issue open until backend#161 is resolved or explicitly split out.
Not verified: `verify` as one green run in CI (only locally, with the flaky-test caveat above). Frontend CI status on a PR was not checked because no PR was created.
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.
Цель и область
Внедрить ESLint с анализом типов и проверками под стек WealthLedger: добавить на frontend и расширить существующий профиль backend. Эта issue в workspace координирует работу в двух самостоятельных репозиториях; зависимости и конфигурации принадлежат каждому из них.
На frontend изначально использовался Biome; backend уже использует ESLint и typescript-eslint recommendedTypeChecked.
Согласованные ограничения
72d7835;frontend/README.mdописывает действующее состояние. Возврат Biome не планируется.--force/--legacy-peer-depsдля обхода несовместимости.1. Добавляем сразу
Существующие пакеты backend обновляем/переиспользуем.
Фактическое состояние на 2026-10-17
developобоих репозиториев содержит согласованные версии:eslint.config.mjsприсутствует в обоих;lintподключён кverify. Дальнейшие delivery areas — в комментариях Issue.Разрешение расхождения по Biome
Тело Issue содержало ограничение «Biome пока не удаляем», принятое 28.09.2026. Фактически от Biome отказались: frontend перешёл на ESLint Stylistic + Perfectionist, Biome удалён коммитом
72d7835. Решение принято и подтверждено владельцем — ограничение в теле Issue устарело, а не нарушено.Тело Issue обновлено: пункт про сохранение Biome заменён на фактическое решение. Это единственное расхождение, требовавшее правки.
Проверка остальных упоминаний Biome
Проверены все вхождения на
developво всех пяти репозиториях:frontend/README.md:98frontend/CHANGELOG.md:251docs/code-quality-review.md(4 вхождения)audits/2026-10-11/reports/10-*.md.ai/migrations/conventions-v1/audit.mdspecs/openspec/changes/archive/**Ни один live-документ не утверждает, что Biome используется. Dated audits и архивы — read-only по root AGENTS, правке не подлежат.
Фактическое состояние ESLint на
developВерсии совпадают с согласованными в теле Issue.
eslint.config.mjsприсутствует в обоих репозиториях,lintподключён кverify.Issue остаётся открытой: закрытие относится к её delivery areas целиком, а не к этому расхождению.
chore: внедрить ESLint 10 и проверки качества frontend/backend, сохранив Biometo chore: внедрить ESLint 10 и проверки качества frontend/backendStatus update (backend part). Work paused; no PR merged, branch discarded,
developuntouched.What was measured
eslint-plugin-unicorn@76.0.0withrecommendedon backend: ~1250 findings in ~147 files before tuning.no-null(Prisma/DTO contracts),name-replacementsandconsistent-boolean-name(renames would touch Nest DI names, DTO class names in openapi.json and API field names),prefer-set-methods(ES2023 lib has noSet.union),explicit-length-check(conflicts with theno-magic-numberspolicy intest/eslint-config.cjs).prefer-math-min-maxonDate,prefer-array-index-ofon narrowed union,Set.union) and rewrote ~90 files. Those were fixed with narroweslint-disablecomments, not reverted in bulk.src(prefer-await 50, no-array-callback-reference 35, no-array-sort 30, max-nested-calls 26, consistent-class-member-order 23, and others).Why not merged
srcwere delegated to subagents. Two of them changed behaviour (TbankSyncService.statusrewrote thestatebranch andaccess.localordering; it also referenced a non-existent method). Those edits were discarded. Given backend#119 (sync consistency), manual changes to sync code must not be bundled with lint.srcwould violate "не отключать правила массово ради зелёного lint".Decision
no-nullandname-replacementsconfigured), so the remaining AC check is a verification run, not new code.Not verified:
npm run verifyandtest:e2eon an unlint'ed branch (not run because the change was discarded).Frontend verification (no code changes needed; frontend develop
ad93725).Commands and results (Node 24.22.1 via nvm)
npm ci: OK.npm run lint(eslint . --max-warnings=0, ESLint 10.13.0): exit 0.npm run typecheck(tsc -b --noEmitafterbuild:packages): exit 0.npm run test:lint: exit 0.npm run openapi:check: exit 0, no contract drift.npm run verify(full): first run failed on 3 flaky unit tests (screen-sync.test.tsx,OperationForm.test.tsx,StockPage.test.tsx). They pass in isolation (24/24) and in two subsequent fullvitest run --coverageruns (580/580). Not a lint regression. Not investigated further in this Issue; the flakiness itself is a separate concern.knip, depcruise (both configs),tsc -b,vite build,storybook build: all exit 0.AC check (frontend)
unicorn.configs.recommendedenabled; the only off rule specific to unicorn isno-null(with a reason in config).eslint-disablecount insrc/packagesis 68 (per-site, not new in this Issue).entities/bank-card/ui/BankCardFace/BankCardFace.tsx:58-62(matching, not UI copy).Backend
Not done. Tracked in WealthLedger/backend#161 (split from this Issue): enabling unicorn on backend with staged fixes, after backend#119.
Status
Frontend part: verified. Backend part: open (backend#161). Keeping this Issue open until backend#161 is resolved or explicitly split out.
Not verified:
verifyas one green run in CI (only locally, with the flaky-test caveat above). Frontend CI status on a PR was not checked because no PR was created.