Five Dependabot major-version PRs were reviewed and deferred rather than merged (#31, #33, #32, #28, #17). None of them can be taken as-is: each needs a coordinated change that Dependabot cannot make on its own. This issue records the specific blocker for each so the analysis does not have to be redone.
Each PR was told @dependabot ignore this major version, so it will not be reopened for that major line. To pick one up, comment @dependabot unignore <dependency> on any Dependabot PR, or just do the upgrade by hand.
The six safe PRs from the same batch were merged in 4d25235 (actions/checkout v7, pyyaml, anthropic, qrcode, react-router-dom 7, pyarrow 24).
#31 — Vite 5 → 8
Cannot be merged alone; two hard constraints in the current tree:
@vitejs/plugin-react@4.7.0 declares peerDependencies.vite = "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" — 8 is outside the range.
vitest@2.1.9 has vite: "^5.0.0" in its own dependencies, not peers.
So the upgrade is really a four-package job: vite + @vitejs/plugin-react + vitest + @vitest/coverage-v8, landed together, with npm run build and npm run test re-verified afterwards.
#33 — ESLint 8 → 10
The repo lints via .eslintrc.json (extends: ["eslint:recommended", "plugin:react/recommended", "plugin:react-hooks/recommended"]). ESLint 9 made flat config the default and ESLint 10 removed eslintrc support entirely, along with string-form extends.
npm run lint -- --max-warnings=0 runs in CI, so merging this turns CI red immediately. Prerequisite: port the config to eslint.config.js, keeping the current rule set (react/prop-types off, react/react-in-jsx-scope off, the ^_ unused-args pattern, no-console allowing warn/error, and the test-file globals override).
#32 — Recharts 2 → 3
Breaking API changes, plus the lockfile in the PR shows v3 pulls @reduxjs/toolkit into the dependency tree — a real bundle-size cost for a dashboard that already warns about a 1.09 MB chunk.
Mitigating factor: the blast radius is one file, frontend/src/components/StatisticsPanel.jsx (plus a mock in src/test/setup.js). This is the most tractable of the five, but it is a deliberate migration, not an automatic bump.
#28 — i18next 23 → 26
react-i18next stays at 14.1.3 in this PR. Its peer range is i18next: ">= 23.2.3" — open-ended, so npm will not error on the mismatch. That is exactly what makes it risky: it installs cleanly and fails at runtime. Upgrading i18next needs react-i18next 15+ in the same change.
#17 — pandas 2.1.4 → 3.0.2
Highest risk of the five, and the one to be most careful with.
The backend has 8 modules importing pandas. A scan for removed APIs (applymap, iteritems, inplace=True, is_categorical_dtype, swapaxes) found no hits, so this would not fail loudly on merge. The danger is the opposite: pandas 3 turns on Copy-on-Write by default and switches string columns to the str dtype. Both are silent semantic changes — they do not raise, they just produce different numbers. In a health-data pipeline that is the worst possible failure mode.
Taking this needs a real evaluation pass over backend/data_readers/ with before/after value comparison, not a green test suite.
Side note: the pinned versions do not match what anyone actually runs
While reviewing these, the local dev environment was found to be well off the declared pins:
backend/requirements.txt |
installed locally |
pandas==2.1.4 |
2.3.3 |
pyarrow==14.0.2 (now 24.0.0) |
22.0.0 |
anthropic>=0.96.0 (now >=0.97.0) |
0.46.0 — below the floor |
The anthropic row is the interesting one: the full suite passes on 0.46.0 despite the manifest requiring 0.96+, which means the SDK is mocked throughout the tests. So "tests pass locally" and "CI is green" are not statements about the same dependency set, and neither is strong evidence for an upgrade decision.
Side note: pyarrow appears to be unused
pyarrow is a hard dependency but nothing references it — no import pyarrow, no read_parquet/to_parquet, no .parquet files anywhere in the tree. The only mention is a comment in backend/config.py:172. #17's sibling PR bumping it to 24.0.0 was merged on the grounds that it cannot break what is never executed, but the dependency itself is probably droppable, which would shrink every install and Docker image.
Five Dependabot major-version PRs were reviewed and deferred rather than merged (#31, #33, #32, #28, #17). None of them can be taken as-is: each needs a coordinated change that Dependabot cannot make on its own. This issue records the specific blocker for each so the analysis does not have to be redone.
Each PR was told
@dependabot ignore this major version, so it will not be reopened for that major line. To pick one up, comment@dependabot unignore <dependency>on any Dependabot PR, or just do the upgrade by hand.The six safe PRs from the same batch were merged in
4d25235(actions/checkout v7, pyyaml, anthropic, qrcode, react-router-dom 7, pyarrow 24).#31 — Vite 5 → 8
Cannot be merged alone; two hard constraints in the current tree:
@vitejs/plugin-react@4.7.0declarespeerDependencies.vite = "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"— 8 is outside the range.vitest@2.1.9hasvite: "^5.0.0"in its own dependencies, not peers.So the upgrade is really a four-package job:
vite+@vitejs/plugin-react+vitest+@vitest/coverage-v8, landed together, withnpm run buildandnpm run testre-verified afterwards.#33 — ESLint 8 → 10
The repo lints via
.eslintrc.json(extends: ["eslint:recommended", "plugin:react/recommended", "plugin:react-hooks/recommended"]). ESLint 9 made flat config the default and ESLint 10 removed eslintrc support entirely, along with string-formextends.npm run lint -- --max-warnings=0runs in CI, so merging this turns CI red immediately. Prerequisite: port the config toeslint.config.js, keeping the current rule set (react/prop-typesoff,react/react-in-jsx-scopeoff, the^_unused-args pattern,no-consoleallowing warn/error, and the test-file globals override).#32 — Recharts 2 → 3
Breaking API changes, plus the lockfile in the PR shows v3 pulls
@reduxjs/toolkitinto the dependency tree — a real bundle-size cost for a dashboard that already warns about a 1.09 MB chunk.Mitigating factor: the blast radius is one file,
frontend/src/components/StatisticsPanel.jsx(plus a mock insrc/test/setup.js). This is the most tractable of the five, but it is a deliberate migration, not an automatic bump.#28 — i18next 23 → 26
react-i18nextstays at 14.1.3 in this PR. Its peer range isi18next: ">= 23.2.3"— open-ended, so npm will not error on the mismatch. That is exactly what makes it risky: it installs cleanly and fails at runtime. Upgrading i18next needs react-i18next 15+ in the same change.#17 — pandas 2.1.4 → 3.0.2
Highest risk of the five, and the one to be most careful with.
The backend has 8 modules importing pandas. A scan for removed APIs (
applymap,iteritems,inplace=True,is_categorical_dtype,swapaxes) found no hits, so this would not fail loudly on merge. The danger is the opposite: pandas 3 turns on Copy-on-Write by default and switches string columns to thestrdtype. Both are silent semantic changes — they do not raise, they just produce different numbers. In a health-data pipeline that is the worst possible failure mode.Taking this needs a real evaluation pass over
backend/data_readers/with before/after value comparison, not a green test suite.Side note: the pinned versions do not match what anyone actually runs
While reviewing these, the local dev environment was found to be well off the declared pins:
backend/requirements.txtpandas==2.1.4pyarrow==14.0.2(now 24.0.0)anthropic>=0.96.0(now>=0.97.0)The
anthropicrow is the interesting one: the full suite passes on 0.46.0 despite the manifest requiring 0.96+, which means the SDK is mocked throughout the tests. So "tests pass locally" and "CI is green" are not statements about the same dependency set, and neither is strong evidence for an upgrade decision.Side note: pyarrow appears to be unused
pyarrowis a hard dependency but nothing references it — noimport pyarrow, noread_parquet/to_parquet, no.parquetfiles anywhere in the tree. The only mention is a comment inbackend/config.py:172. #17's sibling PR bumping it to 24.0.0 was merged on the grounds that it cannot break what is never executed, but the dependency itself is probably droppable, which would shrink every install and Docker image.