Commit Graph
27 Commits
Author SHA1 Message Date
rouggy dd7b63c059 fix(awards): stack the reference validity dates, and prove the award fallback
Two dates side by side put each one in a half-width Field2, which spends 120px
on its label column — the second label overlapped the first input and the row
ran off the panel. The comment ten lines above says exactly this about the
group/subgroup fields; one per row, as everything else in this editor.

Also shows a far-future end date as open-ended. RDA carries 9999-12-31 as "no
end" and printing it back reads like a real deadline.

The claim that an empty per-reference window inherits the award's is now a
test rather than a comment: a QSO before the award's own ValidFrom does not
count for a reference that has no window of its own, and a narrower reference
window still applies on top.
2026-08-12 10:51:12 +02:00
rouggy 8fc6673611 fix(awards): apply the per-reference validity window
References are not forever: a park is delisted, a district merged, a castle
loses its number. A QSO made while the reference existed is a valid contact
and must keep counting; one made afterwards must not.

The JSON format did not need to change — ValidFrom/ValidTo were already on
awardref.Ref, already columns in award_references, already round-tripping
through export and import. They were simply never read: awardRefMetas dropped
them on the way into the engine, so nothing downstream could enforce them.
This carries them through and checks them in keepRefs.

Empty means the award's own window governs, which inScope already enforces for
every QSO in the award. That fallback is deliberately NOT duplicated per
reference — two places enforcing the same dates is two places for them to
disagree. The editor shows the award's dates as the hint under the boxes so
the operator can see what empty inherits.

Dates are compared as ISO strings rather than parsed times: the stored shape
is "2006-01-02", lexical order on it IS chronological, and this cannot fail on
a malformed value the way a parse can — a reference with a typo in its window
keeps counting instead of silently vanishing from an operator's totals.

The Explain trace names the date and the cutoff, because "did not count" on a
contact the operator remembers making is exactly when they need to be told it
is the reference that has a window, not their log that is wrong.
2026-08-12 10:43:23 +02:00
rouggy d33291b521 feat(awards): wire up the single-award export
Only the whole-catalogue bundle was reachable from the UI, so sharing one
award meant handing over every award you have — including the ones you edited
for yourself.

Nothing new was needed underneath: ExportAward(code) already existed and
already reads the definition AND its references from the database rather than
from the embedded catalog, which is the point (a WAPC is only worth sharing
because of the province list and city regexes the operator added). The English
and French strings existed too. Only the button was missing.

Kept distinct from the catalog publish next to it: that one stamps a version
and clears user_edited to seed a release, this one is a plain share and leaves
both alone, so the recipient's copy is correctly marked as someone else's work
instead of a pristine built-in that future catalog updates would overwrite.
2026-08-12 10:23:55 +02:00
rouggy 40f5960c76 feat(awards): implement the QRZ.com and Custom confirmation sources
The award editor offered five confirmation sources and Def's own doc comment
named five, but confirmed() had cases for three. "qrzcom" and "custom" fell
through the switch, so ticking either marked nothing as confirmed — the exact
failure the GrantCodes comment in this struct warns about: a checkbox that does
nothing is worse than no checkbox, because it is trusted.

QRZ.com reads qrzcom_qso_download_status, not the upload one: uploading a QSO
is us telling QRZ about it, which confirms nothing.

Custom names a field. Rather than a checkbox per external source, the Def gains
ConfirmField + ConfirmValue: any QSO field or ADIF extras key, and optionally
the comma-separated values that count. That one shape covers the three cases
asked for — the OpsLog card marker (APP_OPSLOG_QSL_RCVD), an arbitrary ADIF
tag, and a tag stamped by an imported club list — because all three end up as a
field on the QSO.

An empty ConfirmValue means any non-empty content confirms: the OpsLog marker
stores the date the card arrived, not a Y/N flag. A custom source naming NO
field confirms nothing, deliberately — the opposite default would silently mark
a whole logbook confirmed.
2026-08-09 02:11:24 +02:00
rouggy b202d98ae5 fix(awards): add a Prefix field to the primary QSOFIELDS search
Only OrRule had a Prefix ("prepended to each found reference", e.g. postal 74 →
D74); the primary search passed "" for prefix, so an award whose references are
D01/D02… couldn't prepend the D on its main rule — only on OR fallbacks. Add
Def.Prefix, pass it into the primary run(), and expose a Prefix input next to the
primary Leading/Trailing fields in the award editor.
2026-08-07 14:23:41 +02:00
rouggy a4623e9ea3 feat(awards): refuse an ambiguous match on one-reference awards
Two DARC DOKs are both called "Gießen" — two clubs share the town. Exact
matching finds both and both are right as far as the matcher can tell, so
it kept both and the operator got a QSO credited to a DOK that may well
have been the other one.

Picking one is not an option: it writes a reference into the log with no
evidence behind it. So a Def can now be marked one reference per QSO, and
an ambiguous match on such an award assigns none, names the candidates in
the trace and leaves the contact under missing references — where the
operator's choice now sticks (06e3437).

Off by default, and deliberately NOT a revival of the old `Multi` flag: a
field holding several references (an n-fer POTA activation, a VUCC grid
line) is several references, correctly, and stays that way.
2026-08-01 01:04:17 +02:00
rouggy ad02583ef7 fix: recognise the microwave bands — 10 GHz resolved to no band at all
Reported on 3 cm. cat.BandFromHz stopped at 23 cm, so a 10 GHz frequency came
back EMPTY — and an empty band is not cosmetic: the QSO is logged without one,
counts in no award slot, and exports with no BAND field. The low end was short
too (2190m / 630m / 560m).

Four band tables had to be extended because four exist: the CAT one, the award
plan in app.go, the cluster spot classifier, and the frontend's. Plus the places
that LIST bands — the QSO editor and award-definition pickers (you could not set
3 cm by hand either), the statistics axis, and the award band ORDER, where a
missing band sorts to the end instead of in frequency order.

Ranges and names are ADIF 3.1.7, which is what an export has to carry.

A test now pins one frequency per band across the Go tables and asserts they
agree — that is what was missing, four hand-maintained copies with nothing
checking them. It also pins that an out-of-band frequency stays empty rather
than snapping to the nearest band, which would file a QSO under a band the
operator never used.
2026-07-28 14:50:17 +02:00
rouggy 91b5af1c7b chore: release v0.21.3 2026-07-26 16:57:19 +02:00
rouggy 1b2da95ad4 ui: widen the Award management modal (max-w-6xl, 95vw) so the fuller footer fits 2026-07-20 14:35:18 +02:00
rouggy 8538f48259 feat: Publish-to-catalog export for awards (edit in UI, version, ship to team)
Adds ExportAwardForCatalog(code, version): writes the selected award as a
catalog-format JSON ({"def":…,"references":…}) stamped with a version and with
user_edited cleared, ready to paste over internal/award/catalog/<code>.json. A
new release then propagates the change to the whole team via mergeCatalog —
unedited copies auto-upgrade, edited ones are offered the update.

UI: a version input + "Publish to catalog…" button in the award editor footer,
defaulting to one past the award's current version.
2026-07-20 14:20:30 +02:00
rouggy 04b6431726 fix: Improved the code for awards 2026-07-14 16:42:48 +02:00
rouggy 0c6f8e2d68 feat: Added a test tab in awards to test the matching 2026-07-14 16:32:49 +02:00
rouggy 4fe0405432 feat: Allow updation of award catalog 2026-07-14 16:22:54 +02:00
rouggy 7f95a71426 feat: added Worked All Italian Provinces award and FFMA 2026-07-14 00:03:10 +02:00
rouggy 08f4b61523 feat: added FFMA award support 2026-07-13 22:18:25 +02:00
rouggy 656e238a59 feat: awards folder in the data folder, anybody can create its own awards. 2026-07-13 18:03:06 +02:00
rouggy c170d6091e feat: Reworked the awards logic so it is easy to add new ones. 2026-07-13 17:38:18 +02:00
rouggy 96390110f8 fix: Improved awards matches 2026-07-10 15:28:01 +02:00
rouggy daf38554a5 feat: Award column can now show either reference or description 2026-07-07 20:23:18 +02:00
rouggy 06183bd5d4 feat: Themes added, 4 themes available (3 dark, 1 light) 2026-07-06 09:08:47 +02:00
rouggy 2d742be7df feat: Complete translation in French 2026-07-05 10:44:40 +02:00
rouggy 69d0780bac feat: added versionning & About window 2026-06-16 19:36:56 +02:00
rouggy 16c04fc12b awards 2026-06-07 01:11:37 +02:00
rouggy 17f7a00bd7 up 2026-06-06 14:16:30 +02:00
rouggy 922a185208 up 2026-06-06 00:02:56 +02:00
rouggy 51d3a734e8 award 2026-06-05 22:35:28 +02:00
rouggy 88623f55df awards 2026-06-05 17:22:38 +02:00