Six new design-system components, all documented with live examples in
the StyleGuide as required by CLAUDE.md before any page can use them:
- MultiSelect: checkbox dropdown for filters/tags, built on Select's
trigger/menu styling
- LineChart: telemetry/time-series charting for the upcoming Health tab
- SignalIndicator: signal-strength glyph for device RSSI display
- PressHoldButton: press-and-hold confirmation for destructive actions
- EditableText: inline click-to-edit text with a hover/focus-revealed
pencil affordance
- TimeRangeSelect: preset + custom time-range picker, backed by the new
lib/timeRange.js helper
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Toast gains a pending/update lifecycle so async actions can show a single
toast that transitions from in-progress to success/error, instead of
firing a new one. Select's floating-menu placement logic is extracted
into a shared helper so other dropdown-style components (MultiSelect)
can reuse it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Was previously a dead stub (TODO: implement). This real implementation
is the foundation for live heartbeats, ping RTT, and the device command
ack flow that later commits build on.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Firmware rebuilt its MQTT topics to v2 (control/command+ack+reports,
status/playback, system/alerts+info+logs+metrics, LWT, req_id, per-topic
switches — see project-vesper's docs/reference/vesper_mqtt_topic_spec_v2.md
and feature-catalog.md F-062). Mirrors that in the console's API Reference:
- Transports tab now splits into V2 (fully documented: topic table with
per-topic switches, req_id correlation, heartbeat/playback/reports/
alerts/boot-report/metrics payload cards) and Legacy (placeholder,
to be filled in later)
- mqtt namespace gains mqtt.get_topics / mqtt.set_topics command docs
- mqtt.disable description updated for its new graceful-offline behavior
- Message envelope docs (top of page) note the new optional req_id field
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Firmware side added an MQTT-only sysadmin command to override a
device's factory-set identity (serial/hw_family/hw_revision) — see
project-vesper commit 64a8bc2. Per docs/README.md's console-sync
rule, mirrors the same command into the console's live API Reference
page.
Note: this repo had substantial other pending uncommitted work
(diagnostics reports, boot history, log retention, etc.) in this
same file and elsewhere at the time of this commit — left untouched
and still uncommitted, only the system.set_identity hunk is included
here.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mirrors firmware changes: new SD log retrieval commands on LoggingHandler
(logs.list, logs.download — chunked/paginated for offline-device
troubleshooting), and firmware.status now returns OTA rollback safety-net
diagnostics (retry/failure counts, backup partition info).
Adds a dedicated Heartbeat Payload card to the Transports tab showing
the full JSON schema with per-field descriptions, including the new rssi field.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
network.info: updated description and response example to reflect new fields
(subnet, mac, hostname, ssid, connection_type). Notes it as the command to use
for console panel population.
network.status: updated to show slimmed response (connected, ap_mode, rssi,
uptime_ms, state). Notes it as the command for monitoring/polling, not display.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- clock.get_config response example now includes gmt_offset_sec, dst_offset_sec, ntp_server
- Description updated to note it supersedes clock.get_timezone
- clock.set_backlight field names corrected to match wire format
(backlight, backlight_output, backlight_on, backlight_off)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document three new batch commands with full response/errors/example fields:
- relay.set_config: combined bell durations + outputs
- clock.set_config: clock hardware settings (enabled, c1, c2, timings)
- clock.set_alerts_config: alert type, bell assignments, silence windows
Also updated output field notes throughout clock and relay commands to reflect
the enforced 1-based output numbering convention (0 = disabled, 255 = unconfigured).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
melody.uid is never actually populated anywhere in MelodyForm.jsx, so keying
local .bsm storage on it (as the previous commit did) would silently break
for every existing melody. pid is the correct key anyway: it identifies the
underlying archetype binary, and multiple melodies legitimately share one
pid (each remaps the same note sequence to different bells/speed/duration
via its own settings). Deletion is now share-aware — a melody's binary is
only removed from disk once no other melody still references its pid.
Also adds backend/scripts/migrate_melody_binaries_to_local.py to backfill
existing melodies from their old Firebase URLs to local storage, with
--dry-run support and a warning list for pids whose melodies point at
different source files (a pre-existing data issue, flagged for manual
review via each melody's playback button rather than silently resolved).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ESP32 devices can't spare the 40KB+ RAM a TLS client needs, so Firebase
Storage's HTTPS-only download URLs were blocking melody downloads. Binaries
are now written to local disk (./data/melody_binaries) and served through a
new unauthenticated /api/melodies/download/{pid} route, exposed publicly on
a separate melodies.bellsystems.net vhost (plain HTTP, no TLS) so the main
console domain can stay HTTPS-only with no exceptions. Preview audio still
uses Firebase Storage since it's only ever fetched by the HTTPS admin UI.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Manufacturing router now uses shared/audit.log_action (Postgres) instead
of the separate manufacturing/audit.py (SQLite mfg_audit_log), so all
manufacturing events appear in the Log Viewer
- Added log_action calls to 5 previously unlogged endpoints: lifecycle
patch, lifecycle create, lifecycle delete, flash asset upload, flash
asset note
- Removed the now-redundant /manufacturing/audit-log endpoint
- Log Viewer restricted to sysadmin only: backend uses require_sysadmin
(was require_admin_or_above), frontend adds role guard on the page
- Fixed Action badge column clipping: table-layout auto + whiteSpace nowrap
so the column sizes to fit the widest badge (Status Change)
- Added device_batch entity type to Log Viewer entity labels and filters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Orders:
- Auto-set customer status to ACTIVE when creating a new order (both "+ New Order" and "Init Negotiations")
- Update Status panel now resets datetime to current time each time it opens
- Empty note on status update saves as empty string instead of falling back to previous note
- Default note pre-filled per status type when Update Status panel opens or status changes
- Timeline items now show verbose date/time ("25 March 2026, 4:49 pm") with muted updated-by indicator
CustomerDetail:
- Reordered tabs: Overview | Communication | Quotations | Orders | Finance | Files & Media | Devices | Support
- Renamed "Financials" tab to "Finance"
CustomerList:
- Location column shows city only, falls back to country if city is empty
OverviewTab:
- Hero status container redesigned: icon + status name + verbose description + shimmer border
- Issues, Support, Orders shown as matching hero cards on the same row (status flex-grows to fill space)
- All four cards share identical height, padding, and animated shimmer border effect
- Stat card borders use muted opacity to stay visually consistent with the status card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New public page at /serial-monitor: connects to Web Serial (115200 baud),
streams live output, saves sessions to localStorage + downloads .txt
- New protected page at /settings/serial-logs (admin/sysadmin only):
lists saved sessions, expandable with full scrollable log, search,
export and delete per session
- Registered routes in App.jsx and added Log Viewer to Console Settings sidebar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add deploy-host.sh for webhook-triggered docker redeploy
- Update docker-compose.yml and nginx.conf for auto-pull setup
- Fix vite.config.js and admin router for deployment environment
- Fix NVS CRC seed to use 0xFFFFFFFF to match esp_rom_crc32_le
- Add dual-panel flash UI: esptool log + live 115200 serial monitor
- Auto-reset device via RTS after flash (no manual power cycle needed)
- Clean up Header.jsx debug title text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>