Entrant per-QSO confirmation view (checklist A) #7

Merged
kiro_agent merged 1 commit from feature/entrant-qso-confirmation-view into main 2026-10-25 13:39:43 +00:00
Owner

What was built

The per-QSO confirmation view (checklist A, items A1-A7): a display-only feature that shows the entrant each individual QSO after upload, as a simple confirmation check that the upload parsed correctly. This is advisory / display-only — there is NO scoring or flag-computation logic change. The table is a pure advisory recompute reusing existing primitives; persisted is_multiplier is trusted so the display equals the score basis.

  • A1: full per-QSO table (date, time, band, worked call, sent RST+serial, received RST+serial, received locator) on the preview; the per-band summary is kept alongside it.
  • A2: per-row status markers (Multiplier; OUT_OF_TIME, DUP_BAND, NON_DUTCH_LOCATOR, UNKNOWN_LOCATOR, ADIF_MISSING_FIELD). SECTION_MISMATCH / SERIAL_RULE render as a log-level banner, not per row.
  • A3: same table on the confirmation + stored Entry view, built from stored QSO rows.
  • A4: table as the primary sub-view on /manager/entry/{id}; dashboard stays a compact list.
  • A5: new UI strings via get_translator in nl.po/en.po; flag-type labels and jargon native in both catalogs (R30). Works for Cabrillo / EDI / ADIF.
  • New files: app/web/qso_view.py (pure helper), app/web/templates/_qso_table.html (shared partial), tests/test_web_qso_view.py.

Where the per-QSO table appears

  • Entrant preview (before submit) — alongside the existing per-band summary.
  • Entrant confirmation / stored-entry view — built from the persisted QSO rows.
  • Manager drill-in — the /manager/entry/{id} page.

How the manager side avoids the all-inline mess

The per-QSO table lives on the drill-in page (/manager/entry/{id}), not inline on the dashboard. Any dashboard collapse defaults collapsed, so /manager stays a compact list rather than a large mess of every entrant's full QSO table on one page.

Corpus-based verification results (A6)

Rendered via TestClient against the example test-corpus:

  • 01 (clean Cabrillo) preview: 6 rows, all 6 Dutch rows marked multiplier, no banner, no NON_DUTCH / UNKNOWN row markers.
  • 02 (EDI) preview: 6 rows render with 6 multiplier markers (format coverage).
  • 08 (foreign + unknown locators, Cabrillo) preview: JN49MR + JO40AA → NON_DUTCH_LOCATOR (2), ZZ99ZZ → UNKNOWN_LOCATOR (1); only the Dutch JO21GW row marked multiplier.
  • 09 (ADIF-missing-fields) preview: PE9K + PA2JCB → ADIF_MISSING_FIELD (2), PA2JCB → UNKNOWN_LOCATOR, complete PI4ZHE row marked multiplier.
  • Manager drill-in (08 stored, Section D): same per-row markers present.
  • Dashboard: per-QSO table header absent (compact list preserved).

Multiplier rows are asserted where the received locator is Dutch (e.g. JO21GW in 08, PI4ZHE in 09).

Bilingual proof (R30)

A column header renders Dutch by default and English after switching: "Ontvangen locator" (nl) / "Received locator" (en). Jargon terms (QSO / locator / multiplier) are identical in both catalogs; flag-type label NON_DUTCH_LOCATOR is identical in both.

Test suite

Full pytest suite passes: 147 passed, 1 warning (baseline 139 + 8 new A7 tests; no regressions). Targeted run (qso_view + entrant + manager + i18n): 44 passed.

Review note

Do NOT merge — the user reviews this PR.

## What was built The per-QSO confirmation view (checklist A, items A1-A7): a **display-only** feature that shows the entrant each individual QSO after upload, as a simple confirmation check that the upload parsed correctly. This is **advisory / display-only** — there is **NO scoring or flag-computation logic change**. The table is a pure advisory recompute reusing existing primitives; persisted `is_multiplier` is trusted so the display equals the score basis. - **A1**: full per-QSO table (date, time, band, worked call, sent RST+serial, received RST+serial, received locator) on the preview; the per-band summary is kept alongside it. - **A2**: per-row status markers (Multiplier; OUT_OF_TIME, DUP_BAND, NON_DUTCH_LOCATOR, UNKNOWN_LOCATOR, ADIF_MISSING_FIELD). SECTION_MISMATCH / SERIAL_RULE render as a log-level banner, not per row. - **A3**: same table on the confirmation + stored Entry view, built from stored QSO rows. - **A4**: table as the primary sub-view on /manager/entry/{id}; dashboard stays a compact list. - **A5**: new UI strings via get_translator in nl.po/en.po; flag-type labels and jargon native in both catalogs (R30). Works for Cabrillo / EDI / ADIF. - New files: app/web/qso_view.py (pure helper), app/web/templates/_qso_table.html (shared partial), tests/test_web_qso_view.py. ## Where the per-QSO table appears - **Entrant preview** (before submit) — alongside the existing per-band summary. - **Entrant confirmation / stored-entry view** — built from the persisted QSO rows. - **Manager drill-in** — the /manager/entry/{id} page. ## How the manager side avoids the all-inline mess The per-QSO table lives on the drill-in page (/manager/entry/{id}), **not** inline on the dashboard. Any dashboard collapse defaults **collapsed**, so /manager stays a compact list rather than a large mess of every entrant's full QSO table on one page. ## Corpus-based verification results (A6) Rendered via TestClient against the example test-corpus: - **01 (clean Cabrillo)** preview: 6 rows, all 6 Dutch rows marked multiplier, no banner, no NON_DUTCH / UNKNOWN row markers. - **02 (EDI)** preview: 6 rows render with 6 multiplier markers (format coverage). - **08 (foreign + unknown locators, Cabrillo)** preview: JN49MR + JO40AA → NON_DUTCH_LOCATOR (2), ZZ99ZZ → UNKNOWN_LOCATOR (1); only the Dutch JO21GW row marked multiplier. - **09 (ADIF-missing-fields)** preview: PE9K + PA2JCB → ADIF_MISSING_FIELD (2), PA2JCB → UNKNOWN_LOCATOR, complete PI4ZHE row marked multiplier. - **Manager drill-in** (08 stored, Section D): same per-row markers present. - **Dashboard**: per-QSO table header absent (compact list preserved). Multiplier rows are asserted where the received locator is Dutch (e.g. JO21GW in 08, PI4ZHE in 09). ## Bilingual proof (R30) A column header renders Dutch by default and English after switching: "Ontvangen locator" (nl) / "Received locator" (en). Jargon terms (QSO / locator / multiplier) are identical in both catalogs; flag-type label NON_DUTCH_LOCATOR is identical in both. ## Test suite Full pytest suite passes: **147 passed, 1 warning** (baseline 139 + 8 new A7 tests; no regressions). Targeted run (qso_view + entrant + manager + i18n): 44 passed. ## Review note **Do NOT merge** — the user reviews this PR.
Add a shared, display-only per-QSO table to the entrant preview, the entrant
confirmation/stored-Entry view, and the manager drill-in. Pure advisory
recompute reusing existing primitives; no scoring or flag-computation logic
changed.

- A1: full per-QSO table (date, time, band, worked call, sent RST+serial,
  received RST+serial, received locator) on preview; per-band summary kept.
- A2: per-row status markers (Multiplier; OUT_OF_TIME, DUP_BAND,
  NON_DUTCH_LOCATOR, UNKNOWN_LOCATOR, ADIF_MISSING_FIELD). SECTION_MISMATCH /
  SERIAL_RULE render as a log-level banner, not per row.
- A3: same table on confirmation + stored Entry, built from stored QSO rows
  (trusts persisted is_multiplier so display equals score basis).
- A4: table as the primary sub view on /manager/entry/{id}; dashboard stays a
  compact list (no inline expansion).
- A5: new UI strings via get_translator in nl.po/en.po; flag-type labels and
  jargon native in both catalogs (R30). Works for Cabrillo/EDI/ADIF.
- New: app/web/qso_view.py (pure helper), app/web/templates/_qso_table.html
  (shared partial), tests/test_web_qso_view.py.

Verification (venv python -m pytest, cwd worktree):
- Full suite: 147 passed, 1 warning (baseline 139 + 8 new A7 tests; no
  regressions). Output: /tmp/pytest-qso-view.txt.
- Targeted (qso_view + entrant + manager + i18n): 44 passed.
- Corpus render proof via TestClient (A6):
  * 01 Cabrillo preview: 6 rows, all 6 Dutch rows marked multiplier, no banner,
    no NON_DUTCH/UNKNOWN row markers.
  * 02 EDI preview: 6 rows render with 6 multiplier markers (format coverage).
  * 08 Cabrillo preview: JN49MR + JO40AA -> NON_DUTCH_LOCATOR (2), ZZ99ZZ ->
    UNKNOWN_LOCATOR (1), only the Dutch JO21GW row marked multiplier.
  * 09 ADIF preview: PE9K + PA2JCB -> ADIF_MISSING_FIELD (2), PA2JCB ->
    UNKNOWN_LOCATOR, complete PI4ZHE row marked multiplier.
  * Manager drill-in (08 stored, Section D): same per-row markers present.
  * Dashboard: per-QSO table header absent (compact list preserved).
  * Bilingual: "Ontvangen locator" (nl) / "Received locator" (en);
    NON_DUTCH_LOCATOR identical in both.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
public/vrza-contestrobot!7
No description provided.