[feat](trx-logbook): work a contest, and record what came back #60

Merged
sjg merged 6 commits from feat/logbook-contest-and-qsl into main 2026-08-07 21:50:02 +02:00
2 changed files with 48 additions and 10 deletions
Showing only changes of commit d539ff96e5 - Show all commits
+24 -10
View File
@@ -453,23 +453,29 @@ put in the exchange there is nothing for it to write.
| `RigState` | `FREQ`, `BAND`, `MODE`/`SUBMODE`, and the rig id a QSO was made on | watch channel already in the frontend context |
| Client config `general.callsign` | `STATION_CALLSIGN`, and the default `OPERATOR` | already surfaced as `owner_callsign` in frontend meta |
| The QSO's own rig, and its position | `MY_GRIDSQUARE` | per-rig latitude and longitude already carried in the rig list |
| Server clock | `QSO_DATE`, `TIME_ON` in UTC | new `GET /logbook/now`, which also feeds the browser-clock check |
| Server clock | `QSO_DATE`, `TIME_ON` in UTC | new `GET /api/logbook/now`, which also feeds the browser-clock check |
| Decoder panels and map | a pre-filled entry: callsign, grid, and the report to offer | existing decode history; no new plumbing |
| `bandForHz` | `BAND` from a frequency | exists in `map-core.ts`; move to a shared module |
#### HTTP API
Under `/api/logbook`, as the recorder's endpoints are, because `/logbook` itself is the page:
the `/bookmarks` API and the bookmarks page already share a path, and whichever is registered
first wins.
| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/logbook` | Query: filters, paging |
| `POST` | `/logbook` | Add a QSO |
| `PUT` | `/logbook/{id}` | Edit |
| `DELETE` | `/logbook/{id}` | Delete |
| `GET` | `/logbook/export.adi` | ADIF export, honouring the current filter |
| `GET` | `/logbook/export.cbr` | Cabrillo export of a contest selection |
| `POST` | `/logbook/import` | Import, answering with counts: added, duplicate, rejected |
| `GET` | `/logbook/worked/{call}` | Worked-before: bands and modes |
| `GET` | `/logbook/now` | The server's UTC clock, for stamping entries and checking the browser's |
| `GET` | `/api/logbook` | Query: filters, paging |
| `POST` | `/api/logbook` | Add a QSO |
| `PUT` | `/api/logbook/{id}` | Edit |
| `DELETE` | `/api/logbook/{id}` | Delete |
| `GET` | `/api/logbook/export.adi` | ADIF export, honouring the current filter |
| `GET` | `/api/logbook/export.cbr` | Cabrillo export of a contest selection |
| `POST` | `/api/logbook/import` | Import, answering with counts: added, duplicate, rejected |
| `GET` | `/api/logbook/worked/{call}` | Worked-before: bands and modes |
| `GET` | `/api/logbook/statistics` | Contacts, stations and confirmations, per band |
| `GET` | `/api/logbook/now` | The server's UTC clock, for checking the browser's |
| `GET` | `/api/logbook/prefill` | The six fields an entry opens with |
Writes require the control role, as the rig endpoints do.
@@ -505,6 +511,8 @@ task and the rig is the instrument.
### Phases
All five are implemented.
| Phase | Lands |
|-------|-------|
| 1 | `trx-logbook`: `Qso`, the ADI reader and writer, round-trip tests against files from other loggers |
@@ -513,6 +521,12 @@ task and the rig is the instrument.
| 4 | Ham layout, pre-filled entry from a decode row or the map, worked-before |
| 5 | Contest exchange fields and Cabrillo export; QSL and LoTW/eQSL fields; per-band worked/confirmed statistics |
Two decisions phase 5 settled. The Cabrillo header cannot be derived from a log — how many
operators, how much power, what the score is claimed to be — so it comes from the operator,
with `SINGLE-OP`, `LOW`, `ALL` and `MIXED` behind it. And a confirmation counts from whichever
bureau answered: an award wants one card or one electronic match, not one of each, so a log
that counted them separately would tell the operator they were short of what they have.
### Decisions
**One station log, not one per rig.** Awards and uploads are per station callsign — DXCC, WAS
+24
View File
@@ -519,6 +519,30 @@ most the contact being written. It lives in your data directory by default;
`[trx-client.logbook].path` moves it, for a station that keeps its log on a
backed-up volume.
### Contests
The **Contest exchange** block on the entry holds the contest's name and the
serials — sent and received. Both stay between contacts, because they belong to
the session rather than to the contact just logged, and the serial sent counts
on by itself so it is not retyped forty times an hour. An exchange that is a
zone, a section or a name rather than a number is kept as written.
**Contest entry (Cabrillo)** exports the entry sponsors accept. Only the
contacts of the contest named there are included. The header — operator
category, power, claimed score — cannot be worked out from a log, so it is
yours to fill in; the defaults are single operator, low power, all bands, mixed
mode.
### Confirmations
The **QSL** column shows a tick when the other station has confirmed, and the
**Confirm** button on a row records a card that has arrived. A confirmation
counts from wherever it came: a paper card, LoTW or eQSL. An award wants one of
them, not all three, so the log does not ask for all three.
**Bands worked** counts, per band, the contacts made, the distinct stations
worked, and how many of those contacts are confirmed.
### Ham radio layout
The **Ham radio** operator layout opens on the logbook with the transceiver