Skip to content

fix(web): truthful operator status and save feedback across the server pages - #317

Merged
dorkmo merged 1 commit into
masterfrom
website-status-and-feedback
Sep 15, 2026
Merged

dorkmo merged 1 commit into
masterfrom
website-status-and-feedback

Conversation

@dorkmo

@dorkmo dorkmo commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Stacked PR. Base branch is website-config-roundtrip-calibration (#316). Merge order: #314#315#316 → this PR. This PR's diff shows only its own changes.

Summary

Third website PR from the 2026-09 master review: S-W06 (operator status can be misleading) and S-W07 (logs, save feedback, secondary API usability). All changes are in TankAlarm-112025-Server-BluesOpta.ino; the server-side parts are small, targeted handler fixes.

S-W06 — operator status

Item Before After
Float switches on the dashboard (M-30) "Tank Level" card, value -- for OFF, an in/24h delta and a trend sparkline "Float Switch" card reading ON / OFF, no delta, no sparkline
Level of exactly 0 in -- (indistinguishable from no data) 0.0"
"Update requested" pill (M-31) never expired; an unreachable client kept the dashboard on 10 s polling and hid the Update button for good expires after the client's reply window (10 min grid / 60 min solar); the button returns as Retry Update with a tooltip and polling drops back to normal
/api/clients client-level at (M-41) overwritten by whichever sensor reported last, so a multi-sensor client could show "ALARM: clear" kept for the sensor in alarm
Site Config sensor rows (L-25) the ts[] mapper dropped flt/ma, so the FAULT badge and mA readout were dead and a current-loop fault rendered as a number fault string and mA mapped; float switches read ON/OFF
Outdated-client banner (L-51) counted any client whose version string differed from the release, including newer ones uses the sketch's existing compareFirmwareVersions(); only older-than counts
Client Console "Approve Deletion" prompted for the admin PIN although requireValidPin() validates the session and ignores the value a confirm dialog, like the dashboard's Remove Client

S-W07 — logs, feedback, secondary APIs

  • Transmission Log (M-26, M-27): filter options are built from the vocabulary logTransmission() emits (13 types, 14 statuses) plus whatever the loaded entries contain, so error, ota, alarm, applied, stalled… are selectable and no option is dead. The CSV export now uses the same filtered set as the table, including the detail-text search it used to omit. Badge colours added for error, applied, stalled.
  • saved:false (M-57): Contacts and Server Settings show an error toast ("saved in memory only, lost at the next reboot") when the server reports the flash write failed, instead of "saved successfully".
  • Overlong settings (M-58): GitHub route alias, FTP user and FTP password return 400 … too long (max 31 characters) instead of being silently cut; the inputs carry maxlength="31".
  • GET /api/location (M-61): the client= parameter goes through getQueryParam() (URL-decoded), so dev%3A… matches the stored UID and the Client Console location readout works for real UIDs.
  • Year-over-year history (L-49): ?sensor= splits at the last colon.
  • Login (L-22): anything other than a 401 shows the server's text (the 429 lockout countdown, the first-login "set a 4-digit PIN" message, or Login failed (HTTP n)); 401 still reads "Invalid PIN".
  • Config Generator (L-19, L-20, L-21): ?uid= for a client with no snapshot (404 or no config) starts a new configuration with the UID filled in and one sensor card, with an explanatory toast; Add Sensor stops at 8 with a toast, collectConfig refuses more, and handleConfigPost rejects a config with more than 8 sensors (the client keeps MAX_MONITORS = 8 and dropped the rest); if the contacts directory has not loaded, the download is refused and the load retried instead of deriving the daily report time from a hard-coded 05:00 UTC.
  • Server Settings (L-18): settings load once per page open (one /api/clients?summary=1 fetch measured) instead of twice.

Verification

Browser, against a loopback fixture serving the pages extracted from this branch (placeholder data), zero error events on every page exercised:

  • Dashboard cards: Float Switch / OFF with no delta or sparkline; pressure tank in alarm shows ALARM: HIGH; a request older than its window renders Retry Update with the tooltip, a 100 s-old one renders the ETA pill.
  • Site Config rows: 40.0 in 12.50 mA, OFF, FAULT OPEN.
  • Transmission Log: 6 fixture entries; status = error → 1 row; search "needle" (detail only) → 1 row and the CSV export has exactly that row.
  • Login: 1111 → "Invalid PIN", 9999 → "Too many failed attempts. Try again in 30 seconds", 0000 → "Please set a 4-digit PIN on first login".
  • Contacts: a schedule change against a saved:false reply shows the in-memory-only error toast.
  • Config Generator: ?uid=dev:000000000009 (404) → UID filled, one card, commissioning toast; nine Add Sensor clicks → 8 cards and the cap toast.
  • Client Console: approveDeletion calls confirm, never prompt, and sends {"client":"…"} only.
  • Server Settings: one /api/clients?summary=1 request; maxlength 31 on the three inputs.
  • Compile at arduino:mbed_opta 4.5.0, --warnings all: 1,028,012 B (52%) flash on this stacked branch (+2984 B over fix(web): lossless config generator round-trips and calibration sensor identity #316; the same change on a master base measured +2,984 B), 360,720 B (68%) static RAM (unchanged); warning set identical to the master build (line numbers aside). CI's compile-check and check-web-pages both pass on this PR.
  • check_web_pages.py (from fix(web): bind six dead controls programmatically, restrict client UIDs, clamp config inputs, add page checker to CI #315): every <script> block on all 18 pages passes node --check, 0 problems.

Not in this PR

  • L-42 (transmission-log entries for SMS/email carry no site/client and truncate detail): the fix is in the alarm-dispatch code path and deserves its own change.
  • The stale threshold policy (49 h vs the old label) is unchanged, as the review recommends; Website: unify page chrome and fix layout/style inconsistencies #314 already renders the label from the constant.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 14, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 15:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from ce5c5d7 to 4333343 Compare September 14, 2026 16:22
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 29a139f to 9dc30fb Compare September 14, 2026 16:22
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 18:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from 4333343 to d35a73d Compare September 14, 2026 19:03
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 9dc30fb to 50b4d9f Compare September 14, 2026 19:03
@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from d35a73d to 53c0854 Compare September 14, 2026 19:32
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 50b4d9f to a5ca903 Compare September 14, 2026 19:32
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 19:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from 53c0854 to 9aa1ba2 Compare September 14, 2026 19:52
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from a5ca903 to 688b7cb Compare September 14, 2026 19:52
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 19:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from 9aa1ba2 to aa60921 Compare September 14, 2026 20:11
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 688b7cb to a94c81c Compare September 14, 2026 20:11
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from aa60921 to 10d60da Compare September 14, 2026 20:31
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 21:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from d8a475e to 1b421bb Compare September 14, 2026 21:22
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 451bd31 to 80ba638 Compare September 14, 2026 21:22
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 21:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from 1b421bb to be491d4 Compare September 14, 2026 21:39
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 80ba638 to cef08c2 Compare September 14, 2026 21:39
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 21:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from be491d4 to f3552d5 Compare September 14, 2026 21:55
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from cef08c2 to faeb2ff Compare September 14, 2026 21:55
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 21:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from f3552d5 to 9ccd11f Compare September 14, 2026 22:15
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from faeb2ff to 2bdaecf Compare September 14, 2026 22:15
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

…r pages

S-W06 (operator status; CLAUDE M-30, M-31, M-41, L-25, L-51):
- Dashboard renders float switches as "Float Switch" with ON/OFF instead
  of "Tank Level --" with an inches-per-24h delta and a trend sparkline,
  and a level of exactly 0 in reads 0.0" instead of "--".
- An "Update requested" pill now expires after the client's reply window
  (10 min grid, 60 min solar); the button comes back as "Retry Update"
  with a tooltip, and the 10 s polling stops with the pill.
- /api/clients no longer overwrites the client-level alarm type with the
  newest sensor's (a multi-sensor client showed "ALARM: clear").
- Site Config keeps the fault string and mA the server sends, so its FAULT
  badge and mA readout work; float switches read ON/OFF there too.
- The outdated-client count uses the existing compareFirmwareVersions()
  so clients running newer firmware than the release are not "outdated".
- Client Console deletion asks for confirmation instead of a PIN prompt;
  the server validates the session, not the PIN, for that request.

S-W07 (logs, save feedback, secondary APIs; CLAUDE M-26, M-27, M-57,
M-58, M-61, L-18, L-19, L-20, L-21, L-22, L-49):
- Transmission Log filter options are built from the vocabulary
  logTransmission() emits plus whatever the loaded entries contain
  ("error" was unreachable; two options matched nothing), and the CSV
  export uses the same filter as the table, including the detail search.
- Contacts and Server Settings report a saved:false reply as an error
  (in memory only, lost at reboot) instead of "saved successfully".
- GitHub route alias, FTP user and FTP password are rejected with a 400
  when longer than 31 characters instead of being truncated silently;
  the inputs carry maxlength=31.
- GET /api/location decodes the client parameter, so real dev: UIDs no
  longer always read "Not yet received" on the Client Console.
- Year-over-year history splits the sensor key at the last colon.
- Login shows the server's reason (lockout countdown, first-login setup)
  for anything other than a 401.
- Config Generator: opening ?uid= for a client with no snapshot starts a
  new configuration instead of an error; at most 8 sensors can be added
  or collected, and handleConfigPost rejects more; the daily report time
  is not computed from a guessed 05:00 UTC when the contacts schedule has
  not loaded (the load is retried and the download refused until then).
- Server Settings loads its settings once per page open instead of twice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@dorkmo
dorkmo force-pushed the website-config-roundtrip-calibration branch from 9ccd11f to 738760d Compare September 14, 2026 22:34
@dorkmo
dorkmo force-pushed the website-status-and-feedback branch from 2bdaecf to bd877e0 Compare September 14, 2026 22:34
@dorkmo
dorkmo requested a balanced review from Copilot September 14, 2026 22:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo requested a balanced review from Copilot September 15, 2026 14:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@dorkmo
dorkmo changed the base branch from website-config-roundtrip-calibration to master September 15, 2026 14:34
@dorkmo
dorkmo merged commit 2e2c97c into master Sep 15, 2026
4 checks passed
@dorkmo
dorkmo deleted the website-status-and-feedback branch September 15, 2026 14:35
dorkmo added a commit that referenced this pull request Sep 15, 2026
…statuses

Adds CODE_REVIEW_09152026_WEBSITE_PRS_314_317_CLAUDE.md (what each PR
changed, how it was verified, the eleven Copilot review rounds, what
remains) and marks S-W01/02/03 done and S-W05/06/07 merged with residuals
in TODO.md, with the merge commits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
dorkmo added a commit that referenced this pull request Sep 15, 2026
…ess config round-trips, calibration identity, operator status, UID hardening

Server-only release; client and viewer are version bumps only (notefile
schema, command formats and the config payload are unchanged). Details in
release-notes/v2.2.15.md and CODE REVIEW/CODE_REVIEW_09152026_WEBSITE_PRS_314_317_CLAUDE.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants