Commit graph

945 commits

Author SHA1 Message Date
FluxCD
528c64bfbc chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771438938-f89eec8 [skip ci] 2026-02-18 18:23:03 +00:00
f89eec8877
Disable clustering with single replica 2026-02-18 12:21:58 -06:00
FluxCD
98d980ad6e chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771438634-87dc076 [skip ci] 2026-02-18 18:19:02 +00:00
87dc076220
Set APRS_HOST and APRS_PASSWORD env vars
Connect to 204.110.191.232 instead of the default dallas.aprs2.net.
runtime.exs now reads APRS_HOST (over APRS_SERVER) and APRS_PASSWORD
(over APRS_PASSCODE) so both naming conventions work.
2026-02-18 12:16:54 -06:00
FluxCD
15dd528e05 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771438486-46e01cd [skip ci] 2026-02-18 18:15:02 +00:00
46e01cdea1
Scale down to 1 replica until clustering is needed 2026-02-18 12:14:25 -06:00
FluxCD
75d1784a3b chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771438217-bd26556 [skip ci] 2026-02-18 18:12:01 +00:00
bd265564a2
Handle insufficient privileges in pg_stat_statements migration
Wrap CREATE EXTENSION in a PL/pgSQL DO block that catches
insufficient_privilege so the migration completes successfully
even when the DB user is not a superuser.
2026-02-18 12:09:56 -06:00
FluxCD
95c009db0d chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771437137-d886f5d [skip ci] 2026-02-18 17:53:42 +00:00
d886f5d987
Fix migration init container env vars and ConnectionMonitor crash
- Add missing env vars to migration init container (PHX_HOST, PORT,
  APRS_PORT, APRS_CALLSIGN, APRS_PASSCODE) so runtime.exs config
  provider doesn't fail due to Kubernetes service discovery injecting
  APRS_PORT as a full URL
- Guard ConnectionMonitor.accepting_connections?/0 with Process.whereis
  to avoid crashing when the GenServer isn't started (e.g. cluster
  enabled but no libcluster topologies configured)
2026-02-18 11:51:56 -06:00
FluxCD
e71034dd47 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771434255-a72d50c [skip ci] 2026-02-18 17:08:35 +00:00
a72d50ca52
Update dependency version constraints and lock file
Loosen version pins for gettext, phoenix, swoosh, and gridsquare to allow
patch/minor updates, and update lock file to pick up latest releases.
2026-02-18 11:03:56 -06:00
FluxCD
f1b3a00882 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771433746-a0f72cf [skip ci] 2026-02-18 16:56:34 +00:00
FluxCD
06d09b590e chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771368069-24c01d0 [skip ci] 2026-02-18 16:56:17 +00:00
a0f72cfd43
Run database migrations as init container on each deploy
Adds an init container that runs `bin/migrate` before app pods start,
ensuring migrations are applied on every deployment. Uses the existing
advisory lock in MigrationLock so only one pod runs migrations during
a rolling update.
2026-02-18 10:55:25 -06:00
FluxCD
f1ce1b1e03 chore: update aprs.me image to git.mcintire.me/graham/aprs.me:main-1771368069-24c01d0 [skip ci] 2026-02-17 22:52:19 +00:00
24c01d00b0
Trigger CI build 2026-02-17 16:40:51 -06:00
e3b9e61d3c
Remove Docker Hub login - only need Forgejo registry 2026-02-17 16:39:12 -06:00
8a093ee590
Match towerops CI pattern for Forgejo registry builds 2026-02-17 16:35:56 -06:00
091a9ee2f6
Fix Forgejo Actions workflow - use github.* compat context 2026-02-17 16:17:54 -06:00
19661abec0
Use Forgejo-native context variables instead of GitHub 2026-02-17 16:13:24 -06:00
db34470e90
Use built-in Forgejo token for registry auth 2026-02-17 16:12:57 -06:00
a637b3b87c
Add k8s deployment manifests and FluxCD GitOps config
Kubernetes manifests for deploying to home cluster in the aprs
namespace with Forgejo Actions CI pipeline for building and
pushing container images to git.mcintire.me registry.
2026-02-17 16:11:27 -06:00
4366fa36da
Refactor conditionals to use multi-clause pattern matching
Replace case/cond/if blocks with multi-clause function dispatch
and pattern matching in function heads across 9 modules:
- WeatherUnits: case to multi-clause unit_system/1, unit_labels via do_unit_labels/1
- PacketUtils: if to pattern match on %{"id" => id}, multi-clause threshold/callsign
- SetLocale: case to multi-clause extract_locale/1
- IPGeolocation: if/cond to pattern match on conn, binary prefix matching for private_ip?
- DeviceIdentification: cond to extracted pattern_matches?/2
- MobileChannel: cond to multi-clause do_callsign_match/2
- PacketProcessor: cond to dispatch_visibility/6 on {in_bounds, has_marker} tuple
- PacketManager: destructure packet_state in heads, multi-clause maybe_cleanup/3
- AprsSymbol: case/if to multi-clause get_table_id/1, normalize_symbol_code/1
2026-02-10 17:15:49 -06:00
6b624e1365
more tests 2026-02-09 17:21:16 -06:00
094a50d183
Add tests for 14 modules with 0% coverage
Adds test files for:
- AprsIsConnection (83% coverage)
- Cluster.PacketDistributor (100%)
- Cluster.PacketReceiver (100%)
- Cluster.Topology (100%)
- ConnectionMonitor (78%)
- DbOptimizer (90%)
- DynamicSupervisor (100%)
- ErrorHandler (89%)
- MigrationLock (90%)
- MockHelpers (100%)
- PacketConsumerPool (90%)
- PacketCounter (100%)
- PacketPipelineSetup (75%)
- PacketPipelineSupervisor (100%)

Uses stub repo modules to test MigrationLock lock contention
paths without real multi-session PostgreSQL advisory lock
contention.
2026-02-09 17:19:50 -06:00
9d9cd881c1
fix some tests 2026-02-09 15:32:09 -06:00
0eccbd2ac7
Fix all remaining cyclomatic complexity issues
Resolves the final 5 Credo cyclomatic complexity issues by:

1. packet.ex: Create get_field_value/2 helper function
   - Replaces all `data[:field] || data["field"]` patterns
   - Reduces complexity in put_equipment_fields (11 -> 9)
   - Reduces complexity in put_phg_fields (12 -> 9)
   - Reduces complexity in put_standard_parser_fields (11 -> 9)

2. query_builder.ex: Use SQL fragment for weather_only query
   - Replaces multiple Elixir `or` operators with single SQL fragment
   - Reduces complexity from 10 to within limits

3. packet_utils.ex: Use SQL fragment for weather check query
   - Replaces multiple Elixir `or` operators with single SQL fragment
   - Reduces complexity from 11 to within limits

All 71 Credo issues now resolved:
- 14/14 warnings ✓
- 14/14 design suggestions ✓
- 40/40 refactoring issues ✓
- 3/3 code readability issues ✓

100% Credo compliance achieved!
2026-02-09 13:20:54 -06:00
072b145e73
Reduce cyclomatic complexity in streaming_packets_pubsub
Extract bounds validation helpers to reduce complexity:

- streaming_packets_pubsub.ex: Extract validation helpers
  Creates all_bounds_numeric?/4, valid_latitude_range?/1,
  valid_longitude_range?/1
  Moves complex boolean conditions into readable helper functions
  Reduces complexity from 13 to within limits

Fixes 1 Credo cyclomatic complexity issue (5 remaining).
2026-02-09 13:16:35 -06:00
6653678860
Reduce cyclomatic complexity in high-complexity functions
Extract helper functions to reduce complexity in functions with
complexity 10-15:

- packet.ex: Extract add_symbol_data/2
  Moves symbol data extraction into separate function
  Reduces complexity from 10 to 9

- mobile_channel.ex: Extract bounds validation helpers
  Creates all_numeric?/4, valid_latitudes?/2, valid_longitudes?/2
  Moves complex boolean conditions into readable helper functions
  Reduces complexity from 15 to within limits

- historical_loader.ex: Extract packet_has_valid_coordinates?/1
  Moves coordinate validation logic with multiple conditions
  Reduces complexity from 15 to within limits

Fixes 3 more Credo cyclomatic complexity issues.
2026-02-09 13:15:17 -06:00
9784cee344
Reduce cyclomatic complexity in multiple files
Extract helper functions to reduce cyclomatic complexity:

- telemetry/database_metrics.ex: Extract emit_packets_table_telemetry/7
  Moves multiple || 0 operators into separate function
  Reduces complexity from 10 to within limits

- packet_utils.ex: Extract build_weather_check_query/1
  Moves Ecto query building with multiple or conditions
  Reduces complexity from 11 to within limits

- packet.ex: Extract merge_extracted_data/3
  Moves telemetry and parser data merging logic
  Reduces complexity from 11 to within limits

Fixes 3 Credo cyclomatic complexity issues (7 remaining).
2026-02-09 13:13:15 -06:00
5f369a3bed
Fix predicate function naming conventions
Rename predicate functions to follow Elixir style guide:
- Remove 'is_' prefix from predicate function names
- 'is_' prefix is reserved for guard-safe functions

Changes:
- ip_geolocation.ex: is_private_ip? → private_ip?
- ip_geolocation.ex: is_172_private_range? → in_172_private_range?
- leader_election.ex: is_pid_alive? → pid_alive?

Fixes 3 Credo code readability issues.
All Credo code readability issues now resolved.
2026-02-09 12:42:07 -06:00
c8bd85565c
Reduce cyclomatic complexity in callsign_json.ex
Extract device attribute addition into helper function to reduce
cyclomatic complexity from 10 to 9:

- callsign_json.ex: Extract add_device_attributes/2 helper
  Moves device.model, device.vendor, device.contact, and device.class
  attribute additions into separate function

This reduces complexity by isolating the && operators in a dedicated
helper function.

Fixes 1 Credo cyclomatic complexity issue (10 remaining).
2026-02-09 12:39:22 -06:00
41000e3482
Fix remaining nesting depth issues
Extracts nested logic into helper functions to comply with Credo
requirements (max nesting depth 2):

- data_builder.ex: Extract historical packet data building
  (build_historical_packet_data/2)
  Reduces depth 3 -> depth 2

- streaming_packets_pubsub.ex: Extract subscriber filtering and messaging
  (send_to_matching_subscribers/5)
  Removes conditional check by sending cleanup message unconditionally
  (GenServer handles empty list gracefully)
  Reduces depth 3 -> depth 2

- historical_loader.ex: Extract RF path station loading logic
  (maybe_load_rf_path_stations/3)
  Reduces depth 3 -> depth 2

- packet_processor.ex: Extract marker popup logic
  (send_marker_with_popup_check/2)
  Reduces depth 3 -> depth 2

Fixes all 4 remaining Credo nesting depth issues.
All nesting depth issues now resolved (0 remaining).
2026-02-09 12:37:38 -06:00
318eb30046
Fix additional nesting depth issues across multiple files
Extracts nested logic into helper functions to comply with Credo
requirements (max nesting depth 2):

- data_builder.ex: Extract historical packet distance filtering
  (filter_historical_by_distance/3, packet_far_enough_from_most_recent?/3)
  Reduces depth 5 -> depth 3

- streaming_packets_pubsub.ex: Extract subscriber message sending
  (send_to_subscriber_if_alive/3)
  Reduces depth 4 -> depth 2

- aprs_symbol.ex: Extract symbol code calculation
  (get_symbol_code_ord/1)
  Reduces depth 3 -> depth 2

- mobile_channel.ex: Extract subscription bounds update
  (update_subscription_bounds/2)
  Reduces depth 3 -> depth 2

- core_components.ex: Extract SVG tag class insertion
  (add_class_to_svg_tag/2)
  Reduces depth 3 -> depth 2

- info_live/show.ex: Extract row mapping for database queries
  (map_digipeater_row/2, map_station_heard_row/2)
  Reduces depth 3 -> depth 2 (2 instances)

Also updates .sobelow-skips with new line numbers from code changes.

Fixes 7 Credo nesting depth issues (2 remaining)
2026-02-09 12:32:42 -06:00
74a19b0640
Fix nesting depth issues in device_cache, packets, and spatial_pubsub
Reduces function nesting depth to comply with Credo requirements (max depth 2):

- device_cache.ex: Extract pattern matching logic into separate helpers
  (pattern_matches?/2, matches_wildcard_pattern?/2)

- packets.ex: Extract data sanitization logic into separate helpers
  (sanitize_data_extended_attr/1, deep_sanitize_map/1)
  Note: This refactoring improved robustness - invalid data_extended
  values now return validation errors instead of throwing exceptions

- spatial_pubsub.ex: Extract grid cell and client filtering logic
  (remove_client_from_grid_cell/3, update_grid_cell_after_removal/3,
  filter_clients_by_bounds/3, client_contains_point?/3)

- Update test expectation in packets_test.exs to match improved
  error handling behavior (validation_error vs storage_exception)

Fixes 3 Credo nesting depth issues (8 remaining)
2026-02-09 12:27:34 -06:00
d033e8af76
Eliminate complexity 72 monster in info_live/show.ex
Refactor decode_path_element from 217 lines with complexity 72 to clean helpers:
- Add @q_constructs module attribute with all 39 Q-construct descriptions
- Extract decode_wide_element/1 for WIDE digipeater patterns
- Extract decode_trace_element/1 for TRACE digipeater patterns
- Extract decode_relay_element/1 for RELAY digipeater patterns
- Extract decode_tcpip_element/1 for TCPIP gateway patterns
- Main function now has simple map lookup and pattern-based routing

Reduced from 217 lines to 66 lines while improving readability and maintainability.

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:20:45 -06:00
c30a1c55f7
Reduce cyclomatic complexity in weather callsign view
Simplify timestamp comparison and weather value formatting:
- Extract compare_timestamps with pattern matching for different types
- Remove duplicate formatter code (was a bug)
- Extract format_string_value and format_numeric_value helpers

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:10:56 -06:00
12cf324d4c
Reduce cyclomatic complexity in database metrics collection
Extract each metric collection into separate helper functions:
- collect_database_size: Database size metrics
- collect_connection_stats: Connection pool statistics
- collect_packets_table_stats: Table-level statistics
- collect_query_performance_stats: Query performance metrics
- collect_replication_lag: Replication lag metrics

This breaks down the complexity 27 function into manageable pieces.

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:08:37 -06:00
0f8b60c2f4
Reduce cyclomatic complexity in historical packet loader
Extract packet query logic into helper functions:
- query_historical_packets: Main query orchestration with error handling
- build_query_params: Build query parameters with callsign filtering
- maybe_include_latest_packet: Include latest packet for tracked callsigns

This breaks down the complex do_load_historical_batch function.

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:06:58 -06:00
52cb874f55
Reduce cyclomatic complexity in IP geolocation validation
Simplify private IP range checking by extracting helper functions:
- is_private_ip?: Check if IP is in private ranges
- is_172_private_range?: Properly check 172.16.0.0/12 range

This replaces 20+ String.starts_with? checks with intelligent range parsing.

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:03:42 -06:00
386cd756bb
Reduce cyclomatic complexity in packet telemetry parsing
Extract telemetry parsing logic into separate helper functions:
- parse_telemetry_seq: Handle sequence number parsing
- parse_telemetry_vals: Handle values array parsing
- normalize_telemetry_value: Normalize individual value types
- parse_integer_string: Parse integer from string

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 12:02:10 -06:00
0b5b50a13b
Reduce cyclomatic complexity in aprs_symbol and database_metrics
Simplify complex functions:
- aprs_symbol.ex: Simplify get_overlay_base_table_id (all cases return "1")
- database_metrics.ex: Extract metric reporting helpers to reduce nesting

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 11:59:46 -06:00
d48a3a291f
Reduce cyclomatic complexity in clustering, encoding, and leader_election
Simplify complex functions to improve readability and maintainability:
- clustering.ex: Convert case statement to map lookup for cluster radii
- encoding.ex: Extract codepoint validation into separate function clauses
- leader_election.ex: Extract PID liveness checking and cleanup logic into helpers

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 11:57:50 -06:00
48be64583a
Reduce nesting depth in regex_cache, connection_monitor, and device_identification
Extract nested logic into helper functions to improve readability:
- regex_cache.ex: Extract compile_and_cache/1 for regex compilation and caching
- connection_monitor.ex: Extract calculate_scheduler_utilization/1 for CPU stat calculation
- device_identification.ex: Extract fetch_devices_from_url/0 for HTTP request handling

Co-Authored-By: Graham <noreply@anthropic.com>
2026-02-09 11:55:51 -06:00
73448d7811
Fix remaining warning and design suggestion
- Fix length/1 check in mobile_channel.ex
- Add LeaderElection alias in connection_manager.ex

All warnings and design suggestions now complete!
Remaining: 40 refactoring opportunities (complex/nested functions)
2026-02-09 11:49:51 -06:00
185266a1f9
Refactor: reduce nesting depth in 2 functions
Extract nested logic into helper functions to improve readability:
- broadcast_task_supervisor.ex: extract broadcast_to_topics/3 helper
- log_sanitizer.ex: extract redact_match/1 helper

Progress: 2/42 refactoring opportunities fixed
2026-02-09 11:48:05 -06:00
d8606bb609
Complete nested module alias fixes and update Sobelow skips
Software design fixes:
- Add proper aliases for all nested modules
- release.ex: Ecto.Adapters.SQL
- packet_consumer.ex: Aprsme.Cluster.PacketDistributor
- cleanup_scheduler.ex: Aprsme.Workers.PacketCleanupWorker
- health_check.ex: Ecto.Adapters.SQL
- status_live/index.ex: Aprsme.Cluster.LeaderElection
- packet_receiver.ex: Aprsme.Cluster.LeaderElection
- packet_distributor.ex: Aprsme.Cluster.LeaderElection, AprsmeWeb.MapLive.PacketStore

Security:
- Update .sobelow-skips for false positive SQL injection warning (div is builtin function)

All 13 software design suggestions now complete.
All 13 warnings previously fixed.
Remaining: 42 refactoring opportunities (complex/nested functions)
2026-02-09 11:26:47 -06:00
dc0bc7bbdf
Fix credo warnings and start on design suggestions
Warnings fixed (13 issues):
- Replace expensive length/1 checks with empty list comparisons
- Remove redundant n == n comparison in is_finite guards
- Use proper type notation in @spec instead of struct literal

Design suggestions (3/13 files):
- Add aliases for nested modules in historical_loader, page_controller, mobile_channel

Remaining: 10 design suggestions, 42 refactoring opportunities (complex functions)
2026-02-09 11:23:01 -06:00
81a4b7b815
Fix credo issues
- Remove trailing whitespace from comments
- Fix long line in packet_processor.ex
- Rename is_leader? to leader? following Elixir conventions
2026-02-09 11:17:56 -06:00