D: live in-browser contest logging (logger, lifecycle, conversion, EDI export) #10
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/live-logging"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements checklist D1-D6: an entrant can log a contest live in the browser and the result is a normal Entry.
What this adds
The logger (D2). A single horizontal entry bar in the style of Wavelog: frequency first, band derived from it and never typed (432.2 MHz can never wear a 6m badge), mode restricted to the reglement's three modes (FM, SSB, CW - verified in the reglement, USB/LSB normalised to SSB, anything else refused server-side), call, RST sent/received, serials sent/received, other side's locator. Rows support true inline editing with a save/cancel pair, and a menu offering exactly Edit or Delete - no mimicked-green-dot affordances.
Session lifecycle (D3). The old
abandonedstate is gone; the owner called it a trap, and it was: it stranded the QSOs with no way back and no manager visibility. Ending a session now pauses it (ended), and the same callsign + PIN reopens the very same log. A session closes itself (closed, read-only) once the contest's submission window passes. Migration 0006 adds both states to the Postgres enum inside an autocommit block (ALTER TYPE cannot run in a transactional DDL step) and converts every legacyabandonedrow toended.Manager visibility (D2/D3). A live session is not an Entry, so it used to be invisible in the manager UI while sitting in the database. The dashboard now links to a read-only list per Monthly Contest (callsign, section, locator, state, QSO count, bands, last QSO, start time) with a read-only drill-in to the logged QSOs. No scoring, no flags, no mutations, and the page says these are not entries yet.
Conversion (D4).
/live/finishcollects only what a session cannot (email twice, PIN, Declaration, operator, address, afdeling) and callsingest_parsed_logwith a generated Cabrillo log - so scoring, flags, the one-Entry invariant and the raw-file-first rule all apply unchanged. The generated log is written todata/app/uploads/as the recovery anchor, so a live Entry stays rebuildable from raw files. Refusals: no QSOs, wrong PIN, mismatched emails, missing Declaration, closed submission window (a late log is a manager Override, which this path cannot perform).EDI export (D5). One REG1TEST file per band, because EDI is single-band by definition. Mode codes are IARU R1 (Vienna 1998) 4.12.2 values, checked against the standard after I got them wrong from memory: 6 = FM, 1 = SSB, 2 = CW; 4 is CW-TX/SSB-RX cross-mode and is never written for FM. Unknown modes become an empty column (allowed by the spec) instead of a wrong code. Lines are validated against the 75-character limit, and points are left unclaimed because the adjudicating software recomputes them. Downloadable by the manager from the entry page, and by the entrant from the conversion confirmation gated by the browser session rather than a PIN in the URL.
Verification
Deliberately not in this PR
Band.HIGHERcollapses everything above 440 MHz into one band, so EDI cannot declarePBandfor 23cm/6cm. Flagged in future-work as a Contest Manager question, not silently invented.Known issue this PR does not fix (needs a decision)
A second upload for the same contest + callsign + section replaces the first. Because EDI is natively one file per band, an entrant who uploads 2m and then 6m currently ends up with only the 6m QSOs. That predates this branch and is untouched here; it needs a decision (merge per band vs one Entry per band) before real EDI submissions arrive.
The manager was blind to live logging: sessions sat in the database and appeared nowhere in the UI, because a session is deliberately not an Entry. That is the wrong trade — during a contest night the manager should see who is active. - Dashboard: a "Live sessies (N)" link per Monthly Contest, only when sessions exist. - GET /manager/contest/{id}/sessions: callsign, section, own locator, state (bezig/gepauzeerd/gesloten/omgezet), QSO count, bands used, last QSO, start time. - GET /manager/contest/{id}/sessions/{session_id}: the logged QSOs read-only. - Strictly read-only and labelled as such: no scoring, no flags, no mutations, and the page says these are not entries yet. Tests: 256 (was 250) — manager-only access, list state and counts, detail QSOs, dashboard link, repeated views change nothing, unknown session redirects.