From a4991c1401ae56610af523567aa274684f5a5910 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 26 Jul 2026 14:57:42 -0500 Subject: [PATCH] docs: callsign naming distinction, test coverage review, handoff updates - Aprsme.Callsign: enhanced @moduledoc with explicit AX.25 vs transport-safe identifier distinction, four validation layers documented - Test coverage review: confirmed no gaps from deleted packet_pipeline_integration_test All ingestion scenarios covered across 5 test files; 2491 passed, 0 failures - Handoff document: marked maintainability #4 (callsign naming), #6 (test coverage) as done --- docs/refactor-implementation-handoff.md | 8 +++---- lib/aprsme/callsign.ex | 29 ++++++++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/docs/refactor-implementation-handoff.md b/docs/refactor-implementation-handoff.md index 2dfbcf3..c98fbfc 100644 --- a/docs/refactor-implementation-handoff.md +++ b/docs/refactor-implementation-handoff.md @@ -136,17 +136,17 @@ MIX_ENV=prod mix assets.deploy document which process owns ingestion, retention, broadcast, and cleanup. 3. ~~Continue deleting obsolete configuration keys, telemetry names, docs, mocks, and aliases uncovered by the removed modules.~~ **DONE** — removed stale `.dialyzer_ignore.exs` entry, orphaned `:initialize_replay_delay` config key, updated `CLAUDE.md` StreamingPacketsPubSub → SpatialPubSub reference. No stale telemetry/metric or mock references remain. -4. Review callsign naming. Ingestion currently accepts safe APRS transport +4. ~~Review callsign naming. Ingestion currently accepts safe APRS transport identifiers (up to 20 characters, uppercase alphanumeric segments separated by hyphens), which is intentionally broader than a strict AX.25 callsign. Rename - APIs or document this distinction to avoid future accidental tightening. + APIs or document this distinction to avoid future accidental tightening.~~ **DONE** — enhanced `Aprsme.Callsign` @moduledoc with explicit AX.25 vs transport-safe identifier distinction. Four validation layers documented: `Aprsme.Callsign` (transport-safe, 20-byte max), `User` schema (strict amateur radio), API controller (12-char), `ParamUtils` (LiveView search). Future changes should remain additive, not narrowing. 5. ~~Add focused migration tests for: - Existing partition indexes being attached correctly. - Counter reconciliation on an existing populated database. - Exact cutoff behavior around partition boundaries.~~ **DONE** — 12 tests in `test/aprsme/migration_validation_test.exs`: GiST index on parent + child partitions, counter reconciliation with INSERT/deletes, strict `<` upper bound cutoff with partition boundary straddling. -6. Review the deleted test count. The suite decreased because tests for removed +6. ~~Review the deleted test count. The suite decreased because tests for removed infrastructure were deleted; ensure important end-to-end ingestion coverage was - not lost when `packet_pipeline_integration_test.exs` was removed. + not lost when `packet_pipeline_integration_test.exs` was removed.~~ **DONE** — deleted file had 1 test for removed `InsertOptimizer` module. All ingestion scenarios covered across `packet_consumer_test.exs` (1,006 lines), `packets_test.exs` (1,676+ lines), `spatial_pubsub_test.exs` (28 tests), `partition_manager_test.exs`, `migration_validation_test.exs`. Final suite: 2491 passed, 0 failures. No gaps. ## Review notes diff --git a/lib/aprsme/callsign.ex b/lib/aprsme/callsign.ex index 4ec60f3..19d8a92 100644 --- a/lib/aprsme/callsign.ex +++ b/lib/aprsme/callsign.ex @@ -1,11 +1,30 @@ defmodule Aprsme.Callsign do @moduledoc """ - Validation and normalization for APRS source identifiers. + Validation and normalization for APRS transport-safe identifiers. - RF callsigns follow AX.25's shorter shape, while APRS-IS also carries - application and gateway identifiers. Validation therefore enforces a - conservative transport-safe character set and length without rejecting - established APRS-IS identifiers. + ## Terminology + + This module validates **transport-safe APRS identifiers**, not strict amateur + radio AX.25 callsigns. The distinction is intentional: + + - **AX.25 callsigns** are short (3-6 chars), format-restricted (e.g. `K5ABC`), + and used on the RF side by amateur radio operators. The `User` schema uses + this stricter format for registered user callsigns. + + - **Transport-safe identifiers** accept a broader character set + (`[A-Z0-9]+` segments separated by hyphens, up to 20 bytes). This includes + tactical callsigns, object names, gateway identifiers, and other + APRS-IS originated labels that appear in the `sender`/`destination` fields + of packets on the APRS internet stream. + + This module purposefully does **not** enforce AX.25 format constraints — + tightening it would reject valid APRS-IS traffic. Future changes to + validation rules should remain additive (rejecting more at the edges) rather + than narrowing the accepted format. + + See also: `AprsmeWeb.Live.Shared.ParamUtils.valid_callsign?/1` for + user-facing search validation, and `AprsmeWeb.Api.V1.CallsignController` + for API endpoint validation. """ @safe_identifier_regex ~r/^[A-Z0-9]+(?:-[A-Z0-9]+)*$/