Skip to content

Bump the backend-dependencies group in /backend with 10 updates - #5

Open
dependabot[bot] wants to merge 10 commits into
mainfrom
dependabot/pip/backend/backend-dependencies-644e275eb8
Open

Bump the backend-dependencies group in /backend with 10 updates#5
dependabot[bot] wants to merge 10 commits into
mainfrom
dependabot/pip/backend/backend-dependencies-644e275eb8

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 10, 2026

Copy link
Copy Markdown

Updates the requirements on fastapi, uvicorn, sqlalchemy, alembic, pydantic, python-multipart, jinja2, pytest, httpx and ruff to permit the latest version.
Updates fastapi to 0.141.1

Release notes

Sourced from fastapi's releases.

0.141.1

Fixes

  • 🐛 Fix support for background tasks and headers from dependencies in app.frontend(). PR #16105 by @​tiangolo.

Docs

Commits
  • 95f8322 🔖 Release version 0.141.1 (#16106)
  • f137944 📝 Update release notes
  • d623544 🐛 Fix support for background tasks and headers from dependencies in `app.fron...
  • 1d211b9 📝 Update release notes
  • 8a1f876 📝 Document FASTAPI_ENV in FastAPI CLI guide (#16104)
  • c7e7b65 🔖 Release version 0.141.0 (#16103)
  • 6bceb84 📝 Update release notes
  • 5429fed ✨ Add app.frontend(check_dir="auto"), to make local development more conven...
  • 628663f 🔖 Release version 0.140.13 (#16096)
  • 0b54fd0 📝 Update release notes
  • Additional commits viewable in compare view

Updates uvicorn to 0.52.1

Release notes

Sourced from uvicorn's releases.

Version 0.52.1

Fixed

  • Complete the closing handshake on server-initiated WebSocket closes in the websockets-sansio and wsproto implementations, waiting for the client's close reply with a 10 second timeout instead of resetting the connection (#3053)
  • Add missing write flow control to the websockets-sansio implementation, preventing data truncation on server-initiated closes with large in-flight payloads (#3048)
  • Handle connection loss while a WebSocket write is waiting on backpressure (#3050)
  • Remove duplicate Content-Type and Content-Length headers from WebSocket denial responses on the websockets-sansio implementation, and deliver non-UTF-8 denial bodies intact (#3041)

Full Changelog: Kludex/uvicorn@0.52.0...0.52.1

Changelog

Sourced from uvicorn's changelog.

0.52.1 (August 1, 2026)

Fixed

  • Complete the closing handshake on server-initiated WebSocket closes in the websockets-sansio and wsproto implementations, waiting for the client's close reply with a 10 second timeout instead of resetting the connection (#3053)
  • Add missing write flow control to the websockets-sansio implementation, preventing data truncation on server-initiated closes with large in-flight payloads (#3048)
  • Handle connection loss while a WebSocket write is waiting on backpressure (#3050)
  • Remove duplicate Content-Type and Content-Length headers from WebSocket denial responses on the websockets-sansio implementation, and deliver non-UTF-8 denial bodies intact (#3041)

0.52.0 (July 29, 2026)

This release adds an experimental HTTP/1.1 implementation backed by zttp, a sans-IO HTTP parser I've been developing on the side: a core written in Zig, with bindings to Python. It has been running under a fuzzer for some weeks now, and has been through multiple rounds of security auditing.

It is still experimental, so don't put it in front of production traffic yet. Try it with --http zttp, and please send any feedback to the issue tracker.

Added

  • Add an experimental zttp HTTP/1.1 implementation, selectable with --http zttp (#2979)

Fixed

  • Keep non-ASCII WebSocket request headers intact with websockets 17.0, which encodes them with ISO-8859-1 (#3036)

0.51.0 (July 8, 2026)

Added

  • Restart workers one at a time on SIGHUP, bringing each replacement up before retiring the old worker, so reloads no longer drop requests (#3025)

Removed

  • Remove colorama from the standard extra (#3027)

0.50.2 (July 6, 2026)

Fixed

  • Require websockets>=13.0, which the default websockets-sansio implementation needs (#3021)

0.50.1 (July 6, 2026)

Fixed

  • Split comma-separated Sec-WebSocket-Protocol values in the websockets-sansio implementation (#3019)

0.50.0 (July 4, 2026)

If you use WebSockets, note that --ws auto now picks the websockets-sansio implementation. You shouldn't need it, but you can pin --ws websockets to get the deprecated legacy one back.

Changed

... (truncated)

Commits
  • ee8e45c Version 0.52.1 (#3056)
  • b57926d Remove duplicate content headers from WebSocket denial responses on websocket...
  • 49de1b9 chore(deps): bump pymdown-extensions from 10.21.3 to 11.0 (#3042)
  • 2f3fa3a Complete server-initiated closes in SansIO WebSocket protocols (#3053)
  • 8c59d55 chore(deps): bump the github-actions group with 5 updates (#3054)
  • e148451 Handle connection loss during WebSocket write backpressure (#3050)
  • e16a69b Add missing write flow control to websockets-sansio (#3048)
  • ef1dd44 Fold the zttp-only tests back into the HTTP test suite (#3046)
  • 8f1b884 Version 0.52.0 (#3044)
  • f6833db Add experimental zttp HTTP/1.1 protocol (#2979)
  • Additional commits viewable in compare view

Updates sqlalchemy to 2.0.51

Release notes

Sourced from sqlalchemy's releases.

2.0.51

Released: June 15, 2026

orm

  • [orm] [bug] Fixed issue where _orm.subqueryload() combined with PropComparator.of_type() and PropComparator.and_() would silently drop the additional filter criteria, causing all related objects to be loaded instead of only those matching the filter. The LoaderCriteriaOption was being constructed against the base entity rather than the effective entity indicated by PropComparator.of_type(). Pull request courtesy Arya Rizky.

    References: #13207

  • [orm] [bug] Fixed bug where a failure during tpc_prepare() within _orm.Session.commit() for a two-phase session would raise IllegalStateChangeError instead of the original database exception. The internal _prepare_impl() method's error handler was unable to invoke _orm.SessionTransaction.rollback() due to a state-change guard, preventing proper cleanup and masking the underlying error.

    References: #13356

engine

  • [engine] [bug] Fixed issue where Result.freeze() would lose track of ambiguous column names present in the original CursorResult, causing key-based access on the thawed result to silently return a value instead of raising InvalidRequestError. The SimpleResultMetaData now accepts and propagates ambiguous key information so that frozen, thawed, and pickled results raise consistently for duplicate column names. Pull request courtesy Saurabh Kohli.

    References: #9427

sql

  • [sql] [bug] Fixed issue where _sql.StatementLambdaElement would proxy attribute access through the cached "expected" expression rather than the resolved expression, causing stale closure-bound parameter values to be used when a lambda statement was extended with non-lambda criteria such as an additional .where() clause. Courtesy cjc0013.

    References: #10827

... (truncated)

Commits

Updates alembic to 1.19.0

Release notes

Sourced from alembic's releases.

1.19.0

Released: August 4, 2026

changed

  • [changed] [installation] Environmental updates:

    -   Trove classifiers now include Python 3.15 which is now part of CI
        integration
    
    • Python 3.14 is also added to trove classifiers which had been previously omitted

    • Implemented PEP 604 style unions in type annotations

feature

  • [feature] [autogenerate] Autogenerate now detects the addition and removal of named CHECK constraints, as part of the default autogenerate behavior. Detection is name-based only; a constraint whose name is unchanged is presumed equivalent regardless of its expression text, as reliably normalizing SQL expressions across backends for comparison purposes is not generally feasible. This behavior is implemented as a plugin named alembic.autogenerate.checkconstraint_byname, and may be disabled if not desired by excluding it from the EnvironmentContext.configure.autogenerate_plugins list. Pull request courtesy Francois van Kempen.

    References: #508

bug

  • [bug] [commands] Fixed inconsistency where running stamp or downgrade to base in offline (--sql) mode would emit a DROP TABLE alembic_version statement, while the same operations in online mode never drop the version table. Offline mode no longer emits this DROP, matching online behavior. The version table continues to be created when it does not exist; only the spurious offline-only drop has been removed. Pull request courtesy imurodl.

    References: #1822

Commits

Updates pydantic to 2.13.4

Release notes

Sourced from pydantic's releases.

v2.13.4 2026-05-06

v2.13.4 (2026-05-06)

What's Changed

Packaging

Fixes

Full Changelog: pydantic/pydantic@v2.13.3...v2.13.4

Changelog

Sourced from pydantic's changelog.

v2.13.4 (2026-05-06)

GitHub release

What's Changed

Packaging

Fixes

v2.13.3 (2026-04-20)

GitHub release

What's Changed

Fixes

v2.13.2 (2026-04-17)

GitHub release

What's Changed

Fixes

  • Fix ValidationInfo.field_name missing with model_validate_json() by @​Viicos in #13084

v2.13.1 (2026-04-15)

GitHub release

What's Changed

Fixes

v2.13.0 (2026-04-13)

GitHub release

The highlights of the v2.13 release are available in the blog post.

... (truncated)

Commits
  • cf67d4b Fix linting
  • f0d8a21 Prepare release v2.13.4
  • 5e3fe1d Check for pydantic tag pattern in CI
  • 7f9edcc Document tagging conventions
  • b46a0c9 Adapt pydantic-core linker flags on macOS
  • 50629c8 Update to PyPy 7.3.22
  • 8522ebb Preserve RootModel core metadata
  • a37f3af Adapt MISSING sentinel test to work with unreleased typing_extensions ver...
  • 909259a Remove Logfire example in documentation
  • 2c4174c Bump libc from 0.2.155 to 0.2.185
  • Additional commits viewable in compare view

Updates python-multipart to 0.0.32

Release notes

Sourced from python-multipart's releases.

Version 0.0.32

What's Changed

Full Changelog: Kludex/python-multipart@0.0.31...0.0.32

Changelog

Sourced from python-multipart's changelog.

0.0.32 (2026-06-04)

  • Speed up partial-boundary scanning for CR/LF-dense part data #300.

0.0.31 (2026-06-04)

  • Speed up multipart header parsing and callback dispatch #295.
  • Bound header field name size before validating #296.
  • Validate Content-Length is non-negative in parse_form #297.

0.0.30 (2026-05-31)

  • Parse application/x-www-form-urlencoded bodies per the WHATWG URL standard, treating only & as a field separator #290.
  • Ignore RFC 2231/5987 extended parameters (name*, filename*) in parse_options_header, keeping the plain parameter authoritative per RFC 7578 §4.2 #291.

0.0.29 (2026-05-17)

  • Handle malformed RFC 2231 continuations in parse_options_header #270.

0.0.28 (2026-05-10)

  • Speed up partial-boundary tail scan via bytes.find #281.
  • Cap multipart boundary length at 256 bytes #282.

0.0.27 (2026-04-27)

  • Add multipart header limits #267.
  • Pass parse offsets via constructors #268.

0.0.26 (2026-04-10)

  • Skip preamble before the first multipart boundary more efficiently #262.
  • Silently discard epilogue data after the closing multipart boundary #259.

0.0.25 (2026-04-10)

  • Add MIME content type info to File #143.
  • Handle CTE values case-insensitively #258.
  • Remove custom FormParser classes #257.
  • Add UPLOAD_DELETE_TMP to FormParser config #254.
  • Emit field_end for trailing bare field names on finalize #230.
  • Handle multipart headers case-insensitively #252.
  • Apply Apache-2.0 properly #247.

0.0.24 (2026-04-05)

  • Validate chunk_size in parse_form() #244.

0.0.23 (2026-04-05)

... (truncated)

Commits
  • 238ead6 Version 0.0.32 (#302)
  • 8672979 Replace per-byte partial-boundary scan with rfind lookbehind (#300)
  • 8190779 Bump the python-packages group with 7 updates (#301)
  • 0d3c086 Use uv package ecosystem for Dependabot (#299)
  • 4cffc68 Version 0.0.31 (#298)
  • c814948 Reject negative Content-Length in parse_form (#297)
  • 6b837d4 Bound header field name size before validating (#296)
  • e0c4f9d Bump the github-actions group with 3 updates (#294)
  • b8a01bb Bump the python-packages group with 3 updates (#293)
  • 6732164 Speed up multipart header parsing and callback dispatch (#295)
  • Additional commits viewable in compare view

Updates jinja2 to 3.1.6

Release notes

Sourced from jinja2's releases.

3.1.6

This is the Jinja 3.1.6 security release, which fixes security issues but does not otherwise change behavior and should not result in breaking changes compared to the latest feature release.

PyPI: https://pypi.org/project/Jinja2/3.1.6/ Changes: https://jinja.palletsprojects.com/en/stable/changes/#version-3-1-6

  • The |attr filter does not bypass the environment's attribute lookup, allowing the sandbox to apply its checks. GHSA-cpwx-vrp4-4pq7
Changelog

Sourced from jinja2's changelog.

Version 3.1.6

Released 2025-03-05

  • The |attr filter does not bypass the environment's attribute lookup, allowing the sandbox to apply its checks. :ghsa:cpwx-vrp4-4pq7

Version 3.1.5

Released 2024-12-21

  • The sandboxed environment handles indirect calls to str.format, such as by passing a stored reference to a filter that calls its argument. :ghsa:q2x7-8rv6-6q7h
  • Escape template name before formatting it into error messages, to avoid issues with names that contain f-string syntax. :issue:1792, :ghsa:gmj6-6f8f-6699
  • Sandbox does not allow clear and pop on known mutable sequence types. :issue:2032
  • Calling sync render for an async template uses asyncio.run. :pr:1952
  • Avoid unclosed auto_aiter warnings. :pr:1960
  • Return an aclose-able AsyncGenerator from Template.generate_async. :pr:1960
  • Avoid leaving root_render_func() unclosed in Template.generate_async. :pr:1960
  • Avoid leaving async generators unclosed in blocks, includes and extends. :pr:1960
  • The runtime uses the correct concat function for the current environment when calling block references. :issue:1701
  • Make |unique async-aware, allowing it to be used after another async-aware filter. :issue:1781
  • |int filter handles OverflowError from scientific notation. :issue:1921
  • Make compiling deterministic for tuple unpacking in a {% set ... %} call. :issue:2021
  • Fix dunder protocol (copy/pickle/etc) interaction with Undefined objects. :issue:2025
  • Fix copy/pickle support for the internal missing object. :issue:2027
  • Environment.overlay(enable_async) is applied correctly. :pr:2061
  • The error message from FileSystemLoader includes the paths that were searched. :issue:1661
  • PackageLoader shows a clearer error message when the package does not contain the templates directory. :issue:1705
  • Improve annotations for methods returning copies. :pr:1880
  • urlize does not add mailto: to values like @a@b. :pr:1870

... (truncated)

Commits

Updates pytest to 9.1.1

Release notes

Sourced from pytest's releases.

9.1.1

pytest 9.1.1 (2026-06-19)

Bug fixes

  • #14220: Fixed a logic bug in pytest.RaisesGroup which would might cause it to display incorrect "It matches FooError() which was paired with BarError" messages.
  • #14591: Fixed a regression in pytest 9.1.0 which caused overriding a parametrized fixture with an indirect @​pytest.mark.parametrize to fail with "duplicate parametrization of '<fixture name>'".
  • #14606: Fixed list-item typing errors from mypy in @pytest.mark.parametrize <pytest.mark.parametrize ref> argvalues parameter.
  • #14608: Fixed a regression in pytest 9.1.0 where conftest.py files located in <invocation dir>/test* were no longer loaded as initial conftests when invoked without arguments. This could cause certain hooks (like pytest_addoption) in these files to not fire.
Commits
  • cf470ec Prepare release version 9.1.1
  • e0c8ce6 Merge pull request #14625 from pytest-dev/patchback/backports/9.1.x/a07c31a97...
  • 1b82d16 Merge pull request #14624 from pytest-dev/patchback/backports/9.1.x/b375b79ec...
  • 501c4bc Merge pull request #14596 from bluetech/doc-classmethod
  • b61f588 Merge pull request #14622 from chrisburr/fix-14608-initial-conftest-test-subdir
  • 9a567e0 [automated] Update plugin list (#14617) (#14618)
  • ef8b299 Merge pull request #14620 from pytest-dev/patchback/backports/9.1.x/680f9f3ed...
  • 66abd07 Merge pull request #14220 from bysiber/fix-stale-iexp-raisesgroup
  • 79fbf93 Merge pull request #14612 from pytest-dev/patchback/backports/9.1.x/974ed48b6...
  • 0d312eb Merge pull request #14611 from bluetech/parametrize-argvalues-typing
  • Additional commits viewable in compare view

Updates httpx to 0.28.1

Release notes

Sourced from httpx's releases.

Version 0.28.1

0.28.1 (6th December, 2024)

  • Fix SSL case where verify=False together with client side certificates.
Changelog

Sourced from httpx's changelog.

0.28.1 (6th December, 2024)

  • Fix SSL case where verify=False together with client side certificates.

0.28.0 (28th November, 2024)

Be aware that the default JSON request bodies now use a more compact representation. This is generally considered a prefered style, tho may require updates to test suites.

The 0.28 release includes a limited set of deprecations...

Deprecations:

We are working towards a simplified SSL configuration API.

For users of the standard verify=True or verify=False cases, or verify=<ssl_context> case this should require no changes. The following cases have been deprecated...

  • The verify argument as a string argument is now deprecated and will raise warnings.
  • The cert argument is now deprecated and will raise warnings.

Our revised SSL documentation covers how to implement the same behaviour with a more constrained API.

The following changes are also included:

  • The deprecated proxies argument has now been removed.
  • The deprecated app argument has now been removed.
  • JSON request bodies use a compact representation. (#3363)
  • Review URL percent escape sets, based on WHATWG spec. (#3371, #3373)
  • Ensure certifi and httpcore are only imported if required. (#3377)
  • Treat socks5h as a valid proxy scheme. (#3178)
  • Cleanup Request() method signature in line with client.request() and httpx.request(). (#3378)
  • Bugfix: When passing params={}, always strictly update rather than merge with an existing querystring. (#3364)

0.27.2 (27th August, 2024)

Fixed

  • Reintroduced supposedly-private URLTypes shortcut. (#2673)

0.27.1 (27th August, 2024)

Added

  • Support for zstd content decoding using the python zstandard package is added. Installable using httpx[zstd]. (#3139)

Fixed

  • Improved error messaging for InvalidURL exceptions. (#3250)
  • Fix app type signature in ASGITransport. (#3109)

0.27.0 (21st February, 2024)

... (truncated)

Commits

Updates ruff to 0.16.1

Release notes

Sourced from ruff's releases.

0.16.1

Release Notes

Released on 2026-07-30.

Preview features

  • Add an option to opt out of human-readable names (#27160)
  • [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
  • [pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
  • [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)

Bug fixes

  • Bump gen-lsp-types to gracefully handle unknown enumeration values in LSP messages (#27230)
  • [flake8-bugbear] Mark range as immutable (B008) (#27247)
  • [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
  • [flake8-return] Fix false positive when variable is read in finally clause (RET504) (#25441)
  • [pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)
  • [refurb] Parenthesize yield arguments in the FURB192 fix (#27192)

Rule changes

  • [flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)
  • [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)

Server

  • Fix indexing of excluded nested Ruff workspaces (#27303)
  • Lint TOML files in the LSP (#26862)

Documentation

  • Cover pycon Markdown formatting (#27153)
  • [flake8-bandit] Document TYPE_CHECKING exception (S101) (#27004)
  • [flake8-import-conventions] Document that extend-aliases can override default aliases (#27191)
  • [pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)

Other changes

  • Reduce syntax error noise by swallowing dedents like indents (#27170)
  • Vendor latest annotate-snippets (#27033)

Contributors

... (truncated)

Changelog

Sourced from ruff's changelog.

0.16.1

Released on 2026-07-30.

Preview features

  • Add an option to opt out of human-readable names (#27160)
  • [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
  • [pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
  • [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)

Bug fixes

  • Bump gen-lsp-types to gracefully handle unknown enumeration values in LSP messages (#27230)
  • [flake8-bugbear] Mark range as immutable (B008) (#27247)
  • [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
  • [flake8-return] Fix false positive when variable is read in finally clause (RET504) (#25441)
  • [pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)
  • [refurb] Parenthesize yield arguments in the FURB192 fix (#27192)

Rule changes

  • [flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)
  • [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)

Server

  • Fix indexing of excluded nested Ruff workspaces (#27303)
  • Lint TOML files in the LSP (#26862)

Documentation

  • Cover pycon Markdown formatting (#27153)
  • [flake8-bandit] Document TYPE_CHECKING exception (S101) (#27004)
  • [flake8-import-conventions] Document that extend-aliases can override default aliases (#27191)
  • [pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)

Other changes

  • Reduce syntax error noise by swallowing dedents like indents (#27170)
  • Vendor latest annotate-snippets (#27033)

Contributors

... (truncated)

Commits
  • 80790b3 Bump 0.16.1 (#27330)
  • 63830f3 [ty] Borrow from constraint set storage less often (#27328)
  • f40dca9 [ty] Preserve forwarded expanded-variadic diagnostic sources (#27266)
  • 0d80497 Lint TOML files in the LSP (#26862)
  • d91586b Update prek dependencies (#27293)
  • 7da4b8b [ty] Respect bounds and constraints in generic materializations (#27228)
  • b20daf7 [ty] refactor: add helper function to send partial results (#27249)
  • 4d4c8fa [ty] Emit diagnostic when specializing a non-generic class (#26883)
  • 7c3e2db [ty] Fix enum class container assignability (#27318)
  • d5ef97f [flake8-return] Fix false positive when variable is read in finally claus...
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

jonathanlan08 and others added 10 commits August 9, 2026 00:51
…covery

Response to the 2026-08-08 external audit. All six P1 findings and the
actionable P2s are fixed with regression tests.

Backend:
- Valuations store a SHA-256 input fingerprint; the API flags stale results
  and report generation returns 409 until valuation + strategies are
  refreshed from one consistent state
- Unscored comparables get zero weight (was: full base weight) with an
  explicit warning; new effective_count drives adequacy warnings and the
  single-comparable band
- Strict config validation (unknown keys, NaN/Infinity, negative range_k,
  negative dollar assumptions, non-positive similarity caps all 422)
- CSV import rejects non-finite numbers and surplus cells as row errors;
  blank property_type/pool stay unknown (nullable columns + migration)
  instead of being guessed; pool adjustments skip unknown status
- Explicit-null PATCH on required fields 422s; PATCH enforces the
  future-sale-date rule; no-op adjustment edits create no audit events
- SQLite FK enforcement, SQL-side audit pagination, pre-read upload size
  check, report favicon fix

Frontend:
- Stale banners on valuation/strategies/report + header badge
- Generate suggested adjustments persists visible assumption edits first
- Failed saves keep drafts and re-enable controls (finally + commit-on-
  success drafts); report flow uses an explicit open link instead of a
  blockable popup and updates the stepper; dashboard gains complete/
  archive/restore; weights editor blocks an all-zero total

Docs/tools: METHODOLOGY calc-v1.1 notes, DATA_DICTIONARY, README (counts,
env vars, e2e isolation, expanded known limitations), QA_REPORT addendum,
CHANGELOG; verify_math.py verifies the new semantics and no longer assumes
CMA id 1 (279 checks passing)

Tests: 106 pytest (+19), 33 Vitest (+5), 4/4 Playwright (chromium+webkit)
Fixes the five remaining findings from the follow-up external audit.

Backend:
- Suggested adjustments record the assumption set that produced them
  (weight_configurations.suggestions_assumptions + migration). Changing
  assumptions without regenerating flags the config, adds an
  outdated_suggestions warning to any valuation computed from them, and
  blocks report generation (409) until suggestions are regenerated
- Reports require a complete chain: no valuation or no strategies is 400,
  never a seller-facing document with empty sections
- Hard input bounds: adjustment amounts +/-$1B, prices <= $1B, living area
  <= 1M sq ft, lot <= 100M sq ft (API and CSV) so extreme values cannot
  overflow; nonpositive_estimate warning when the central estimate <= 0 and
  strategies refuse to price off it (a falsy check previously let negative
  centrals generate negative list prices)
- Strategies record the valuation_id they were derived from (+ migration);
  seed records the same provenance as the API

Frontend:
- Manual comparable entry defaults property type and pool to "Not
  specified" (stored as unknown) instead of guessing single-family/no-pool
- Weight, multiplier, and adjustment changes refresh the header staleness
  flag immediately; adjustments page shows an outdated-suggestions banner
  and refetches the flag after regenerating
- Report page disables Generate and lists exactly what is still missing;
  strategy cards show the valuation they were computed against

Docs: METHODOLOGY provenance/bounds/completeness notes, DATA_DICTIONARY
columns and limits, CHANGELOG, README test counts

Tests: 112 pytest (+6), 33 Vitest, 4/4 Playwright (chromium+webkit),
verify_math 279/279 against the reseeded demo
…-click repair

Six previously deferred usability gaps, all user-facing convenience:
- Form submits with validation errors focus the first invalid field
- 44px touch targets for the include toggles and pool checkbox
- Strategy price inputs display $ + thousands separators (text/numeric
  input; commit strips formatting, accepts pasted currency)
- StaleBanner gains a one-click "Recalculate valuation & refresh
  strategies" button (pages refetch via onRefreshed)
- Workflow stepper auto-centers the active step on narrow screens with an
  edge-fade scroll hint; scrolls only its own container (scrollIntoView
  panned the whole page on mobile and was replaced)
- Inline rename in the CMA header (Enter/Escape, audit-logged; excluded
  from the staleness fingerprint as a cosmetic field)

Verified in-browser on mobile and desktop viewports; 35 Vitest (+2), 4/4
Playwright (chromium+webkit), tsc/ESLint clean, verify_math 279/279.
UX review follow-up: the remaining gaps were all about staleness being
invisible in places results appear.

- Dashboard: value ranges whose inputs changed show an "outdated:
  recalculate" badge (the list API already computed the flag; it was
  simply never rendered)
- Strategies: warn when the cards were generated from an earlier
  valuation (stored valuation_id vs latest) with an inline refresh
  action, distinct from the inputs-changed banner
- Comparables table: secondary columns (sale date, sq ft, beds/baths,
  distance) collapse below md; sold date moves into the address sub-line
  and full details remain in the expandable similarity breakdown
  (10 -> 6 columns on phones)

Verified headless on iPhone-width: 6 visible columns, page cannot pan
horizontally (window.scrollX stays 0; the documentElement scrollWidth
delta is a benign reporting artifact of the stepper's clipped scroller).
35 Vitest, 4/4 Playwright (chromium+webkit), tsc/ESLint clean, build ok.

Note: the review's report-completeness and manual-entry-guessing items
were already fixed in e01ed99 (gates + "Not specified" defaults).
…caps

Third external audit round. The headline finding was real: the
suggestion-provenance snapshot only tracked assumptions, so editing the
subject's square footage let old adjustments into a "fresh" report.

- suggestions_fingerprint (new column + migration) hashes ALL suggestion
  inputs: assumptions + subject priced fields + every comparable's priced
  fields (as-of date deliberately excluded to avoid daily false flags).
  Subject edits, comp edits, and newly added comps now flag suggestions
  outdated, warn on the valuation, and block the report
- Strategy generation and price edits 409 while the latest valuation is
  stale, closing the API path that priced strategies off known-outdated
  numbers
- Magnitude caps: assumptions <= $1B, similarity params <= 1M, subject
  living area/lot size capped, so extreme finite values cannot overflow
  into server errors
- Subject property_type/has_pool now nullable with "Not specified"
  defaults (+ migration), matching the comparables' never-guess rule;
  report template renders unknowns as placeholders
- Saving assumptions refreshes the header staleness flag immediately
- Docs: corrected test counts (117/35), METHODOLOGY provenance section,
  DATA_DICTIONARY columns

Tests: 117 pytest (+5, 1 strengthened), 35 Vitest, 4/4 Playwright,
verify_math 279/279, migration up/down/up verified
Found while live-demoing the provenance gate: fingerprints hashed 1850
(int) and 1850.0 (float) differently, so SQLite/JSON round-trips could
flip staleness flags on identical values. Two real consequences:

- seed.py assigns int literals to Float columns and fingerprints them
  pre-persistence, so a fresh demo seed reported its own suggestions as
  outdated (unknown/true) the moment the values round-tripped
- config defaults hold ints (bedroom_cap: 3) that become 3.0 after any
  user save, silently changing the valuation fingerprint

All numeric fingerprint leaves are now normalized to float (bools kept
as bools, dates as ISO strings) in both valuation and suggestion
fingerprints. Verified live: fresh seed -> clean; subject resized ->
flagged + report 409; reverted -> clean + report 201.

Also: README roadmap notes the hosted read-only demo as future work
(blocked on auth + rate limiting).

Tests: 119 pytest (+2: type-stability unit test, seeded-provenance
regression)
… ints

Fourth external audit round, all four findings:

- The one-click repair now regenerates outdated suggested adjustments
  before recalculating valuation and strategies (it previously cleared
  the banner while leaving the report gate blocked); button renamed to
  "Refresh the full analysis" and covered by two new component tests
- Unknown provenance FAILS CLOSED: valuations/suggestions with null
  fingerprints (rows migrated from before provenance tracking) now 409
  on strategy generation and reports until recalculated, instead of
  silently passing verification they cannot satisfy
- CSV integer caps (bedrooms/parking <= 50, bathrooms <= 50, distance
  <= 20,000 mi): bedrooms=1e308 becomes a row error instead of a
  database-overflow 500
- Test counts corrected in README/ARCHITECTURE (121 backend / 36
  frontend)

Tests: 121 pytest (+2), 36 Vitest (+1), 4/4 Playwright, verify_math
279/279 on the reseeded demo
Updates the requirements on [fastapi](https://github.com/fastapi/fastapi), [uvicorn](https://github.com/Kludex/uvicorn), [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy), [alembic](https://github.com/sqlalchemy/alembic), [pydantic](https://github.com/pydantic/pydantic), [python-multipart](https://github.com/Kludex/python-multipart), [jinja2](https://github.com/pallets/jinja), [pytest](https://github.com/pytest-dev/pytest), [httpx](https://github.com/encode/httpx) and [ruff](https://github.com/astral-sh/ruff) to permit the latest version.

Updates `fastapi` to 0.141.1
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.110.0...0.141.1)

Updates `uvicorn` to 0.52.1
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](Kludex/uvicorn@0.27.0...0.52.1)

Updates `sqlalchemy` to 2.0.51
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Updates `alembic` to 1.19.0
- [Release notes](https://github.com/sqlalchemy/alembic/releases)
- [Changelog](https://github.com/sqlalchemy/alembic/blob/main/CHANGES)
- [Commits](https://github.com/sqlalchemy/alembic/commits)

Updates `pydantic` to 2.13.4
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](pydantic/pydantic@v2.5.0...v2.13.4)

Updates `python-multipart` to 0.0.32
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md)
- [Commits](Kludex/python-multipart@0.0.9...0.0.32)

Updates `jinja2` to 3.1.6
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](pallets/jinja@3.1.0...3.1.6)

Updates `pytest` to 9.1.1
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@8.0.0...9.1.1)

Updates `httpx` to 0.28.1
- [Release notes](https://github.com/encode/httpx/releases)
- [Changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md)
- [Commits](encode/httpx@0.27.0...0.28.1)

Updates `ruff` to 0.16.1
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@v0.4.0...0.16.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.141.1
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: uvicorn
  dependency-version: 0.52.1
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: sqlalchemy
  dependency-version: 2.0.51
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: alembic
  dependency-version: 1.19.0
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: pydantic
  dependency-version: 2.13.4
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: python-multipart
  dependency-version: 0.0.32
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: jinja2
  dependency-version: 3.1.6
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: pytest
  dependency-version: 9.1.1
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: httpx
  dependency-version: 0.28.1
  dependency-type: direct:production
  dependency-group: backend-dependencies
- dependency-name: ruff
  dependency-version: 0.16.1
  dependency-type: direct:production
  dependency-group: backend-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python Pull requests that update python code labels Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant