Skip to content

Unbreak main twice over, and work four issues behind it - #112

Merged
dimmus merged 6 commits into
mainfrom
claude/printorian-pr-fixes-1a9039
Sep 24, 2026
Merged

dimmus merged 6 commits into
mainfrom
claude/printorian-pr-fixes-1a9039

Conversation

@dimmus

@dimmus dimmus commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Why main is red, and the one-line fix

main has failed its backend job on every push since #106 (2026-09-09). That PR raised anyio to 4.15.1, which deprecates anyio.abc.BlockingPortal; starlette 1.6.0 still imports it from there in testclient.py, and filterwarnings = ["error"] turns the import into a collection error in tests/api/test_events_ws.py — pytest exits 2 before running a test. Both open Dependabot PRs (#110, #111) fail on that same line, including the frontend one, which is what marks it as a main problem. #106 merged red because branch protection (#67) is not on.

Fix: starlette==1.7.0 in backend/constraints.txt (released 2026-09-23; imports the portal from anyio.from_thread). The comment in the file records why a filterwarnings ignore was refused. After this merges, #110 and #111 need @dependabot rebase.

The second break, hidden behind the first

Once the backend job passed, the frontend job ran on main's tree for the first time since #105 (vitest 4.1.11 → 5.0.0, merged red) and failed Types with 208 TS2339 errors: vitest 5 changed Assertion<T> to Assertion<R, T> and jest-dom 7.0.1's augmentation no longer merges (jest-dom's fix, testing-library/jest-dom#742, is unreleased). frontend/types/jest-dom-vitest.d.ts bridges it through vitest's Matchers<R, T> extension point; delete it and the four tsconfig.json includes when jest-dom ships. Verified from a lockfile install: tsc --build --force 208 errors without, 0 with; lint, full vitest (33 files, 317 passed) and build exit 0. Note npm run typecheck alone passed on a stale tsbuildinfo — HANDOFF records that trap.

Issues worked in the same branch

  • purchasing.html — no Supplier, no PurchaseOrder, nothing #34 — supplier scorecard, computed. procurement.reads.supplier_scores groups orders by supplier with three FILTER counts (deliveries = reached STORED, dated = of those with an expected_at, on_time = stored_at <= expected_at). policies.on_time_share is null when nothing was dated — an undated delivery is neither punctual nor late. «Брак», «Оборот» and «Оценка» are deliberately absent (unmeasured / money the board never carries / undefined composite); the schema docstring says so. Board panel «Поставщики» on the purchasing screen. test_purchasing_api.py crossed the 400-line gate and was split at its seam (_purchasing_support.py, test_purchasing_scorecard_api.py).
  • Worker loop intervals only take effect on restart #32 — the three restart-only intervals now say so on the screen. Hints on scheduler_tick_seconds, sla_sweep_seconds, telemetry_poll_seconds in both catalogues; SettingsPage.test.tsx pins each in its own section and fails when the catalogue change is reverted (run). The hot reload stays deferred.
  • Closes The documented development account credentials do not work #12 — docs/DEVELOPMENT.md no longer publishes credentials nothing seeds. Verified on a fresh database (CREATE DATABASE → alembic upgrade head → provision_with → POST /auth/sign-in): boss@ 200 with the password typed at provisioning, floor@ 401 invalid_credentials because no row exists. The role decision the issue flagged is not made: the document no longer asserts one.
  • Reprice a line from slicer truth, so a cache hit can skip prep entirely #58 is built by Price the plate the farm already sliced, so a repeat order queues itself #92; it is closed separately with the reproduction pasted on the issue.

Verified

Backend, each run separately and each exit=0: ruff check, ruff format --check, mypy --strict (255 source files), lint-imports (6 kept, 0 broken), check_context_isolation.py, check_file_length.py.

Full backend suite on this tree: 1 619 passed, 7 skipped, exit=0 in 1687.95s (started before the scorecard tests existed; those plus the split purchasing API tests and the two #58 intake files then ran in one further session: 28 passed, exit=0).

Frontend, from npm ci on the lockfile: tsc --build --force, lint, test (33 files, 317 passed) and build each exit=0.

Mutations run and reverted: counting RECEIVING as a delivery (1 scorecard test fails), deliveries as the denominator (2), 0 for an undated share (3), every dated delivery on time (1); reverting the settings-hint catalogue change fails the new SettingsPage test.

HANDOFF.md carries the session record.

🤖 Generated with Claude Code

dimmus and others added 5 commits September 24, 2026 17:57
… warning gate refused the old import

`main` has failed its backend job on every push since #106 raised anyio to
4.15.1: `anyio.abc.BlockingPortal` is deprecated there, starlette 1.6.0 still
imports it in `testclient.py`, and `filterwarnings = ["error"]` turns that
import into a collection error in `tests/api/test_events_ws.py` before a
single test runs. Both open Dependabot pull requests fail on the same line.

starlette 1.7.0 imports the portal from `anyio.from_thread`. The comment in
`constraints.txt` records why an ignore was refused: it would pass the gate
while leaving the farm on a version the next anyio actually breaks.

Verified: `tests/api/test_events_ws.py` 14 passed; the full suite 1 619
passed, 7 skipped, exit=0 in 1687.95s; all six gates exit=0.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
)

`scheduler_tick_seconds`, `sla_sweep_seconds` and `telemetry_poll_seconds`
are handed to their loops once in `workers/runner.py`; their neighbours on the
settings screen resolve at the read edge and take effect on save. The screen
gave no sign of the difference, so an owner saw the audit row and concluded
the change had taken. The hint now states it, in both catalogues, and the new
`SettingsPage` test pins that each of the three carries it in its own section.
Reverting the catalogue change fails that test (run). The hot reload itself
stays deferred, as the issue says.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Closes #12. `docs/DEVELOPMENT.md` listed `[email protected]` /
`shop-floor-pass-1` and a fixed owner password; nothing in the repository
creates the first or sets the second. Verified against a freshly created
database: `alembic upgrade head` (0001 -> 0026), `provision_with` with the
password `owner-pass-12345`, then `POST /auth/sign-in` through Starlette's
TestClient - `boss@` 200, `floor@` 401 `error.identity.invalid_credentials`,
and `SELECT email, role FROM users` returns the one owner row. The table now
says the owner's password is whatever was typed at the prompt and the second
account is made in the console with the role the gate being checked needs.
The role decision the issue flagged as needs-person is not made: the document
no longer asserts one.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
… cannot be scored (#34)

The last clause of #34's "done when": the supplier scorecard computes from
delivered purchase orders rather than being typed in. `supplier_scores`
groups orders by supplier with three FILTER counts on one join - reached
STORED, of those the ones that carried an expected_at, of those the ones on
the shelf by that date. `on_time_share` is on_time / dated, and null when
nothing was dated: an undated delivery is neither punctual nor late, and
counting it either way moves the score for every date a buyer did not type.

Three of the kit's six columns are deliberately absent, each for a reason the
schema docstring records: a defect share needs a rejected quantity no receipt
records and would read 0% for everyone; turnover is money the board never
carries; a composite rating is a policy nobody has written.

`test_purchasing_api.py` crossed the 400-line gate with the API test for this
and is split at its seam: `_purchasing_support.py` (helpers, no fixtures - the
`_catalog_support.py` rule) and `test_purchasing_scorecard_api.py`.

Verified: nine unit tests and two API tests; four mutations each fail at
least one - RECEIVING counted as delivered (1), deliveries as the denominator
(2), 0 for an undated share (3), every dated delivery on time (1). The screen
test draws the share with its counts and an em dash where nothing was dated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
…ot yet

#105 raised vitest to 5.0.0 with its frontend check red, and nothing on main
noticed because the backend job ahead of it was already failing on another
bump. Vitest 5 made `Assertion<T>` into `Assertion<R, T>`; jest-dom 7.0.1
augments the one-parameter shape, the merge silently fails under
`skipLibCheck`, and a clean `tsc --build` reports 208 TS2339 errors across
every test file while the suite runs green - the runtime half still works.

`frontend/types/jest-dom-vitest.d.ts` augments vitest's documented
`Matchers<R, T>` extension point with jest-dom's matchers, in the parameter
order jest-dom's own pending fix uses (testing-library/jest-dom#742). The
four project tsconfigs include it. Delete both when jest-dom ships #742.

Verified from a lockfile install: `tsc --build --force` 208 errors without
the file, 0 with it; `lint`, the whole vitest run (33 files, 317 passed) and
`build` each exit=0. HANDOFF records the trap: `npm run typecheck` passed on
this tree because stale `*.tsbuildinfo` skipped the check.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@dimmus dimmus changed the title Unbreak main with one pin, and work four issues behind it Unbreak main twice over, and work four issues behind it Sep 24, 2026
@dimmus
dimmus merged commit d097b30 into main Sep 24, 2026
7 checks passed
@dimmus
dimmus deleted the claude/printorian-pr-fixes-1a9039 branch September 24, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The documented development account credentials do not work

1 participant