Expand description
Row types mirroring the tables in migrations/0001_initial_schema.sql.
These are deliberately typed, not raw-column, shapes: wherever a table’s columns are a
clean 1:1 match for an existing bhtune-core type (DcsTemplate, LoopTags,
LoopConfig, Tick + MrftState), the row struct holds that type directly rather than
re-declaring its fields — one less place for the two to drift apart. Where a table
combines fields from two bhtune-core types that both carry their own overlapping field
(TuningResult/PidParameters both carry response_level; InitialReadings/PvRange
don’t nest cleanly with the extra controller_direction column), the row struct is flat
instead, matching the table exactly and avoiding a redundant, only-sometimes-consistent
duplicate field.
DemoSessionRow, DcsTemplateRow, and
TuneRunRow/TuneSampleRow/TuneResultRow/
TuneMvActuationRow/TuneWriteRow have full repository methods (insert, lifecycle
transitions, filtering, pagination) — covering db-seed-templates and
history-query-api. LoopRow deliberately has none yet: full CRUD for saved loops
(list/update/delete) is a separate “loop management” concern from history (which is about
runs, not the loops they reference), left to whichever future todo actually needs it.
Until then, tests construct loops rows with raw SQL (see tests/schema.rs’s seed_loop
helper) purely as foreign-key setup.
TuneRunRow::list/TuneRunRow::count build their WHERE clause dynamically with
sqlx::QueryBuilder, since TuneRunFilter’s fields are all optional and the set of
active conditions varies per call — a fixed query! string can’t express that, and
bhtune-db uses runtime query/query_as throughout anyway (see Cargo.toml), so this
doesn’t introduce a new query style, just the first dynamic one.
Structs§
- DcsTemplate
Row - One row of
dcs_templates: aDcsTemplateplus the database bookkeeping fields that don’t belong on the pure domain type itself. - Demo
Session Row - A short-lived anonymous owner for simulator-only public demo runs. The raw bearer token is never stored; callers pass its lowercase hexadecimal SHA-256 hash to the repository.
- Effective
Tuning - Concrete tune timing values after configuration defaults have been resolved.
- LoopRow
- One row of
loops: a saved, named tag mapping plus default MRFT parameters. - NewTune
MvActuation - Input for
TuneMvActuationRow::insert_pending. - NewTune
Write - Everything needed to record one write-back attempt, successful or not. Built up by the
caller as it works through the sequential pre-read / write-and-verify / rollback steps,
then persisted in a single
TuneWriteRow::insertcall – replacing the old two-outcomeinsert_success/insert_failuresplit, which could not represent a partial write or a rollback attempt at all. Seesafety-writeback-rollbackin AGENTS.md for the four distinguishable outcomes this shape exists to capture. - Pagination
- A page of
TuneRunRow::listresults:limitrows starting atoffset, ordered newest first. - Poll
Latency Metrics - Operation-latency diagnostics captured while a run is polling.
- Setting
Row - One row of
settings: an app-wide key/value pair (e.g. thehistory-retentionpolicy). - Timing
Metrics - Polling-cadence diagnostics captured over one run’s successful PV samples.
- Timing
Summary - Summary statistics for one class of measured polling work.
- Tune
MvActuation Row - One row of
tune_mv_actuations: durable evidence for an accepted OPC DA MV write. - Tune
Result Row - One row of
tune_results: the calculated PID result for oneResponseLevelof one run. - Tune
RunFilter - Filter criteria for
TuneRunRow::list/TuneRunRow::count. Every field is optional; the all-Nonedefault matches every run. Build one withTuneRunFilter::defaultand thewith_*methods, e.g.TuneRunFilter::default().with_outcome(TuneOutcome::Failed). - Tune
RunInitial Readings - The initial-readings snapshot for a
TuneRunRow— known only once the driver’s initial read actually succeeds (ReadInitialOPCvaluesin the legacy app);Nonefor a run that failed before or during that step. Combinesbhtune_core::mrft::InitialReadings/bhtune_core::range::PvRangewith the resolvedControllerDirectioncore-tuning-mathneeds alongside them, as one bespoke type, since gluing the two existing structs together with one extra field isn’t any simpler than a purpose-built one here. - Tune
RunRow - One row of
tune_runs: a single MRFT (or future Step Test) execution against a loop. - Tune
Sample Row - One row of
tune_samples: a single tick’sTickinput and resultingMrftState. - Tune
Write Row - One row of
tune_writes: an audit record of PID constants actually written back to the DCS for oneResponseLevelof one run, distinct from what was merely calculated (TuneResultRow). Flattened for the same reason asTuneResultRow. - Write
Readback - A triple of proportional/integral/derivative values, read from the driver before any
write is attempted (
TuneWriteRow::previous). Not abhtune-coretype likebhtune_core::tuning_math::OpcWriteValues: this is a raw observation, not a calculated/intended value.
Enums§
- MvActuation
Kind - The physical purpose of one accepted manipulated-variable command.
- MvActuation
Status - Lifecycle state of one accepted manipulated-variable command.
- Restore
Status - The outcome of a best-effort loop-restore attempt made after a run ended –
safety-restore-guard(finding 3 of the live-plant safety review). Recorded viaTuneRunRow::record_restore_status;NULLin the database (mapped toNoneonTuneRunRow::restore_status) means no restore was ever attempted – either the run never mutated the loop at all, or it hasn’t ended yet. - Rollback
State - Whether a best-effort rollback of a partially-completed PID write was attempted and, if
so, whether it succeeded. See
TuneWriteRow::rollback_statefor when this isNone. - Sample
Quality - How much a
TuneSampleRow’ssample.pvreading should be trusted, as recorded at the moment it was read (finding 5 of the live-plant safety review). - Sampling
Adequacy - Advisory assessment of whether the recorded samples provide enough observations per oscillation period for a trustworthy extrema measurement.
- Template
Origin - Where a
dcs_templatesrow came from, and – sinceTuneRunRowsnapshots a copy of one atTuneRunRow::starttime – where a run’s snapshotted template came from too. Kept as one definition reused by both tables (dcs_templates.origin,tune_runs.template_origin) rather than two, so they can never drift on what the possible origins even are, and so a run’s history never needs to look the original row back up to know its provenance – which matters precisely because that row might no longer exist, or might have been re-imported under a different origin since. - Timing
Basis - The clock basis used for a run’s persisted polling-cadence diagnostics.
- Tune
Driver - Which
crate-agnostic I/O driver a run used. Lives inbhtune-dbrather thanbhtune-corebecause it’s a persistence/orchestration concept (which adapter drove this run), not a domain concept the pure MRFT engine itself needs to know about. - Tune
Outcome - A run’s lifecycle state.
- Write
Kind - Distinguishes a normal write-back from
bhtune history revertundoing an earlier one. Both shareTuneWriteRow’s exact shape – pre-read, write-and-verify each constant, audit the outcome – so they live in the same table rather than a second near-duplicate one;kindis the one column that tells them apart.
Constants§
- DEMO_
RESTART_ INTERRUPTED_ REASON - Failure reason persisted when startup recovery terminates an owned demo run that was still marked as running.