Skip to content

v2.0.2

Choose a tag to compare

@github-actions github-actions released this 07 Jun 21:16
· 64 commits to master since this release
Immutable release. Only release title and notes can be modified.
v2.0.2
1132d08

BridgePort v2.0.2 is a maintenance release with three targeted fixes: binary config files can now be replaced in place (and a data-loss bug when editing their metadata is closed), database/monitoring charts correctly render Postgres metrics and multi-database "Top Tables", and the View Logs modal reliably opens at the newest entry. No database migrations — upgrade is a straight image swap.


Three related gaps on the Config Files page:

  • Binary files now have a replace mechanism. The edit modal previously said "Re-upload to replace" but offered no control, and Upload Asset only ever created new files (409 on a duplicate name). A new operator-only endpoint POST /api/config-files/:id/replace-asset swaps content/mimeType/fileSize in place — keeping service attachments, sync assignments, and history — and the edit modal's binary branch now has a wired-up Replace file input. Old content is saved to FileHistory for rollback.
  • API errors now surface as toasts. Create/upload/edit handlers swallowed failures (e.g. a duplicate-name 409) silently, producing an unhandled rejection instead of feedback. Errors now show via toast.error.
  • Editing a binary file's metadata no longer wipes its content. Binary content is stripped to '' in API responses; saving a description edit round-tripped that empty string back into the stored payload (data loss — the next sync would write an empty file). The UI now omits content for binary files on save, and the API rejects empty content on binary rows with a 400 backstop.

A cluster of database-monitoring bugs found while investigating empty metrics on live environments:

  • Empty Postgres charts / raw-byte Top Tables. node-postgres returns int8/bigint/numeric columns as strings to avoid precision loss, but several consumers checked typeof value === 'number' and dropped them. A shared coerceNumeric() is now applied both at collection and on the history read-path, so existing string data renders immediately and Top Tables shows human-readable sizes (3.8 MB).
  • Only one database's Top Tables rendered. When databases collect a few milliseconds apart, history timestamps form a union and the UI read the rows snapshot at the global last index — dropping every database except whichever collected last. The read now scans back to each database's own latest non-null snapshot.
  • Redis "No metrics data collected yet". The monitoring path omitted the username that ping/backup already send, so AUTH failed on restricted-ACL managed Valkey/Redis and the socket dropped. Username is now passed through; password-only credentials are unaffected.
  • Cold-start empty states. A transient first-load failure (backend warming up) latched a misleading "No metrics available" with no retry. The initial load now retries with bounded exponential backoff, keeping skeletons up — fixing Servers, Services, and Databases uniformly.

The View Logs modal opened scrolled to the oldest entry instead of the most recent. Under React concurrent mode, the requestAnimationFrame scroll from #191 could run before the DOM commit, reading a stale height. The scroll is now driven from a useLayoutEffect keyed on the log data (guaranteed to run after commit, before paint), so first load pins to the newest entry and Load older preserves scroll position while walking backward.


Routine dependency maintenance — no functional or security-relevant changes:

  • Backend minor/patch group (9 updates): @aws-sdk/client-s3, @sentry/node, ioredis, mysql2, nodemailer, vitest, tsx, others (#196)
  • Frontend minor/patch group (7 updates): @sentry/react, date-fns, react-router-dom, zustand, vite, vitest (#195)
  • GitHub Actions version group: actions/download-artifact v7→v8, actions/github-script v8→v9 (#194)
    -----BEGIN SSH SIGNATURE-----
    U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgEyiv4hf6iBgr34ICjN6HnEP/vs
    Yr31eNU5HhdkQaYd4AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
    AAAAQCl9F46hsFQJWnAWb49M6a1OLr4eQMrmAuaMa2At0m0PZ9wbCgfuJaEEDCogMGujlJ
    JEEpAHQqKfjZjpiB1dvQ0=
    -----END SSH SIGNATURE-----