Commit graph

1248 commits

Author SHA1 Message Date
2fc4706d3d
fix: stop silent packet loss, timer leak, and seq-scans
- packet_consumer: when a batch exceeds max_batch_size, carry the
  excess over to the next cycle instead of dropping it. Previously
  any overage was split off into a drop list that was only logged,
  losing packets the producer had already acknowledged.

- map_live: cancel the hover_end_timer in terminate/2 so a user
  disconnecting while a marker is still highlighted doesn't leave
  an orphaned timer behind.

- packet_consumer: rescue/log exceptions inside the async broadcast
  task so PubSub serialization bugs or outages are observable
  instead of silently killing the Task.

- prepared_queries: swap ST_Y/ST_X BETWEEN predicates for the && /
  ST_MakeEnvelope pattern so bounds queries hit the GIST index on
  packets.location instead of sequentially scanning.
2026-04-21 09:29:06 -05:00
FluxCD
acd596e172 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776781097-9aa836e [skip ci] 2026-04-21 14:18:41 +00:00
9aa836e462
refactor(map): share isValidCoordinate and unwrapLongitudes helpers
The coord-validation and antimeridian-unwrap logic added in the last
pass had been duplicated across map.ts, trail_manager.ts, and
info_map.ts. Move both into map_helpers.ts and import from there so
there is one authoritative implementation.
2026-04-21 09:17:52 -05:00
FluxCD
c41e47ed95 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776726355-e90226d [skip ci] 2026-04-20 23:06:18 +00:00
e90226dc21
fix(map): tighten edge cases in heatmap, info map, and trail color
- Heatmap: filter points with invalid coords or out-of-range intensity
  so malformed rows can't distort the layer.
- InfoMap: validate coords for range (not just NaN) and use an epsilon
  when comparing positions, so float noise doesn't cause needless
  re-renders or accept bogus data.
- TrailManager: getTrailCenter returns null for empty input instead of
  the ambiguous (0, 0) null-island; callers guard accordingly.
2026-04-20 18:05:31 -05:00
FluxCD
52418a7b41 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776726224-f777dcb [skip ci] 2026-04-20 23:04:07 +00:00
f777dcbb35
fix(map): stop trail spidering across antimeridian and close gaps
- Normalize longitude delta in trail_manager Haversine so wraps across
  180/-180 no longer compute a near-global distance and spuriously
  split the trail into short-segment-filtered pieces.
- Unwrap longitudes before building segments and drawing polylines in
  both the per-station TrailManager and the show_trail_line handler so
  a date-line crossing renders as a short hop instead of a line that
  wraps around the world.
- Raise maxHopDistance (10 -> 100 km) and drop minSegmentPoints (3 -> 2)
  so legitimate fast movers (aircraft, balloons) and short valid hops
  are drawn instead of being dropped.
- Unbind mousemove/mouseout handlers on a trail before removing it so
  queued events can't fire against discarded state.
- Fix self.isValidCoordinate TypeError in updateMarker (function is
  module-level, not on the hook) and add coord validation to
  show_trail_line.
- Null boundsTimer after clearTimeout for cleanup consistency.
2026-04-20 18:03:25 -05:00
FluxCD
0ed2dd3806 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776724752-4417961 [skip ci] 2026-04-20 22:39:43 +00:00
441796165b
k8s: wire RESEND_API_KEY env and drop to 1 replica
Registration emails were crashing the LiveView because RESEND_API_KEY
lived in aprs-secrets but was never injected into the container env,
so Resend.Swoosh.Adapter raised at delivery time after the user row
was already persisted.
2026-04-20 17:38:50 -05:00
31ea64aa6c
perf: reduce per-packet allocations in ingest pipeline
Drop the pre-insert aprs_messages broadcast in Is.dispatch (subscribers
already get a richer payload via postgres:aprsme_packets after insert).
Switch PacketsLive.CallsignView to the per-callsign packets:<CS> topic
so it only receives relevant packets instead of filtering every one.

In PacketConsumer: reuse the received_at stamped in Is.dispatch instead
of calling DateTime.utc_now/0 per packet; drop the duplicate struct_to_map
pass (Is.dispatch already handled it); fold coordinate validation and
Geo.Point construction into set_lat_lon + create_location_geometry so
coords are normalized once; extract device_identifier from the already-
normalized attrs; pre-build the broadcast payload once (identifier pick,
lat/lon aliases, routing callsign) so the async broadcast task no longer
does Map.drop/Map.merge per packet.

Rewrite PacketSanitizer.sanitize_packet / sanitize_data_map with Map.new/2
instead of Enum.reduce + Map.put — one allocation per packet instead of N.

Also compute has_weather in Packet.changeset/2 so direct-changeset inserts
(tests, backfills) populate it the same way the GenStage pipeline does.
2026-04-19 13:33:16 -05:00
FluxCD
753e4b3cf0 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776451638-5ab2ffc [skip ci] 2026-04-17 18:48:05 +00:00
5ab2ffc8f3
perf: replace per-row pg_notify trigger with elixir broadcast after batch insert 2026-04-17 13:46:51 -05:00
FluxCD
1b969f808a chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776451361-1788419 [skip ci] 2026-04-17 18:44:19 +00:00
1788419ae0
perf: drop redundant packet indexes, compute has_weather in elixir, tighten on_conflict target 2026-04-17 13:42:19 -05:00
FluxCD
19a71ea162 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776450708-4854157 [skip ci] 2026-04-17 18:32:40 +00:00
4854157ee9
feat: add sitemap.xml, api-catalog, and agent-discovery Link headers 2026-04-17 13:31:21 -05:00
FluxCD
b1afc36ec4 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776450324-0b178d4 [skip ci] 2026-04-17 18:26:13 +00:00
0b178d45ba
fix: unsubscribe from pubsub topics on LiveView terminate; catch-all handle_info in ConnectionManager 2026-04-17 13:24:58 -05:00
FluxCD
177b88c3f3 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776449833-ab29a3d [skip ci] 2026-04-17 18:18:08 +00:00
ab29a3dca5
fix: add handle_info/2 for distributed_packet messages in PacketDistributor 2026-04-17 13:16:46 -05:00
FluxCD
1edfd1d418 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776449330-0c50208 [skip ci] 2026-04-17 18:10:04 +00:00
0c50208e4f
fix: use string interpolation for SET statement_timeout instead of parameterized query 2026-04-17 13:08:25 -05:00
FluxCD
70902559ae chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1776449132-0f0cc0d [skip ci] 2026-04-17 18:05:37 +00:00
0f0cc0db88
fix: use github.token for git push in forgejo workflow 2026-04-17 13:05:04 -05:00
7b725206af
chore: add forgejo workflow for docker build and deploy 2026-04-17 12:59:28 -05:00
9c7c190979
chore: trigger CI rebuild 2026-04-17 12:46:28 -05:00
adaf9599e2
chore: update dependencies and fix pre-existing issues
Dep upgrades (mix deps.update --all):
- phoenix_live_view 1.1.27 → 1.1.28
- swoosh 1.23.1 → 1.25.0
- bandit 1.10.3 → 1.10.4
- credo 1.7.17 → 1.7.18
- hammer 7.2.0 → 7.3.0
- igniter 0.7.6 → 0.7.9
- and minor: fine, lazy_html, meck, mimerl
- removed stale lock entries: geocalc, gettext_pseudolocalize, gridsquare

Bug fixes surfaced during update:
- ETS cache tables were :protected (owned by Application master), preventing
  the Cache GenServer from writing; change to :public + write_concurrency
  so device/symbol/query caches actually work
- historical_dot_html returned Phoenix.HTML.safe tuple instead of plain string;
  symbol_html is JSON-encoded for JS so it must be binary
- String.slice always returns binary so the || "Unknown error" fallback was
  unreachable dead code (dialyzer guard_fail)
- Supervisor.which_children always returns a list so the _ -> branch in
  database_metrics was unreachable dead code (dialyzer pattern_match_cov)
- Add @type t :: %__MODULE__{} to User schema to resolve unknown_type in user_auth spec
- Extract nested if in leader_election to fix Credo nesting depth violation
- Update .dialyzer_ignore.exs: remove 2 stale entries, add false positives for
  Ecto.Multi/Gettext opaque types and Mix.Task PLT limitations
2026-04-15 14:07:29 -05:00
CI
54a7b2c0f2 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774646325-51d5107 [skip ci] 2026-03-27 21:20:35 +00:00
Claude
51d5107983
fix: inline regex module attributes to fix deprecation warning
Elixir 1.19 deprecates storing regexes in module attributes. Inline
@wx_preamble_pattern and @wx_field_patterns directly into their
respective functions to resolve the --warnings-as-errors CI failure.

https://claude.ai/code/session_01Ps7Zq3wiBur1RtRKN7JM6X
2026-03-27 16:18:27 -05:00
Claude
a8051ce247
fix: code review refinements
- RegexCache: change ETS table from :public to :protected for consistency
  with other tables, preventing uncontrolled writes bypassing GenServer
- MobileChannel: ensure_float now returns nil instead of the original
  unparsed string on parse failure, so validate_bounds properly rejects it
- map.ts: remove dead commented-out localStorage code
- map.ts: use instanceof HTMLAnchorElement instead of unsafe type cast
  in popup navigation handler
- TrailManager: add destroyed flag to prevent stale RAF and debounce
  callbacks from firing after destroy, and clean up hover timer on destroy

https://claude.ai/code/session_01Ps7Zq3wiBur1RtRKN7JM6X
2026-03-27 16:18:27 -05:00
CI
36a86114a7 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774568941-2300dcd [skip ci] 2026-03-26 23:50:42 +00:00
2300dcd69c
fix: stabilize moving station tracking 2026-03-26 18:48:43 -05:00
CI
d2cc7ffa4d chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774546637-bc82777 [skip ci] 2026-03-26 17:39:09 +00:00
bc82777d34
fix: close review findings 2026-03-26 12:36:50 -05:00
CI
a343febdd0 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774303163-288b9fb [skip ci] 2026-03-23 22:00:54 +00:00
288b9fbbb2
fix: address security vulnerabilities and concurrency issues
- Fix SQL injection in partition_manager, db_optimizer, and release.ex
- Fix XSS vulnerabilities with proper HTML escaping in LiveViews
- Add proper error handling for email delivery functions
- Fix race conditions with advisory locks and atomic operations
- Replace unsupervised spawn/Task.start with supervised alternatives
- Convert ETS operations to GenServer serialization for thread safety
- Change ETS tables from :public to :protected access
- Add client limits to prevent unbounded memory growth
- Add PubSub cleanup in GenServer terminate callbacks
- Fix device upsert to use atomic Repo.insert_all
2026-03-23 16:59:09 -05:00
CI
4477fdf615 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774294338-4644962 [skip ci] 2026-03-23 19:33:49 +00:00
464496222f
fix: harden frontend reconnect callbacks 2026-03-23 14:31:08 -05:00
CI
85858d8fd8 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774292943-512b7c4 [skip ci] 2026-03-23 19:10:31 +00:00
512b7c4fe9
fix: clean up map resize hook listeners 2026-03-23 14:08:30 -05:00
CI
be1c9f1038 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774291436-d1110ec [skip ci] 2026-03-23 18:45:38 +00:00
d1110eca38
fix: sanitize invalid map timestamps 2026-03-23 13:43:37 -05:00
c9e5ece185
fix: guard frontend theme storage access 2026-03-23 13:42:36 -05:00
d2fd0d181f
fix: harden frontend browser compatibility 2026-03-23 13:41:16 -05:00
CI
6e47d3b15c chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774286951-e048be1 [skip ci] 2026-03-23 17:30:40 +00:00
e048be18d1
fix: harden frontend hook lifecycle cleanup 2026-03-23 12:28:54 -05:00
CI
0b7b421c52 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1774219967-08880b1 [skip ci] 2026-03-22 22:54:21 +00:00
08880b1fcb
Fix CI: switch Docker cache from registry to inline
Registry cache export was failing with 500 errors from the container
registry. Inline cache embeds metadata in the image itself, avoiding
the separate cache manifest upload.
2026-03-22 17:52:30 -05:00
d234c313ca
fix: harden mobile channel numeric params 2026-03-22 17:36:09 -05:00
35962c195b
fix: guard device cache refresh when stopped 2026-03-22 17:31:54 -05:00