Repository navigation
feat(fields): the broker holds the pedestrian wind field itself, per direction - #41
Merged
Merged
Conversation
…direction
Every other artefact of a case lives on the Syncthing master and the broker
records where; the published field -- |U| at 1.75 m above grade on the 2 m
grid over the 1008 m core, per direction -- is what the campaign is for, and at
about a megabyte a direction it fits the fleet's own database now that it is no
longer a 500 MB plan (Patrick, 2026-09-28: a 6 TB Postgres on the Synology).
- case_fields: one row per (case, direction, height); the blob is the node's
umag/1 container stored verbatim (gzip of "UMAG" | u32 version | u32 header
length | header JSON | float32 LE nx*ny, NaN inside a building). The header
fills the columns a browser filters by, so they cannot disagree with the bytes.
- PUT /v1/cases/{id}/fields/{direction}?lease_id= from the node the moment a
direction is solved, lease-gated as /v1/parts; 413 past the size limit, 422
for a blob that is not a field, naming what is wrong with it.
- GET /v1/cases/{id}/fields (records, no bytes; also on the case record) and
GET /v1/cases/{id}/fields/{direction} (the blob, strong ETag, a day of cache).
- Dashboard: the field viewer reads the broker first and fetches each direction
as it is looked at -- exact values under the cursor, one colour scale across
the case from the listing's 99.9th percentiles. The .wfld source stays as the
fallback for cases that have nothing there. A direction whose fetch failed
used to be fetched again on every redraw (495 requests in seconds, seen in
the browser); it offers a retry now.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lds; 0.25.0 Only the version lines conflicted. pyproject.toml and uv.lock are 0.25.0, a feature on top of main's 0.24.1, and the CHANGELOG entry for the fields moves from [0.24.0] to [0.25.0] above main's 0.24.1 and 0.24.0. app.py, db.py, DOMAIN.md and dashboard.html merged on their own: a thermal case still hides the pedestrian-wind section, and the field viewer still reads the broker first. Full suite on the merged tree: 840 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kastnerp
added a commit
that referenced
this pull request
Oct 6, 2026
…direction (#41) case_fields table; PUT /v1/cases/{id}/fields/{direction}?lease_id= from the node as each direction is solved (lease-gated, 413 past the size limit, 422 for a blob that is not a field); GET /v1/cases/{id}/fields and /fields/{direction}; the dashboard's field viewer reads the broker first, .wfld stays the fallback. Merged with main after #42 (version 0.25.0); 840 tests green on the merged tree. Eddy3D #962 (already on dev) is the node half: until this deploys, a dev node's field upload gets 404 and its cases complete without fields in the database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The broker now stores the campaign's published answer — |U| at 1.75 m above grade on the 2 m grid over the 1008 m core, per wind direction — in its own database, instead of only pointing at an archive on the Syncthing master. Version 0.24.0.
case_fieldstable (SQLite BLOB / Postgres BYTEA): one row per (case, direction, height). The blob is the node'sumag/1container stored verbatim:gzip("UMAG" | u32 version | u32 header length | header JSON | float32 LE nx*ny), NaN inside a building, ~0.75 MB per direction. The header fills the queryable columns (grid, angle, coverage, U_ref, 99.9th percentile of |U|), so they cannot disagree with the bytes.PUT /v1/cases/{id}/fields/{direction}?lease_id=— from the node the moment a direction is solved. Lease-gated exactly like/v1/parts(409 = lease gone / not this credential's). 413 pastCASEBROKER_FIELD_MAX_BYTES(64 MiB default), 422 for a blob that is not a field, naming what is wrong with it. A second upload for the same direction/height replaces the first.GET /v1/cases/{id}/fields(records, no bytes; also on the case record asfields) andGET /v1/cases/{id}/fields/{direction}?height_m=(the blob, strong ETag,Cache-Control: private, max-age=86400, 304 on match)..wfldcarried a byte), one colour scale across every direction of a case from the listing's percentiles, no arrows (|U| only). The wind-field source / open-from-disk.wfldpath stays as the fallback for cases with nothing in the broker.Why
Patrick's decision, 2026-09-28: the broker's DB is moving to a 6 TB Postgres on the Synology, so storage is no longer the constraint. The
.wfldroute required someone to serve a folder off the master; with the field in the DB a case's answer is one authenticated GET away.Reviewer notes
MetaFOAM.Deploy.PedestrianFieldreader,CaseFieldsuploader,BrokerClient.PutFieldAsync) lives on the Eddy3D branchclaude/sim-nodes-wind-probing-db-9aec5f. Old nodes are unaffected; a node from before fields simply never PUTs.db.decode_umagvalidates the container only (magic, version, header, byte count) — the broker never re-derives values.uv.lockchanged only because of the version bump.tests/test_case_fields.py(14 tests: DB layer, HTTP round trip, refusals, storage). Full suite: 818 passed, 30 skipped.CASEBROKER_DB_QUOTA_MBso/v1/storagestops assuming the 500 MB Supabase plan.🤖 Generated with Claude Code