Переносит архив `audits/2026-10-11/` (19 файлов) из codex/audit-remediation-2026-10-11 в develop и добавляет точечный allowlist в .gitignore.
58 KiB
Аудит 12 — Dependencies & Configuration
1. Audit metadata
- Audit ID/name: 12 / Dependencies & Configuration.
- Дата: 2026-10-11.
- Режим: read-only для
frontend,backend,specs,docs; единственный создаваемый workspace artifact — этот отчёт. - Scope: необходимость dependencies, direct/transitive/peer ownership, toolchain, compiler/test/build configuration, env authority, generated inputs и воспроизводимость локальной подготовки. CI timings, качество assertions, уязвимости и бизнес-контракты не аудировались.
- Skill: установленный
ponytail-auditпрочитан через Skill tool и применён к complexity-pass. Correctness findings получены отдельно по протоколу аудита 12. Прочитанverification-before-completionдля проверки итогового артефакта. Graphify skill прочитан; существующегоgraphify-out/graph.jsonв workspace нет, install/extraction не выполнялись ввиду read-only контракта. - Предыдущие материалы:
technical-audit-2026-10-11.mdпрочитан как реестр гипотез; его выводы и измерения не приняты за доказательство. Отчёт 11 использован для разграничения ответственности, его timings/результаты не пересчитывались.
Workspace: /Users/ksv741/Project/vibe/WealthLedger. Найдены четыре самостоятельных checkout и отдельный root Git repo:
| Repo | Путь | HEAD SHA | Ветка | Начальный status |
|---|---|---|---|---|
| frontend | frontend/ |
c8821200ce699dab1ce65360d1968d5877a2e78b |
codex/fix-stock-screener-race |
clean |
| backend | backend/ |
0ad84ff4f0b4712abc7e69dc299856f14af6eadd |
codex/add-stock-screener |
clean |
| specs | specs/ |
fcdc805f6c1b3be6a20a7e858e3e80cbd83a9121 |
codex/add-stock-screener |
clean |
| docs | docs/ |
e6fd4f64b81dd73b33959b845a1babcfac1891c8 |
codex/add-stock-screener |
clean |
| root, вспомогательная область | ./ |
dc030f84c979cedb2628ef4bd97c62d6c63a9256 |
release/0.2.1 |
clean |
Отдельный deploy/ не исследовался. Root Compose рассматривается только как доступный development configuration consumer, не как доказательство текущего server deployment. Личные .env, базы, сертификаты и credentials не читались.
Выполненные проверки
- Read/Glob/Grep: repo instructions; manifests и верхние секции пяти lockfiles; выбранные lockfile nodes; compiler/build/test/lint/Storybook/Knip/dependency configs; env validators и consumers; generated-artifact callers; setup instructions.
- Во всех пяти Git repo:
git status --short --branch,git rev-parse HEAD; в application repos такжеgit ls-files -- <config/generated/lock patterns>для проверки tracking boundary. - В frontend и backend после
source "$HOME/.nvm/nvm.sh" && nvm use --silent:node --version,npm --version→ v24.21.0 / 11.19.0;npm ls --depth=0 --ignore-scripts→ exit 0. - Там же
npm ls --all --json --ignore-scriptsсset -o pipefailи выводомproblems/errorчерез inline Node stdin reduction → оба exit 0,problems: [],error: null. Это проверка установленного dependency graph, не clean-install/build proof. - Там же
npm query '*' --package-lock-only --ignore-scriptsс inline stdin reduction → inventory виртуального graph из lockfile, без install или записи нового lockfile. Метод и результаты ниже. - Backend:
npm explain better-sqlite3 source-map-support ts-loader --ignore-scripts→ подтверждены consumers и цепочка optional/required peers. Команда ничего не удаляет. - Context7: документация npm об
allowScriptsи Prisma о явной генерации client. Дополнительно прочитаны versioned Prisma v7 deployment/workflow docs. Unversioned workflow URL перенаправил на новую модель Prisma; эта страница не использована для рекомендаций к установленной 7.10.0. - Итоговая проверка файла: чтение нового отчёта, whitespace-check относительно
/dev/null,git diff --check, повторный status/HEAD пяти repos. Результат заключительной проверки записан в разделе 10.
Npm выводит предупреждение Unknown user config "//registry". Это user-level configuration за пределами checkout; её содержимое не читалось. Команды inventory завершились успешно. Предупреждение не объявлено дефектом project configuration.
Не запускались: install/prune/update, npm audit, codegen, migrations, application/CLI watch processes, tests, lint, build, full verify, Docker, OpenSpec validation, обращения к брокерским/банковским API, CI runs, commit/PR. Исполняемые audit tools не создавались. Изменений manifests, lockfiles, sources или generated artifacts нет. Runtime-воспроизведение fresh setup и экономия времени/размера — UNVERIFIED / not measured.
2. Executive verdict
- Факт / FIX, P2: самостоятельный backend quick start пропускает Prisma generation.
npm ci → migrate deploy → start:devне создаёт ignoredgenerated/prisma, который импортирует приложение. CI, Docker и root setup явно готовят client, поэтому существующий тёплый checkout скрывает дефект подготовки. DEPS-001. - Факт / DELETE, P2: backend использует штатный Nest
tscbuilder, но прямо устанавливаетts-loader. Его required peer приводит в graph Webpack и minimizer/Terser; optional peers Nest CLI сами по себе не требуют этой ветки. Прямая декларацияsource-map-supportтакже не имеет project caller. DEPS-002. - Факт / SIMPLIFY, P2: runtime Prisma adapter использует
better-sqlite3@12.11.1, а smoke/durability SQL checks — прямой13.0.3. В production dependency tree сохраняются обе версии. Прямой драйвер нужен, но выбранный major не согласован с runtime owner. DEPS-003. - Факт / FIX, P3:
start:debugне задаётNODE_ENV=development, в отличие отstart:dev. При env example и отсутствии внешнегоNODE_ENVdebugger получает выключенный Swagger и Secure-cookie policy, хотя startup log называет окружение development. Это небольшой setup drift, не подтверждённая уязвимость. DEPS-004. - KEEP: peers без прямых imports, Prisma CLI в production, независимые lockfiles, OpenAPI snapshot/types, Node alignment и разделение JSDOM/Chromium обоснованы реальными consumers. Различие TypeScript frontend/backend и Sonar/application profiles не требует автоматического выравнивания.
- UNVERIFIED: clean installation на Linux/macOS, фактическое удаление транзитивной Webpack-ветки после будущего cleanup, размер image/bundle, Sonar server/analyzer version и настройка глобального OpenSpec CLI. Их нельзя вывести из зелёного
npm ls.
Итог: четыре подтверждённых findings: три P2 и один P3; P0/P1 не установлены. Удаление двух direct dev declarations и согласование одного runtime driver полезнее введения общего cross-repo tooling или нового валидатора.
3. Inventory & coverage
3.1 Manifests, versions и lockfiles
| Repo | Production direct keys | Dev direct keys | Toolchain / назначение |
|---|---|---|---|
| frontend root | 23, включая 3 local workspace dependencies | 52 | React 19.3.0, Vite 8.3.0, TS 5.9.3, Vitest 5.0.0, Storybook 10.6.0 |
| backend | 26 | 37 | Nest 12.x, Prisma 7.10.0, TS 6.0.3, Jest 30.5.1 / ts-jest 29.4.12 |
| specs | 0 | 5 | Commit/release tooling; OpenSpec отсутствует в local npm dependency contract |
| docs | 0 | 7 | Commit/release tooling + Markdown lint/relative-links |
| root | 0 | 5 | Commit/release tooling |
Метод: подсчёт ключей dependencies и devDependencies прочитанных root manifests. Это число declarations, не уникальных packages во всём workspace. Дополнительно полностью прочитаны три frontend workspace manifests, то есть всего восемь manifests. Их peer/dev declarations не суммируются с root: одна и та же установка deduped, но contracts владельцев самостоятельны.
Все пять прочитанных lockfile headers — npm lockfileVersion 3; root names/versions/direct declarations в просмотренных header sections согласованы с соответствующими manifests. Другой tracked JS lockfile в выбранном application tracking inventory не обнаружен. Все пять .nvmrc содержат 24.21.0; application Dockerfiles используют node:24.21.0-bookworm-slim. Версии registry dependencies в direct manifests exact; file: links frontend намеренные.
3.2 Transitive / peer / optional / platform inventory
Метод: один npm query '*' --package-lock-only --ignore-scripts на application repo. Из JSON отброшены nodes с пустым location; посчитаны nodes и truthy поля dev, optional, peer, hasInstallScript, наличие os || cpu. Workspace nodes включены. Это npm virtual graph nodes, не объём диска, не только external names и не число реально установленных platform packages.
| Метрика | frontend | backend |
|---|---|---|
| Nodes с непустым location | 1294 | 1119 |
dev: true |
1192 | 738 |
optional: true |
191 | 43 |
peer: true |
0 | 43 |
hasInstallScript: true |
4 | 8 |
Есть os или cpu |
178 | 34 |
Flags пересекаются и не образуют разбиение. peer: 0 у frontend не означает отсутствия peer contracts: прямо объявленный peer provider не обязан иметь этот installation flag. Например, Mantine charts → Recharts → react-is доказаны installed manifests. Platform entries в lockfile не означают, что на Darwin установлены все Linux/Windows binaries.
Lockfile-marked lifecycle nodes:
- Frontend:
esbuild@0.28.2,fsevents@2.3.3(optional),msw@2.15.0,unrs-resolver@1.12.2. - Backend:
@parcel/watcher@2.6.0, nestedbetter-sqlite3@12.11.1,@prisma/engines@7.10.0,@scarf/scarf@1.4.0,bcrypt@6.0.0,prisma@7.10.0,protobufjs@7.6.5,unrs-resolver@1.12.2.
Frontend allowScripts разрешает esbuild/fsevents; backend разрешает актуальные native/Prisma/protobuf/resolver nodes и содержит разрешение для better-sqlite3@13.0.3, у которого install hook отсутствует. Это не два native build hooks: версия 13 поставляет prebuilds, версия 12 имеет prebuild-install || node-gyp rebuild. Неисполнение MSW/scarf и optional/fallback hooks не объявлено поломкой без proof необходимого поведения. Policy owner — root manifest каждого npm repo, не dependency/workspace manifest.
3.3 Dependency Decision Register
Полный перечень exact versions доступен в frontend/package.json:39–116, backend/package.json:40–105; ниже все direct declarations сгруппированы по реальным ролям. KEEP для группы означает установленную роль в stack/configuration, не semantic audit каждого её API.
| Repo / class | Dependencies | Consumer / назначение | Decision |
|---|---|---|---|
| frontend runtime UI | react, react-dom, react-router, @mantine/core, @mantine/hooks, @mantine/notifications, motion |
App/providers/routes, form/view imports, RouteTransition | KEEP |
| frontend runtime charts/dates | @mantine/charts, recharts, react-is, @mantine/dates, dayjs |
DonutChart/AreaChart, DateInput/DatePickerInput, locale; Recharts/react-is — peers | KEEP |
| frontend forms/i18n | react-hook-form, @hookform/resolvers, zod, i18next, react-i18next |
AuthForm, BankCard/Operation forms и локализованные schemas | KEEP |
| frontend runtime HTTP/cache | @tanstack/react-query, openapi-fetch, openapi-react-query |
src/shared/api/client.ts:1–4, App QueryClient/provider |
KEEP; разные уровни одного typed flow |
| frontend local packages | @wealthledger/icons, @wealthledger/tokens, @wealthledger/ui |
App и Storybook theme/assets/components; exports → dist/JSON | KEEP |
| frontend build/type/PWA | typescript, @types/node, @types/react, @types/react-dom, vite, @vitejs/plugin-react, @rolldown/plugin-babel, @babel/core, babel-plugin-react-compiler, vite-plugin-pwa |
TS configs, Vite React compiler preset/PWA; package library builds | KEEP |
| frontend tests/catalog | vitest, @vitest/coverage-v8, @vitest/browser-playwright, playwright, jsdom, @testing-library/react, @testing-library/jest-dom, msw, storybook, @storybook/react-vite, @storybook/addon-docs |
Vitest projects/setup/server, browser provider, .storybook/main.ts |
KEEP |
| frontend graph/unused | dependency-cruiser, knip |
scripts и разные graph/unused-declaration policies | KEEP |
| frontend lint core | eslint, @eslint/js, typescript-eslint, globals, eslint-import-resolver-typescript, eslint-plugin-import-x |
eslint.config.mjs:1–21,133–164 |
KEEP |
| frontend lint plugins | @eslint-react/eslint-plugin, @stylistic/eslint-plugin, @tanstack/eslint-plugin-query, @vitest/eslint-plugin, eslint-plugin-jest-dom, eslint-plugin-no-unsanitized, eslint-plugin-perfectionist, eslint-plugin-react-hooks, eslint-plugin-react-refresh, eslint-plugin-regexp, eslint-plugin-security, eslint-plugin-sonarjs, eslint-plugin-storybook, eslint-plugin-testing-library, eslint-plugin-unicorn |
Все импортированы/подключены flat config; production/test/story profiles различаются | KEEP; полезность отдельных rules вне этого аудита |
| frontend hooks/release | husky, lint-staged, @commitlint/cli, @commitlint/config-conventional, release-it, @release-it/conventional-changelog, conventional-changelog-conventionalcommits |
prepare/hooks/staged scripts, commitlint, release plugin/preset | KEEP |
| backend HTTP/framework | @nestjs/common, @nestjs/core, @nestjs/config, @nestjs/platform-express, @nestjs/swagger, class-transformer, class-validator, reflect-metadata, rxjs |
Nest modules/bootstrap/DTO validation; metadata/RxJS — framework peers | KEEP |
| backend auth/cookies | @nestjs/jwt, @nestjs/passport, passport, passport-jwt, bcrypt, cookie-parser |
AuthModule, JWT strategy/guard, password hashing, configureApp | KEEP |
| backend DB/config | @prisma/adapter-better-sqlite3, @prisma/client, prisma, better-sqlite3, dotenv |
PrismaService, compiled generated client, image migrations, smoke/durability SQL, prisma.config.ts |
KEEP direct contracts; driver alignment DEPS-003 |
| backend integrations/logs | @grpc/grpc-js, @grpc/proto-loader, cheerio, lru-cache, nestjs-pino, pino-http |
TbankClient RPC/TLS/proto, NCR HTML+bounded cache, typed loggingOptions | KEEP |
| backend build/debug | @nestjs/cli, @nestjs/schematics, typescript, ts-node, tsconfig-paths, ts-loader, source-map-support |
CLI collection/tsc; test:debug explicitly preloads ts-node/paths; Webpack route не выбран |
KEEP первых пяти; DELETE двух последних — DEPS-002 |
| backend tests/types | @nestjs/testing, jest, ts-jest, supertest; @types/bcrypt, @types/cookie-parser, @types/express, @types/jest, @types/node, @types/passport-jwt, @types/supertest |
configured unit/HTTP tests, Jest transformer, application/test TS | KEEP |
| backend lint | eslint, @eslint/js, typescript-eslint, globals, @darraghor/eslint-plugin-nestjs-typed, @stylistic/eslint-plugin, eslint-import-resolver-typescript, eslint-plugin-import-x, eslint-plugin-jest, eslint-plugin-n, eslint-plugin-perfectionist, eslint-plugin-regexp, eslint-plugin-security, eslint-plugin-sonarjs |
eslint.config.mjs:2–15,25–40,79–123 |
KEEP |
| backend/specs/docs/root release | @commitlint/cli, @commitlint/config-conventional, release-it, @release-it/conventional-changelog, conventional-changelog-conventionalcommits |
Локальные scripts/configs каждого независимого repo | KEEP; duplication across repos не дефект |
| docs validation | markdownlint-cli, markdownlint-rule-relative-links |
manifest lint + .markdownlint-rule-relative-links.cjs:1 |
KEEP |
Peer compatibility контрпроверена установленным graph. В частности, backend/node_modules/ts-jest/package.json:64–71 принимает Jest 29/30 и TS >=4.3 <7: различие major names не является конфликтом. Nest CLI локально требует TS ~6.0.2; frontend остаётся на TS 5.9.3 с отдельными browser/package configs. Общий compiler lockfile здесь не нужен.
3.4 Potential Unused (not proven)
| Initial candidate | Почему отсутствие project import недостаточно | Решение / дешёвая следующая проверка |
|---|---|---|
recharts, react-is |
Mantine charts peer recharts >=3.2.1; Recharts peer react-is (node_modules/@mantine/charts/package.json:37–42, node_modules/recharts/package.json:89–92) |
KEEP explicit providers, не перекладывать contract на transitives |
Backend прямой better-sqlite3 |
Dynamic require в durability и JS string, исполняемой внутри container smoke | KEEP direct package; согласовать version, не удалять consumer |
reflect-metadata, rxjs, passport |
Framework/decorator/strategy integration и peer requirements | KEEP; отсутствие import в отдельных business files не unused proof |
@nestjs/schematics |
nest-cli.json:3 выбирает collection; CLI загружает её по строке |
KEEP |
conventional-changelog-conventionalcommits |
Release preset задан строкой name: conventionalcommits; frontend Knip ignore осознанно отражает dynamic loading |
KEEP |
@babel/core, babel-plugin-react-compiler |
Root Vite config вызывает reactCompilerPreset(); preset integration — consumer без прямого compiler-plugin import |
KEEP |
unrs-resolver, fsevents, platform packages |
Transitive tooling/optional native resolution, platform-specific packaging | Не переносить транзитивные packages в direct; не вычищать lock nodes вручную |
ts-loader и прямая декларация source-map-support после проверки config/CLI consumers переведены из кандидатов в DEPS-002. Других доказанных unused direct dependencies не установлено. Массовый автоматический removal по текстовым imports не предлагается.
3.5 Configuration Authority Matrix
| Значение / область | Authoritative owner | Consumers / дублирование | Вывод |
|---|---|---|---|
| Node 24.21.0 | .nvmrc каждого repo; manifest engine; соответствующий Docker base |
setup-node читает local .nvmrc; backend ESLint node version тоже 24.21.0 |
KEEP согласованность; npm 11.19.0 фактически проверен на host, версия внутри image не проверена |
| Direct versions / lifecycle permissions | Local package.json + package-lock.json; allowScripts root npm project |
npm ci, Docker, scripts; independent Renovate configs | KEEP локальную authority; не вводить соседний checkout как toolchain source |
| Backend required env/defaults | src/config/env.validation.ts:21–33,102–114 |
ConfigModule → ConfigService → Prisma/auth/logging/TbankClient/main; example воспроизводит defaults | Один runtime owner для PORT=3000, rate=5, endpoint, LOG_LEVEL=info; mismatch defaults не найден |
| Backend mode | Explicit NODE_ENV launch context |
start:dev, Docker/Compose задают development/production; main/auth читают process.env напрямую | DEPS-004: один debug entry point выбивается из того же launch contract |
| Development env | .env.example каждого app и root .env.development.example |
Local manual setup; root development Compose | Required backend: DB URL, frontend origin, JWT secret, encryption key; реальные secrets не исследованы |
| API base/proxy | Frontend VITE_API_BASE_URL в client.ts:21–26; Vite API_PROXY_TARGET в vite.config.ts:54–60 |
Local example = absolute localhost; Docker = empty same-origin base + backend proxy | Это browser/build-time base и dev-server target, а не два competing endpoints |
| Frontend TS language/alias | tsconfig.base.json, tsconfig.app.json |
Vite/Vitest alias @ → src; packages имеют declaration configs |
Alias согласован; отдельные app/config module modes имеют разных consumers |
| Frontend graph resolution | tsconfig.dependency-cruiser.json |
Package aliases указывают source для архитектурных edges вместо built dist | KEEP deliberate analysis projection; runtime всё ещё использует package exports |
| Backend output/module resolution | tsconfig.json + build/dev profiles, nest-cli.json |
dist/src/main.js, dist-dev; copied proto assets; Jest ts-jest и e2e .js mapper |
ESM Nest integration и CJS generated Prisma — явные contracts; drift failures не доказаны |
| Sonar TS projection | sonar-project.properties:11–12, tsconfig.sonar.json каждого app |
CI использует отдельный profile для заявленного старого analyzer | KEEP до проверки server analyzer; это не app typecheck и не основание слить configs |
| Tests/platforms | vitest.config.ts, backend manifest Jest + test/jest-e2e.json |
JSDOM, Chromium narrow/wide; src unit vs test HTTP suites | KEEP разные boundaries; одинаковые transform fragments не требуют общего runner |
| Browser/RPC deadlines | frontend/src/shared/api/client.ts:15–18; backend/src/integrations/tbank/tbank.client.ts:49–54 |
HTTP transport и upstream RPC имеют собственные retry budgets | Одинаковые 15 s не доказывают единую policy; budget composition — audit 07 |
| Generated Prisma | prisma/schema.prisma:1–5; package.json:12 build |
generated/prisma → PrismaService → TS build; ignored source | DEPS-001 касается самостоятельного quick start; CI/Docker готовят client явно, standalone checks — отдельный audit 11 |
| Public API artifacts | Backend openapi/generator; явно доставленный frontend snapshot + local generator version | openapi-fetch types, temporary byte comparison |
KEEP committed frontend snapshot/types, backend temporary output не коммитить автоматически |
| Specs native CLI | specs/README.md:18–31, предоставленная установка OpenSpec |
Отдельная native validation; npm verify не запускает CLI | INVESTIGATE только если clean setup этой workflow становится требованием; CLI version не проверялась |
Широкого набора неиспользуемых production env flags не найдено: каждое поле Environment имеет validator/default и конкретного ConfigService consumer. NODE_ENV, CI, HUSKY и KNIP_DISABLE_RAW_TRANSFER — launch/tooling context, а не параметры финансовой модели. Корректность бизнес-политик, опций scheduler и закрытых external integrations не исследовалась.
3.6 Tool Overlap Matrix
| Инструменты / configs | Реальные зоны применения | Verdict |
|---|---|---|
ESLint + Stylistic; aliases format, lint:fix |
Одна ESLint flat-config execution, stylistic plugin форматирует тот же JS/TS | KEEP; второго project formatter в direct manifests нет |
| ESLint import rules + dependency-cruiser + Knip | Local import/type checks; graph cycles/layers/reachability; unused entries/exports/declarations | KEEP разные доказательства; повторные triggers — audit 11 |
| Vite/Rolldown + Babel React compiler | Bundling/React transform против React compiler optimization preset | KEEP; Babel не заменяет Vite |
| Nest tsc + ts-jest | Production TS compilation против Jest transform | KEEP |
| Nest tsc + ts-loader/Webpack | Выбранный tsc builder против невыбранного Webpack builder | DELETE unused direct Webpack entry — DEPS-002 |
| Vitest JSDOM + browser-playwright + RTL/MSW | Fast component/transport tests против actual Chromium layout; RTL/MSW дают interactions/network simulation | KEEP; browser dependency не равна дублирующему test framework |
| Zod/RHF resolver + backend class-validator | Browser form validation и server trust-boundary DTO validation в независимых repos | KEEP; generic cross-repo schema layer не нужен |
| OpenAPI JSON + generated TS | Явный provider artifact и derived consumer types | KEEP; source JSON и type output не взаимозаменяемы |
| Markdown main/changelog profiles | Общий lint и специальная повторяемость release headings, через extends |
KEEP |
| Application + Sonar tsconfigs | Текущий compiler против старого external analyzer | KEEP version-compatibility adapter; точная server version UNVERIFIED |
3.7 Generated sources и reproducibility
git ls-filesподтверждает tracking frontendsrc/shared/api/spec/openapi.jsonиsrc/shared/api/generated/schema.d.ts; workspace package dist не tracked.check-openapi.mjs:6–12,16–33,41–43генерирует временный type artifact и сравнивает с committed, затем удаляет temp. Проверка во время аудита не запускалась.- Backend
.gitignore:7–8,69–70исключает generated Prisma иopenapi.json.generate-openapi.cjs:4–15,23–35задаёт disposable configuration, использует Nest preview и пишет provider artifact. Runtime correctness/свежесть artifact не выводятся из наличия файла на диске. - Backend
buildвладеет Prisma generation; frontend package builds владеют JS/CSS/declarations. Требовать committed private outputs вместо этих build owners оснований нет. longs: String, разныеdefaults: true/falsegRPC loaders (tbank.client.ts:194–209,232–241) сохраняют precision/field-presence contracts. Их нельзя консолидировать только по одинаковым именам packages/options.
Coverage risk-based: inventory manifests/configs полный в перечисленных областях; semantic tracing сосредоточен на fresh setup, выбранном compiler, peers без imports, native runtime boundary и mode consumers. Не исследованы все APIs каждого пакета, вся browser support matrix, actual images, registry provenance, advisories и глобальные editor/user configs.
4. Findings
DEPS-001 — Backend quick start не подготавливает generated Prisma Client
- Decision: FIX. Severity: P2. Confidence: High. Effort: S.
- Evidence:
backend/README.md:9–18;backend/package.json:11–18;backend/prisma/schema.prisma:1–5;backend/.gitignore:7–8;backend/src/prisma/prisma.service.ts:3–5,16–21;backend/node_modules/@prisma/client/package.json:264–275; контргарантии:backend/.gitea/workflows/verify.yml:83–85,backend/Dockerfile:7–10,README.md:97–104. - Claim: инструкция для самостоятельного свежего checkout заканчивается
start:devбез шага, создающего импортируемый client. Это дефект prerequisites, не требование коммитить generated code. - Current mechanism: schema output —
generated/prisma; install hooks client 7.10.0 не генерируют его; root project не содержит generation lifecycle.migrate deployприменяет SQL, не генерирует client.start:devзапускает Nest watch, неbuildи неprisma generate. PrismaService импортирует отсутствующий module. - Impact / actual cost: clean quick start не может успешно скомпилировать этот import; warm checkout с существующим ignored output работает и скрывает prerequisite. Impact unmeasured: fresh-checkout reproduction и потраченное setup time не измерены.
- Why now: backend объявляет самостоятельный local setup; текущие Prisma generator/package scripts позволяют доказать отсутствующий preparation owner до будущего dependency update.
- Minimum change: добавить перед
migrate deployв backend quick start существующийnpm run build— он уже выполняетprisma generate && nest build, как root setup. Не добавлять generator wrapper, postinstall side effect или tracked private client. Если требуется self-contained запуск каждого watch script, отдельно выбрать generation передstart:dev/debug, не дублируя оба решения автоматически. - Guarantees at risk: generation должен остаться до TS consumers; схема, migration SQL и существующая база не должны изменяться при preparation. Build не заменяет
migrate deploy. - Counterarguments / trade-offs: CI и Docker уже готовят client; root README содержит правильную последовательность. Это ограничивает failure до самостоятельного fresh setup, но не исправляет эту публичную инструкцию. Полный build чуть дороже standalone generate, зато использует existing owner без нового tooling.
- Verification or rollback: при будущей правке выполнить документированный setup в отдельном disposable checkout с новой SQLite fixture, убедиться в наличии client и успешном старте; тестовые секреты/данные не из live
.env. Для text-only правки сначала достаточно сверить command chain; runtime proof нужен перед заявлением fresh setup verified. Rollback — revert правки инструкции; generated outputs не коммитить. - Related finding IDs: DEPS-004. Related audit signal: audit 11 — owner подготовки standalone checks.
Prisma v7 reference явно отмечает отсутствие generation в migrate deploy: https://www.prisma.io/docs/orm/v7/prisma-migrate/workflows/development-and-production#production-and-testing-environments.
DEPS-002 — Неиспользуемый ts-loader удерживает альтернативную Webpack toolchain
- Decision: DELETE. Severity: P2. Confidence: High. Effort: S.
- Evidence:
backend/package.json:12,15–18,98–104;backend/nest-cli.json:1–10;backend/package-lock.json:14287–14310,13998–14009; installed versioned mechanism:backend/node_modules/@nestjs/cli/lib/configuration/defaults.js:10–18,backend/node_modules/@nestjs/cli/lib/compiler/helpers/get-builder.js:9–15,backend/node_modules/@nestjs/cli/actions/build.action.js:87–110,153–176,backend/node_modules/@nestjs/cli/package.json:84–118. - Claim: прямые
ts-loader@9.6.2иsource-map-support@0.5.21не обслуживают configured project build/debug/test path. Главный лишний entry — ts-loader, который имеет required Webpack peer. - Current mechanism: Nest defaults = tsc, webpack=false; local config не выбирает builder/webpack, scripts не передают webpack option. CLI импортирует Webpack compiler динамически только для выбранного Webpack branch.
npm explainподтверждает цепь root ts-loader → required Webpack → minimizer-webpack-plugin → Terser → source-map-support. Nest CLI отмечает эти bundler peers optional. Прямых project imports/preloads source-map-support нет;test:debugиспользует ts-node с собственным@cspotcode/source-map-support. - Impact / actual cost: поддерживается unused compiler route и его peer/transitive graph; обновления/compatibility review затрагивают packages, не участвующие в configured compilation. Impact unmeasured: размер, install time, audit surface и число исчезающих transitive nodes после re-resolution не измерены. Terser — известный transitive consumer, а не повод удалить его dependency файлы вручную.
- Why now: установленный Nest 12 сделал Webpack optional/lazy; прежняя прямая dependency больше не требуется обычному tsc builder. Исходное намерение держать резервный compiler не найдено.
- Minimum change: убрать только две direct dev declarations, штатно обновить lockfile в отдельной implementation task. Сохранить Nest CLI, TypeScript, ts-node, tsconfig-paths и любую dependency, которую новый resolved graph всё ещё требует. Не переписывать Nest build на bare tsc: CLI владеет proto assets/watch lifecycle.
- Guarantees at risk: production dist layout, copied proto contracts, watch/debug и source-mapped Jest debugging. Debugger должен продолжать использовать существующий ts-node path.
- Counterarguments / trade-offs: ручной
nest build --webpackпотребует отдельной установки; такого поддерживаемого режима в scripts/config/docs/CI не найдено. Optional peer consumer не равен active project consumer. Транзитивный source-map-support может остаться, если его потребует другой retained package. - Verification or rollback: после будущего удаления — clean
npm ci,npm ls --all,npm explain webpack source-map-support, canonical backendverify+test:e2e, watch/debug на disposable configuration; проверить proto asset path. При сохранении Webpack найти новый retained consumer вместо обещания полного удаления. Rollback — вернуть две declarations и предыдущий lockfile вместе. - Related finding IDs: DEPS-001, DEPS-004.
DEPS-003 — Runtime и SQL-проверки используют разные major SQLite-драйвера
- Decision: SIMPLIFY. Severity: P2. Confidence: High. Effort: M.
- Evidence:
backend/package.json:50–53,144–148;backend/package-lock.json:3762–3784,6284–6294;backend/src/prisma/prisma.service.ts:16–21;backend/test/bank-cards-durability.cjs:24,74–81;backend/test/container-smoke.cjs:34–38,58–64;backend/Dockerfile:21–22,31–35;backend/node_modules/better-sqlite3/package.json:24–36,48–54;backend/node_modules/@prisma/adapter-better-sqlite3/node_modules/better-sqlite3/package.json:18–23,40–46. - Claim: прямой
better-sqlite3нужен реальным checks, но версия 13.0.3 заставляет удерживать второй driver поверх adapter-owned 12.11.1. Это не unused package и не npm peer error. - Current mechanism: adapter 7.10.0 требует
better-sqlite3 ^12.6.0и получает nested 12.11.1; direct exact13 не удовлетворяет этому range. Prisma CLI принимает direct13 как optional peer>=9. Smoke/durability SQL читают root13, а PrismaService работает через nested12. Обе dependency paths production и сохраняются после omit-dev prune. - Impact / actual cost: две packaging/native compatibility boundaries; SQL-level проверка использует другой driver generation, чем application adapter. При этом smoke также реально запускает приложение, поэтому нельзя утверждать отсутствие runtime/native proof вообще. Impact unmeasured: disk/image bytes, затраты install и поведенческая разница bundled SQLite не измерены.
- Why now: несовместимые major уже присутствуют в local lock и production manifest; update direct driver независимо от adapter продолжает закреплять лишнюю boundary.
- Minimum change: сохранить direct dependency, но выбрать exact версию, удовлетворяющую adapter range — текущая runtime 12.11.1 является минимальным кандидатом для консолидации. После штатного lock update подтвердить deduplication. Если нужен именно v13, ждать/выбрать официально поддерживающий её adapter; не принуждать несовместимый adapter override. Разрешение install hook v12 сохраняется; stale разрешение v13 можно удалить только после согласования новой policy.
- Guarantees at risk: SQLite persistence, integrity checks, transaction/rollback, native ABI compatibility, read-only image migrations и финансовая durability. Не менять storage format и migration history ради dependency cleanup.
- Counterarguments / trade-offs: v13 поставляет готовые N-API prebuilds, v12 использует install hook и возможную сборку; это реальное различие, а не две одинаковые lifecycle команды. Но production adapter уже зависит от v12, поэтому direct13 не устраняет v12 install cost. Требование тестировать намеренно разные SQLite generations не найдено; future advisories проверяются отдельно перед version change.
- Verification or rollback: будущая clean installation на целевых OS/architecture; подтвердить один resolved driver и adapter-compatible version; backend
verify, SQLite/e2e, built-image smoke и существующий durability runner с disposable baseline. Не запускать durability на рабочей базе. Rollback — восстановить manifest/lock/policy совместно и пересобрать image; database rollback не требуется при чисто dependency/config change без миграций. - Related finding IDs: DEPS-002.
DEPS-004 — Debug entry point теряет development mode
- Decision: FIX. Severity: P3. Confidence: High. Effort: S.
- Evidence:
backend/package.json:16–17;backend/.env.example:1–10;backend/src/config/swagger.config.ts:1–3;backend/src/main.ts:49–57;backend/src/modules/auth/presentation/auth.controller.ts:131–136;backend/src/config/env.validation.ts:9–19. - Claim: при отсутствии унаследованного
NODE_ENVодинаковые dev/debug watch profiles включают разные mode-sensitive policies. Это подтверждённое различие конфигурации, не доказанный отказ auth в конкретном browser. - Current mechanism: start:dev задаёт NODE_ENV=development, start:debug только
--debug --watch --path tsconfig.dev.json. Env example не содержит NODE_ENV; Environment validator не нормализует это поле. Swagger открывается только при точном development, cookie Secure выключается только при точном development, log fallback пишет development даже при undefined. - Impact / actual cost: debugger не воспроизводит development HTTP configuration; Swagger отсутствует, cookies получают иной flag. Поведение Secure cookies на localhost зависит от client, его отказ не заявляется. Impact unmeasured: runtime debugger/browser scenario не запускался.
- Why now: исправляется одной строкой existing entry point без env framework и изменения production defaults.
- Minimum change: добавить
NODE_ENV=developmentв start:debug тем же способом, что уже используется в start:dev. Не задавать global permissive default и не ослаблять production cookie/Swagger policy. - Guarantees at risk: production Secure cookies и отключённый Swagger должны сохраниться; debug остаётся отдельным осознанным local launch.
- Counterarguments / trade-offs: внешняя shell/.env может уже задавать NODE_ENV — тогда расхождения нет. Fresh documented env такого prerequisite не устанавливает. Настройка только launch script намеренно меньше, чем новая unified environment abstraction.
- Verification or rollback: после будущей правки сравнить dev/debug launch configuration на disposable env, убедиться в development Swagger; существующая production-mode проверка должна сохранить закрытый Swagger/Secure cookie. Rollback — revert одной script value.
- Related finding IDs: DEPS-001, DEPS-002.
5. DELETE / SIMPLIFY / KEEP / INVESTIGATE
| Decision | Объект | Основание / сохраняемая гарантия |
|---|---|---|
| DELETE | Direct ts-loader и source-map-support — DEPS-002 | tsc builder остаётся; transitive packages удаляются только штатным dependency resolution |
| SIMPLIFY | Две версии better-sqlite3 — DEPS-003 | Сохранить прямой SQL consumer и adapter-supported native driver; consolidation после SQLite/image/durability proof |
| FIX | Fresh quick start — DEPS-001 | Explicit build/generate до import, без committed private outputs и install hooks |
| FIX | Debug NODE_ENV — DEPS-004 | Local development mode, без изменения fail-closed production policy |
| KEEP | Prisma CLI production dependency | Image и Compose migration запускают node_modules/prisma/build/index.js; перенос в dev сломает omit-dev image |
| KEEP | Recharts/react-is, reflect-metadata/RxJS/passport peers | Dynamic/framework consumers; отсутствие business import не доказательство ненужности |
| KEEP | Bcrypt, native SQLite, proto loaders и TLS CA option | Auth, persistence, precision/field presence, реальная сеть/сертификаты; stdlib replacement не доказан эквивалентным |
| KEEP | OpenAPI snapshot и generated TS | Независимый consumer repo с offline local contract/type check |
| KEEP | Отдельные compiler/test/Sonar profiles | Разные runtime/module/analyzer environments и fixtures, не искусственно дублирующий один compiler |
| KEEP | Независимые lockfiles/release/commitlint configs | Каждый repo устанавливается и выпускается без соседних checkout |
| KEEP | Restrictive allowScripts и exact versions | Не давать wildcard разрешения ради исчезновения lifecycle warnings |
| INVESTIGATE | Specs OpenSpec CLI ownership | README допускает внешнюю незакреплённую CLI; local npm ci не обещает её установку. Pin только при требовании reproducible native workflow |
| INVESTIGATE | Native/image footprint и Sonar projection | Фактические artifacts/server version не проверены; размер и ложные diagnostics нельзя выводить из количества packages |
Complexity-pass в формате ponytail-audit
delete:убрать direct ts-loader, активирующий невыбранную Webpack-ветку; replacement: существующий Nest tsc builder. [backend/package.json:101,backend/nest-cli.json]shrink:согласовать direct better-sqlite3 с adapter-supported runtime version; replacement: один совместимый driver для приложения и SQL checks. [backend/package.json:50–53,backend/package-lock.json:3762–3784]delete:убрать direct source-map-support declaration; replacement: ничего в project code, необходимые transitive consumers сохраняет npm. [backend/package.json:98]
net: -2 manifest lines, -2 direct deps possible. Число относится только к двум предложенным direct declaration removals. Lockfile/transitive line savings не измерены. Consolidation driver может убрать одну version instance, но не сам required direct dependency; clean resolution и compatibility proof ещё нужны.
6. Cost & benefit
| Действие | Класс выгоды | Фактическое измерение | Обязательные границы |
|---|---|---|---|
| DEPS-001: explicit preparation | Setup reliability, cognitive load/agent navigation | Missing prerequisite доказан статически; setup minutes not measured | Fresh client до TS import; безопасная disposable DB; не трогать существующие secrets |
| DEPS-002: remove unused compiler entries | Dependency maintenance, потенциальные install/CI cost | 2 direct entries; Webpack peer chain доказана; minutes/bytes/closure reduction not measured | Nest tsc, assets, watch/debug, existing test transforms сохранить |
| DEPS-003: driver alignment | Runtime packaging, native maintenance, consistent SQL verification | 2 resolved versions установлены; image bytes/runtime improvement not measured | SQLite integrity/durability/transactions, ABI и migration CLI сохранить |
| DEPS-004: debug mode | Local troubleshooting/cognitive load | Различие launch config доказано; recovery time not measured | Production cookie/Swagger policy не ослаблять |
Не обещаются проценты ускорения, bundle reduction или денежная экономия. Package count не равен bundle size: dev dependencies frontend отсутствуют в nginx runtime, а platform lock entries не все устанавливаются на одном host. Общие пакеты между repos не означают двойной runtime bundle.
7. Top actions и план безопасной консолидации
Quick wins
- DEPS-001: исправить самостоятельный backend quick start существующим preparation command; сверить его с tracked generator/import chain. Самая дешёвая правка с непосредственной setup value.
- DEPS-002: удалить direct ts-loader/source-map-support в отдельной dependency task; штатно обновить lockfile, затем clean-install/peer/compiler/assets checks. Не удалять вручную Webpack nodes из node_modules/lockfile.
- DEPS-004: согласовать debug launch с start:dev одной script value, сохранив production mode.
Решение, требующее тестового подтверждения
- DEPS-003: выбрать adapter-compatible SQLite driver version, clean resolve, затем SQLite/image/durability proof. Новая ADR нужна только если принято намеренно сохранять разные driver generations или менять runtime DB packaging; для обычного version alignment достаточно dependency diff и regression evidence.
Минимальная последовательность future implementation: один связанный manifest/config diff → canonical lockfile update штатным npm → чистая установка на нужной платформе → npm ls --all → соответствующие existing type/build/tests → image/durability только для native change. После dependency changes выполнить repo-required npm audit и отдельно triage, не принимать --force/--legacy-peer-deps. Эти операции не выполнялись в аудите.
Не предлагается миграция в monorepo, центральный dependency manifest, новый env parser, custom unused-dependency script, общий test runner или объединение ESLint/graph/contract validators.
8. Cross-audit signals
- Audit 11:
backend/package.json:34,.gitea/workflows/verify.yml:83–89— preparation ownership standalone verify/CI; здесь зафиксирован fresh local setup, execution repetition не пересчитывался. - Audit 07:
frontend/src/shared/api/client.ts:15–18,backend/src/integrations/tbank/tbank.client.ts:49–54— согласование end-to-end timeout/retry budget; одинаковые значения не требуют shared constant автоматически. - Audit 07/15:
frontend/src/app/ui/App.tsx:13–19и.ai/conventions/data.md:70–74— focus-refetch behavior отличается от описанной policy; не включено в dependency findings. - Audit 13:
backend/package.json:107–121,frontend/package.json:118–126,docs/package.json:24–33,backend/.gitea/workflows/verify.yml:64–65— overrides/advisory exception требуют отдельного security rationale; vuln scan не выполнялся. - Audit 15:
specs/README.md:28–31,specs/package.json:15–21— ownership/version of external OpenSpec CLI; SDD lifecycle и CLI installation state здесь не исследованы.
9. Open questions / verification plan
| Вопрос, меняющий решение | Самый дешёвый proof | Что изменит |
|---|---|---|
| Есть ли поддерживаемый backend Webpack consumer вне tracked scripts/config/CI? | Уточнить у owner конкретную command/config; project search не нашёл | При реальном consumer сохранить ts-loader либо оформить его явный режим вместо DELETE |
| Почему direct SQLite v13 нужна при adapter v12? | Проверить необходимость v13 API в двух SQL consumers и существующим image/durability proof на compatible v12 | Если специфичный v13 contract нужен, DEPS-003 станет INVESTIGATE до официального adapter support |
| Сколько transitive nodes/bytes действительно исчезнет после DEPS-002/003? | Сравнить новый штатный lock graph и image digest/artifact в будущей dependency task | Уточнит benefit; не меняет доказанный unused route, не требует нового profiler |
| Работает ли самостоятельный свежий setup после исправления инструкции? | Отдельный disposable checkout/SQLite fixture без inherited generated output | Позволит заменить статический inference DEPS-001 на runtime-verified statement |
| Нужна ли воспроизводимая native OpenSpec workflow на clean host? | Уточнить requirement и получить фактический openspec --version owner среды |
Только тогда решить local pin; application setup от этого не зависит |
| По-прежнему ли Sonar требует отдельный старый TS profile? | Проверить version существующего server analyzer / один уже выполненный scan log | При современном analyzer можно пересмотреть profile, сейчас KEEP |
Открытые вопросы не являются блокерами read-only отчёта. Ни установка новых tools, ни runtime database access для завершения аудита не нужны.
10. Проверка итогового артефакта
Единственная запись — audit-results/12-dependencies-and-configuration-report.md, вне четырёх самостоятельных repos и вне root allowlist. Выполнена semantic сверка: scope, точные SHA/строки, все четыре finding fields, counterarguments, preserved invariants, отсутствие выдуманных измерений, четыре специальные matrices/registers и consolidation table.
- Повторные
git status --short --branchиgit rev-parse HEADпяти repos подтвердили чистые working trees и те же SHA, что в metadata. - В пяти repos
git diff --checkиgit diff --cached --checkзавершились с exit 0 без diagnostics; staged/unstaged tracked изменений нет. git diff --no-index --check /dev/null audit-results/12-dependencies-and-configuration-report.mdзавершился с exit 0 без diagnostics: проверен сам новый ignored отчёт, а не только пустой tracked diff.git status --short --ignored -- audit-results/12-dependencies-and-configuration-report.mdпоказал!! audit-results/: отчёт сохраняется локально и не добавлен в root tracking.- Application tests/build/clean install не выполнялись; успешная проверка артефакта не подменяет future regression proof рекомендаций.
Consolidation table
| ID | Decision | Severity | Confidence | Repo | Files | One-line impact | Effort | Related IDs |
|---|---|---|---|---|---|---|---|---|
| DEPS-001 | FIX | P2 | High | backend | README.md; package.json; prisma/schema.prisma; src/prisma/prisma.service.ts | Самостоятельный fresh quick start пропускает generated client prerequisite | S | DEPS-004 |
| DEPS-002 | DELETE | P2 | High | backend | package.json; package-lock.json; nest-cli.json | Неиспользуемый ts-loader удерживает Webpack peer chain и лишние direct declarations | S | DEPS-001, DEPS-004 |
| DEPS-003 | SIMPLIFY | P2 | High | backend | package.json; package-lock.json; test/container-smoke.cjs; test/bank-cards-durability.cjs | Runtime и SQL checks удерживают две major-версии SQLite-драйвера | M | DEPS-002 |
| DEPS-004 | FIX | P3 | High | backend | package.json; .env.example; src/main.ts; src/config/swagger.config.ts; src/modules/auth/presentation/auth.controller.ts | Debug launch без NODE_ENV development выбирает другую HTTP mode policy | S | DEPS-001, DEPS-002 |