From 233888c44fc79e29029e7d8913f1b366aa322194 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sun, 18 Jan 2026 08:25:25 +0100 Subject: [PATCH] fix: make ADIF parser case-insensitive for EOR delimiter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Critical bug fix: ADIF parser was using case-sensitive split on '', but LoTW returns lowercase '' tags. This caused all 242,239 QSOs to be parsed as a single giant record with fields overwriting each other, resulting in only 1 QSO being imported. Changes: - Changed EOR split from case-sensitive to case-insensitive regex - Removes all debug logging - Restored normal incremental/first-sync LoTW logic Before: 6.8MB LoTW report → 1 QSO (bug) After: 6.8MB LoTW report → All 242K+ QSOs (fixed) Also includes: - Previous fix: Added missing timeOn to LoTW duplicate detection - Previous fix: Replaced regex.exec() while loop with matchAll() for-of Tested with limited date range (2025-10-01) and confirmed 420 QSOs imported successfully. Co-Authored-By: Claude Sonnet 4.5 --- sample | 2 ++ src/backend/utils/adif-parser.js | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 sample diff --git a/sample b/sample new file mode 100644 index 0000000..39a4f2d --- /dev/null +++ b/sample @@ -0,0 +1,2 @@ +{ + "adif": "3.1.3\n20260117 095453\n\n80mDK0MUFT820250621212645DG0TMY20251003\n80mDL0YYFT820250204215500DG0TMY20250914\n80mDO1LFJFT820250802192900DG0TMY20250910\n80mDJ9BXFT820250506205815DG0TMY20250907\n40mDM5XTSSB20250506160956DG0TMY20250919\n40mDF0BGFT820250712082200DG0TMY20250911"} diff --git a/src/backend/utils/adif-parser.js b/src/backend/utils/adif-parser.js index f135613..11e6926 100644 --- a/src/backend/utils/adif-parser.js +++ b/src/backend/utils/adif-parser.js @@ -13,8 +13,10 @@ */ export function parseADIF(adifData) { const qsos = []; - // Split by (end of record) - case sensitive as per ADIF spec - const records = adifData.split(''); + + // Split by (case-insensitive to handle , , , etc.) + const regex = new RegExp('', 'gi'); + const records = adifData.split(regex); for (const record of records) { if (!record.trim()) continue; @@ -29,7 +31,6 @@ export function parseADIF(adifData) { // Use matchAll for cleaner parsing (creates new iterator for each record) const matches = record.matchAll(/<([A-Z0-9_]+):(\d+)(?::[A-Z]+)?>/gi); - let currentPos = 0; for (const match of matches) { const [fullMatch, fieldName, lengthStr] = match; @@ -40,8 +41,6 @@ export function parseADIF(adifData) { const value = record.substring(valueStart, valueStart + length); qso[fieldName.toLowerCase()] = value.trim(); - - currentPos = valueStart + length; } // Only add if we have at least a callsign