feat(log): QSO number column, oldest contact = 1

Not the id: the primary key follows insertion order, so importing an old ADIF
gives the oldest contacts the highest ids. This is a rank over qso_date.

Computed over the WHOLE log, not the query result — ranking inside the result
would renumber every contact the moment a filter is applied, and QSO #1 would
change identity as the operator typed.

Held as one id-to-rank map, built from a single ordered id query and dropped
with the other derived indexes when the log changes. A contact logged from the
entry form is the newest, so it takes the next number without rereading the
log: AddQSO deliberately avoids full invalidation because a contest run would
pay for it once per QSO. A contact entered with an OLDER date belongs in the
middle of the order, so there the map is dropped and rebuilt rather than
mis-numbered.
This commit is contained in:
2026-08-13 00:31:38 +02:00
parent 3c8aadf41f
commit 62256942a1
7 changed files with 230 additions and 6 deletions
+2
View File
@@ -4206,6 +4206,7 @@ export namespace qso {
}
export class QSO {
id: number;
number?: number;
callsign: string;
// Go type: time
qso_date: any;
@@ -4346,6 +4347,7 @@ export namespace qso {
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.id = source["id"];
this.number = source["number"];
this.callsign = source["callsign"];
this.qso_date = this.convertValues(source["qso_date"], null);
this.qso_date_off = this.convertValues(source["qso_date_off"], null);