Skip to content

fix(adif): round-trip satellite and IOTA fields on import/export - #231

Merged
patrickrb merged 1 commit into
mainfrom
optio/task-7d07c732-7e16-4a6c-b88c-449c2be90472
Jul 23, 2026
Merged

fix(adif): round-trip satellite and IOTA fields on import/export#231
patrickrb merged 1 commit into
mainfrom
optio/task-7d07c732-7e16-4a6c-b88c-449c2be90472

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

Problem

Every contact row carries prop_mode, sat_name, band_rx, freq_rx and iota columns, but the ADIF import/export path ignored all five:

  • Satellite QSOs lost their identity on export. A satellite contact exported from Nextlog contained no PROP_MODE=SAT, SAT_NAME, FREQ_RX or BAND_RX, so LoTW/eQSL couldn't credit it toward satellite awards and downstream loggers (GridTracker, SatPC32, N1MM) saw a bare terrestrial QSO.
  • IOTA references never round-tripped. Island-on-the-Air chasers who imported or entered an IOTA reference lost it the moment they re-exported.
  • Import silently dropped the same fields, so even an ADIF file that did carry satellite/IOTA data was flattened on the way in.

Solution

Extend the shared ADIF serializer/parser used by every import and export path:

  • generateAdif() now emits PROP_MODE, SAT_NAME, BAND_RX, FREQ_RX and IOTA. Designators and bands are uppercased to match the existing BAND/GRIDSQUARE handling.
  • insertAdifRecord() persists the same five fields on import, and derives BAND_RX from FREQ_RX when only the receive frequency is present — mirroring the existing FREQ → BAND fallback so satellite ops who send just the downlink frequency still land on the right receive band.
  • AdifExportContact gains the five typed fields.
  • /api/adif/export adds the columns to its explicit SELECT. The search-results export (/api/contacts/search?export=true) already uses SELECT *, so it inherits them automatically.

No schema change — the columns already exist. Fully backwards compatible: contacts without these fields export exactly as before (empty values are omitted by adifField).

Testing

  • npm run typecheck — clean
  • npm run lint — clean
  • npm run build — succeeds
  • npx playwright test adif-generate adif-parse16 passed, including two new cases:
    • satellite/split/IOTA fields are emitted and uppercased (<prop_mode:3>SAT, <sat_name:5>SO-50, <band_rx:4>70CM, <freq_rx:7>435.795, <iota:6>NA-001)
    • the fields survive a generate → parse round trip

Future follow-up

  • insertAdifRecord covers the import mapping but is DB-backed, so it isn't unit-tested here; an integration test against a seeded DB would guard the round trip end-to-end.
  • The new-contact / edit-contact UI forms don't yet expose satellite/IOTA inputs — a natural next step now that the storage and interchange path is complete.

🤖 Generated with Claude Code

… and IOTA fields

The contacts table stores prop_mode, sat_name, band_rx, freq_rx and iota, but
the ADIF import/export path never touched them: exported satellite QSOs lost
their bird and propagation identity (breaking LoTW/eQSL satellite awards and
GridTracker/SatPC32 interop) and IOTA references never round-tripped.

- generateAdif now emits PROP_MODE, SAT_NAME, BAND_RX, FREQ_RX, IOTA
  (designators/bands uppercased like BAND and GRIDSQUARE).
- insertAdifRecord persists the same fields on import, deriving BAND_RX from
  FREQ_RX when only the receive frequency is supplied (mirrors FREQ->BAND).
- /api/adif/export SELECT now returns the five columns; the search-results
  export already used SELECT * so it inherits them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 23, 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 23, 2026 9:06pm

Request Review

@patrickrb
patrickrb merged commit c18dba0 into main Jul 23, 2026
5 checks passed
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.

1 participant