feat: skip QSOs with unchanged confirmation data
When syncing from LoTW/DCL, only update QSOs if confirmation data has changed. This avoids unnecessary database updates and makes it clear which QSOs actually changed. - LoTW: Checks if lotwQslRstatus or lotwQslRdate changed - DCL: Checks if dclQslRstatus, dclQslRdate, DOK, or grid changed - Frontend: Shows skipped count in sync summary Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -192,6 +192,7 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
|
||||
let addedCount = 0;
|
||||
let updatedCount = 0;
|
||||
let skippedCount = 0;
|
||||
const errors = [];
|
||||
const addedQSOs = [];
|
||||
const updatedQSOs = [];
|
||||
@@ -219,26 +220,41 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
.limit(1);
|
||||
|
||||
if (existing.length > 0) {
|
||||
// Update existing QSO with DCL confirmation and DOK data
|
||||
await db
|
||||
.update(qsos)
|
||||
.set({
|
||||
dclQslRdate: dbQSO.dclQslRdate,
|
||||
dclQslRstatus: dbQSO.dclQslRstatus,
|
||||
darcDok: dbQSO.darcDok || existing[0].darcDok,
|
||||
myDarcDok: dbQSO.myDarcDok || existing[0].myDarcDok,
|
||||
grid: dbQSO.grid || existing[0].grid,
|
||||
gridSource: dbQSO.gridSource || existing[0].gridSource,
|
||||
})
|
||||
.where(eq(qsos.id, existing[0].id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
const existingQSO = existing[0];
|
||||
|
||||
// Check if DCL confirmation or DOK data has changed
|
||||
const dataChanged =
|
||||
existingQSO.dclQslRstatus !== dbQSO.dclQslRstatus ||
|
||||
existingQSO.dclQslRdate !== dbQSO.dclQslRdate ||
|
||||
existingQSO.darcDok !== (dbQSO.darcDok || existingQSO.darcDok) ||
|
||||
existingQSO.myDarcDok !== (dbQSO.myDarcDok || existingQSO.myDarcDok) ||
|
||||
existingQSO.grid !== (dbQSO.grid || existingQSO.grid);
|
||||
|
||||
if (dataChanged) {
|
||||
// Update existing QSO with changed DCL confirmation and DOK data
|
||||
await db
|
||||
.update(qsos)
|
||||
.set({
|
||||
dclQslRdate: dbQSO.dclQslRdate,
|
||||
dclQslRstatus: dbQSO.dclQslRstatus,
|
||||
darcDok: dbQSO.darcDok || existingQSO.darcDok,
|
||||
myDarcDok: dbQSO.myDarcDok || existingQSO.myDarcDok,
|
||||
grid: dbQSO.grid || existingQSO.grid,
|
||||
gridSource: dbQSO.gridSource || existingQSO.gridSource,
|
||||
})
|
||||
.where(eq(qsos.id, existingQSO.id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
} else {
|
||||
// Skip - same data
|
||||
skippedCount++;
|
||||
}
|
||||
} else {
|
||||
// Insert new QSO
|
||||
await db.insert(qsos).values(dbQSO);
|
||||
@@ -274,6 +290,7 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
total: adifQSOs.length,
|
||||
added: addedCount,
|
||||
updated: updatedCount,
|
||||
skipped: skippedCount,
|
||||
addedQSOs,
|
||||
updatedQSOs,
|
||||
confirmed: adifQSOs.filter(q => q.dcl_qsl_rcvd === 'Y').length,
|
||||
|
||||
@@ -222,6 +222,7 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
|
||||
let addedCount = 0;
|
||||
let updatedCount = 0;
|
||||
let skippedCount = 0;
|
||||
const errors = [];
|
||||
const addedQSOs = [];
|
||||
const updatedQSOs = [];
|
||||
@@ -247,22 +248,34 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
.limit(1);
|
||||
|
||||
if (existing.length > 0) {
|
||||
await db
|
||||
.update(qsos)
|
||||
.set({
|
||||
lotwQslRdate: dbQSO.lotwQslRdate,
|
||||
lotwQslRstatus: dbQSO.lotwQslRstatus,
|
||||
lotwSyncedAt: dbQSO.lotwSyncedAt,
|
||||
})
|
||||
.where(eq(qsos.id, existing[0].id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
const existingQSO = existing[0];
|
||||
|
||||
// Check if LoTW confirmation data has changed
|
||||
const confirmationChanged =
|
||||
existingQSO.lotwQslRstatus !== dbQSO.lotwQslRstatus ||
|
||||
existingQSO.lotwQslRdate !== dbQSO.lotwQslRdate;
|
||||
|
||||
if (confirmationChanged) {
|
||||
await db
|
||||
.update(qsos)
|
||||
.set({
|
||||
lotwQslRdate: dbQSO.lotwQslRdate,
|
||||
lotwQslRstatus: dbQSO.lotwQslRstatus,
|
||||
lotwSyncedAt: dbQSO.lotwSyncedAt,
|
||||
})
|
||||
.where(eq(qsos.id, existingQSO.id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
} else {
|
||||
// Skip - same data
|
||||
skippedCount++;
|
||||
}
|
||||
} else {
|
||||
await db.insert(qsos).values(dbQSO);
|
||||
addedCount++;
|
||||
@@ -288,13 +301,14 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('LoTW sync completed', { total: adifQSOs.length, added: addedCount, updated: updatedCount, jobId });
|
||||
logger.info('LoTW sync completed', { total: adifQSOs.length, added: addedCount, updated: updatedCount, skipped: skippedCount, jobId });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
total: adifQSOs.length,
|
||||
added: addedCount,
|
||||
updated: updatedCount,
|
||||
skipped: skippedCount,
|
||||
addedQSOs,
|
||||
updatedQSOs,
|
||||
errors: errors.length > 0 ? errors : undefined,
|
||||
|
||||
Reference in New Issue
Block a user