[feat](trx-logbook): work a contest, and record what came back #60
Merged
sjg
merged 6 commits from 2026-08-07 21:50:02 +02:00
feat/logbook-contest-and-qsl into main
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d539ff96e5 |
[docs](trx-rs): write down how a contest and a confirmation are worked
CI / frontend (pull_request) Successful in 5m12s
CI / reuse (pull_request) Successful in 5s
CI / test (push) Successful in 8m0s
CI / lint (pull_request) Successful in 2m22s
CI / test (pull_request) Successful in 8m57s
CI / lint (push) Successful in 2m32s
CI / frontend (push) Successful in 4m13s
CI / reuse (push) Successful in 6s
The manual gains the contest exchange, the Cabrillo entry and the confirmations. The plan marks all five phases done, corrects the API paths to the /api/logbook they were built under -- /logbook is the page, and the bookmarks API already shadows its own page that way -- and records the two decisions phase 5 settled: that the Cabrillo header comes from the operator because no log can derive it, and that a confirmation counts from whichever bureau answered. The plan itself travels with this branch: it was written on a branch of its own that was never proposed for merge, and the earlier attempts to update it from the implementation branches were silent no-ops, because the edits did not assert that they had found what they were replacing. Refs #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |
||
|
|
ca5cd65c85 |
[docs](trx-rs): settle the logbook's remaining questions
The clock is the server's, as asked: it is the machine at the radio, where the browser may be a phone in another timezone with a clock nobody checked. When the two disagree by more than a second the panel says so, rather than logging a time the operator did not expect. The rest, decided against how logging is actually done: One station log, not one per rig. DXCC, WAS and LoTW count the callsign, not the radio, and a station worked on the second rig is still worked. The rig goes on the QSO as MY_RIG. Station location does follow the rig, though — these rigs can be in different places, so MY_GRIDSQUARE comes from the one that made the contact, which is what LoTW's station locations expect too. The operator is a per-QSO field set once per session. ADIF separates the callsign used on the air from the person at the key, and multi-operator stations rotate people through one station callsign. It defaults from the configured callsign, so a single operator never touches it. It cannot come from the session: the auth roles are control and rx, with nobody's name on them. The log file is configurable, defaulting to the user's data directory. Bookmarks sit in the config directory because they are settings and decode logs in the cache directory because they are disposable; a QSO log is irreplaceable, and cache directories get swept. Import collisions match on callsign, band, mode and a two-minute window. Loggers rarely agree to the second on the same QSO — one stamps the contact, the other the entry — so an exact-minute key duplicates half of what it is asked to merge. Two minutes absorbs that without swallowing a legitimate re-work, since contest rules forbid a second contact on the same band and mode. Times compare as instants so midnight matches, and modes are normalised or an imported SSB would miss our USB. That normalisation is now written down: a rig mode is not an ADIF mode. DIG is the one the rig cannot answer — a rig in DIG is in FT8 or FT4 depending on what is decoding — and WSPR never opens an entry at all, because hearing a beacon is not a contact. Refs #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |
||
|
|
a9e1e86fdc |
[docs](trx-rs): settle the logbook's panel, its prefill, and its formats
Three answers from the issue, folded into the proposal. The logbook is a panel of its own rather than a strip on the radio page, and it stands in every layout: a log can be kept without adopting the ham layout, and read while another is selected. The ham layout is then the arrangement that starts from it, with the radio controls around it. Prefill is exactly six fields — frequency, mode, rig name, time, callsign and locator — and nothing else. A signal report in particular stays empty: an FT8 SNR is not what was sent, and prefilling one would put a number in the log that nobody exchanged. The station's own callsign and locator are not per-entry fields at all; they are station identity, shown once at the top of the panel and written into the QSO from configuration. The file format was left to me. ADIF stays, because it is not one option among several: LoTW, eQSL, Club Log, QRZ and every other logger read it and nothing else, so a log that cannot write it cannot be uploaded, confirmed or moved. Nothing on disk is ADI regardless — the store is JSON Lines. The second format is Cabrillo 3.0, which ADIF cannot replace: contest logs are submitted in it and rejected in anything else. It lands with the contest exchange fields, since without a serial or a zone it has nothing to write. Refs #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |
||
|
|
76e33a91bb |
[docs](trx-rs): propose the logbook and the ham radio layout
Issue #54 asks for a ham radio layout and an ADIF logbook, with no detail behind either. This is what they would be: what the logbook has to hold, how it is stored, where ADIF is read and written, and which of the existing parts each half hangs off. Two things it settles before any code is written. The log is append-only JSON Lines rather than the whole-file dump the bookmarks use, because a station with forty thousand QSOs would rewrite megabytes to log one contact and lose the lot if the power went mid-dump. And a decode is not a QSO: the decoders only ever heard something, so a decoded callsign pre-fills an entry and never writes one. The layout is a fifth entry in the operator layouts that already exist, gated on the rig being able to transmit. Refs #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |
||
|
|
ee185b98bc |
[feat](trx-logbook): work a contest, and record what came back
Phase 5 of the logbook: the exchange, the entry sponsors take, and the confirmations an award counts. Contest fields go on the contact — the contest, the serials both ways as numbers and as words, and the zones — because an exchange is not always a number: a zone, a section or a name goes in as written. The serial sent and the contest stay between contacts, since they belong to the session and not to the contact just logged, and the serial counts on by itself rather than being retyped forty times an hour. Cabrillo 3.0 is written because ADIF cannot do this job: sponsors take Cabrillo and reject everything else. Its shape is not ADIF's either — the frequency is kilohertz below 30 MHz and a band designator above it, the modes are CW, PH, FM, RY and DG, and the contacts go oldest first, as a contest log is read. The 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 power, all bands and mixed behind it. QSL, LoTW and eQSL states are held as ADIF's single letters, and anything else is refused rather than written: a log that grew states of its own would be one no other program could read. A contact is confirmed when any one of the three says so — an award wants a card or an electronic match, not one of each, and counting them separately would tell the operator they were short of what they have. The bands report counts contacts, distinct stations and confirmations per band, ordered by wavelength as a band plan reads. Closes #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |
||
|
|
18b2d0efe6 |
[feat](trx-rs): keep a station log, and a layout to work the bands from
The logbook of issue #54, in the shape the proposal settled on. A new crate, trx-logbook, holds the contact, the ADIF reader and writer, the file, and the rules for telling one contact from two. ADIF because it is the only thing the ecosystem reads: LoTW, eQSL, Club Log, QRZ and every other logger take it and nothing else, so a log that cannot write .adi cannot be uploaded, confirmed or moved. The reader is forgiving in the ways real files are irregular -- lowercase tags, CRLF, missing header, unknown fields, a declared length that is the only thing ending a value -- and carries what it does not model through to the export, so a round trip does not strip what another program wrote. The file is JSON Lines, appended one line per contact. A log is the one thing here that cannot be regenerated, and the bookmark store's whole-file dump would rewrite megabytes to log one contact and lose all of them if the power went halfway; an append costs the record being written and no more, which a test tears a line in half to prove. Edits append revisions, deletes append tombstones, and the file compacts when the superseded outnumber the live. The panel is its own tab and stands in every layout. An entry opens with six fields and no more -- frequency, mode, rig name, time, and the callsign and locator of whatever decode it was started from. A report stays empty: an FT8 SNR is not what was sent. Times come from the server, because the browser may be a phone in another timezone, and the panel says so when the two disagree by more than a second. Worked-before answers as a callsign is typed. A decode is not a contact, so the Log button on an FT8 or APRS row opens an entry and logs nothing by itself. The ham layout is the fifth operator layout, opening on the logbook with the radio controls around it, offered only where the rig can transmit. Two bugs found on the way, both in code written here: a frequency of a whole number of megahertz ending in a zero rendered as a tenth of itself, in Rust and in TypeScript alike, because trimming trailing zeros from "20.000000" walks back through the point. The API also sits under /api/logbook rather than /logbook, so it cannot shadow its own page the way /bookmarks does. Closes #54 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7 Signed-off-by: Stan Grams <sjg@haxx.space> |