Skip to content

fix(logging): don't overwrite a contact's NULL power with 0 on edit#245

Merged
patrickrb merged 1 commit into
mainfrom
optio/task-3ed19184-9dbe-42e2-b3b0-29b3692e6f7b
Jul 24, 2026
Merged

fix(logging): don't overwrite a contact's NULL power with 0 on edit#245
patrickrb merged 1 commit into
mainfrom
optio/task-3ed19184-9dbe-42e2-b3b0-29b3692e6f7b

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

Problem

Follow-up to #244 (per-QSO transmit power). A code-review pass caught a data-corruption bug in the edit dialog that merged before the fix could be appended.

When you open an existing QSO that was logged without power, contacts.tx_pwr is NULL and arrives in the edit dialog as JSON null. The submit-time normalization only mapped undefined and '' to null:

tx_pwr:
  formData.tx_pwr === undefined || (formData.tx_pwr as unknown) === ''
    ? null
    : Number(formData.tx_pwr),

null matched neither guard, so it fell through to Number(null) — which is 0, not null. Saving any unrelated edit (e.g. a note) on such a QSO silently rewrote the column from NULL to 0. That also defeats the export's COALESCE(c.tx_pwr, s.power_watts) fallback introduced in #244: the QSO now exports 0 instead of the station's default power (and adifField omits a 0, so TX_PWR vanishes from the export entirely). The empty input box hides the corruption from the operator.

Fix

Treat null / undefined / blank / NaN uniformly as "clear to NULL":

tx_pwr:
  formData.tx_pwr == null ||
  (formData.tx_pwr as unknown) === '' ||
  Number.isNaN(Number(formData.tx_pwr))
    ? null
    : Number(formData.tx_pwr),

== null catches both a cleared input and a contact loaded with no power, so a NULL power stays NULL through an edit. A real value (including 0) still round-trips.

Testing

  • npm run typecheck — clean
  • npm run lint — clean
  • npm run build — compiled successfully (verified before push)
  • DB-free pure-function specs — all pass

🤖 Generated with Claude Code

A contact loaded without power arrives as JSON `null`. The edit-dialog submit
guard only mapped `undefined`/'' to null, so `null` fell through to
`Number(null) === 0` and rewrote the column from NULL to 0 on any save. That
also defeated the export's COALESCE(c.tx_pwr, s.power_watts) station-power
fallback. Treat null/undefined/blank/NaN uniformly as "clear to NULL".

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodelog Ready Ready Preview, Comment Jul 24, 2026 10:25am

Request Review

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.

Pull request overview

This PR fixes a data-corruption edge case in the Edit Contact dialog where a NULL per-QSO transmit power (contacts.tx_pwr) could be unintentionally rewritten to 0 on save due to Number(null) === 0. This preserves correct semantics for “no per-QSO power recorded” and keeps ADIF export fallback behavior (COALESCE(c.tx_pwr, s.power_watts)) intact.

Changes:

  • Normalize tx_pwr on submit so null, undefined, blank, and non-numeric values are all treated as “clear to NULL”.
  • Prevent accidental NULL → 0 conversion when editing a contact that originally had no per-QSO power set.
  • Expand inline comment to document the rationale and the export impact.

@patrickrb
patrickrb merged commit 48bad20 into main Jul 24, 2026
8 checks passed
@patrickrb
patrickrb deleted the optio/task-3ed19184-9dbe-42e2-b3b0-29b3692e6f7b branch July 24, 2026 14:25
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