Commit graph

22 commits

Author SHA1 Message Date
b8a9b8a465
chore(dialyzer): enable stricter flags and fix 97 resulting findings
Turned on :error_handling, :underspecs, and :unmatched_returns in
mix.exs dialyzer config. The 97 warnings this surfaced were fixed in
place rather than suppressed:

- unmatched_return (79): explicit discard with `_ = ...` for
  fire-and-forget side effects (Process.cancel_timer, :ets.new,
  send/2), and pattern-matched `:ok = ...` for control-plane
  Phoenix.PubSub subscribe/unsubscribe/broadcast calls so a future
  return-shape change fails loud.

- contract_supertype (18): tightened @spec arg and return types on
  data_builder, historical_loader, url_params, packet_utils,
  encoding_utils, aprs_symbol, weather_controller, packet_replay to
  match each function's actual success typing.

No behavioural change. mix compile clean, 1008 tests pass, dialyzer
count is now 0.
2026-04-21 10:07:01 -05:00
4854157ee9
feat: add sitemap.xml, api-catalog, and agent-discovery Link headers 2026-04-17 13:31:21 -05:00
6d63638312
Remove dead code - unused controller actions
All pages are already LiveView, so removed:
- InfoController (replaced by InfoLive.Show)
- PageController.home and .packets (unused functions)

Remaining PageController functions are health/status JSON endpoints only.
All user-facing pages use LiveView with proper session continuity.
2026-03-22 13:11:08 -05:00
a796f8a3a9
Add Weather API controller with parameter validation
Implements GET /api/v1/weather/nearby endpoint with comprehensive parameter
validation and error handling. The controller validates required parameters
(lat, lon, radius) and optional parameters (hours, limit) with appropriate
range checking. Integrates with PreparedQueries for efficient database access
and WeatherJSON for response serialization.

Key features:
- Required params: lat (-90 to 90), lon (-180 to 180), radius (0-1000 miles)
- Optional params: hours (1-168, default 6), limit (1-100, default 50)
- Proper error responses via FallbackController (400 for bad requests, 422 for validation)
- Full test coverage (16 tests) including edge cases and error scenarios

Also updates FallbackController to handle {:error, status, message} tuples
and fixes WeatherJSON to support both field name formats (lat/lon and latitude/longitude)
for compatibility with existing tests and actual query results.
2026-03-22 11:27:45 -05:00
e539dc5a3e
Add WeatherJSON view module for API responses
- Implements nearby/1 function to format weather station data
- Returns structured JSON with data and meta fields
- Handles null weather fields gracefully
- Includes distance, position, weather data, and symbols
- Formats DateTime to ISO8601 strings
- All tests passing (3/3)
2026-03-22 11:27:45 -05:00
50544c8354
Remove dead PostGIS code, deduplicate utilities, and simplify module hierarchy
- Delete ~170 lines of commented-out PostGIS spatial query functions
- Consolidate coordinate validation into CoordinateUtils
- Replace private normalize_data_type with EncodingUtils delegation
- Inline to_float/to_decimal wrappers at call sites
- Fix has_weather_data? missing wind_gust field
- Remove BoundsManager passthrough delegation module
- Simplify MapLive.PacketUtils by removing pure-passthrough delegations
2026-02-20 13:39:07 -06:00
ca05b497b9
Consolidate 24 packet columns into JSONB data field
Drop 10 dead parser-compat columns (srccallsign, dstcallsign,
origpacket, body, header, alive, posambiguity, symboltable,
symbolcode, messaging) and move 14 display-only columns into a
single `data` JSONB column (PHG, telemetry, radiorange,
information_field, format, posresolution, position_ambiguity,
luminosity, rain_midnight).

Reduces row width from ~70 to ~48 columns. Table is ephemeral
so migration uses DROP/recreate. Also fixes snow_24h -> snow bug
in weather check query and adds null byte stripping for JSONB
string sanitization.
2026-02-20 13:02:47 -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
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
41c148650d
refactor: Remove CachedQueries and rename optimized functions
- Remove all CachedQueries usage throughout the codebase
- Replace with direct Packets module calls
- Delete CachedQueries module entirely
- Rename get_recent_packets_optimized to get_recent_packets
- Add has_weather_packets? function to Packets module
- Fix duplicate function definitions
- Update all test references to use new function names

This simplifies the codebase by removing the caching layer and
eliminates the database ownership errors in tests.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 13:17:56 -05:00
5c69604c32
feat: Implement direct station URLs with persistent latest packet display
- Add support for station-specific URLs (e.g., /w5isp) as path parameters
- Always display the most recent packet for tracked stations, regardless of trail/historical duration
- Fetch and store tracked callsign's latest packet on mount
- Update packet filtering to preserve tracked callsign's packet even if outside time threshold
- Keep tracked callsign's latest packet updated with real-time arrivals
- Display tracked callsign's packet immediately when map loads
- Remove obsolete RedirectController in favor of direct LiveView routing

This ensures users viewing a specific station always see its most recent position,
even if it falls outside the selected historical timeframe.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 12:56:05 -05:00
eeeebef34e
Fix PgBouncer database connection and graceful shutdown
- Add SKIP_DB_CREATE env var to skip database creation when using PgBouncer
- Fix redis_children() to return proper child specs
- Implement zero-downtime graceful shutdown without user notifications
- Add health check plug for Kubernetes probes
- Remove user-facing shutdown notifications for seamless deployments

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 15:51:06 -05:00
0f26cd7e22
Add cluster-aware APRS-IS status checking
Both /status and /status.json endpoints now show cluster-wide APRS-IS
connection status instead of just local node status.

Features:
- get_cluster_aprs_status() checks all nodes in cluster via RPC
- Returns status from any connected node (usually the leader)
- Shows cluster info: total nodes, connected nodes, leader node
- Graceful fallback to local status in non-clustered mode
- Enhanced status page UI with cluster information display

This ensures status pages accurately reflect the true APRS-IS
connection state across the entire cluster.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 13:10:23 -05:00
234fc2010f
Implement critical performance optimizations and error handling
This commit introduces several major performance improvements and adds
robust error handling for malformed HTTP requests:

Performance Optimizations:
- Add database migration with BRIN indexes for time-series data and partial
  indexes for recent queries, significantly improving query performance
- Create global StreamingPacketsPubSub system for real-time packet distribution
  with geographic bounds filtering using ETS for fast lookups
- Refactor PacketConsumer to use Stream module for memory-efficient processing,
  preventing memory accumulation during batch operations
- Implement dedicated BroadcastTaskSupervisor pool for async broadcast operations,
  preventing GenServer blocking on I/O
- Increase database connection pool from 25 to 45 (production) and 15 to 30 (dev)
  for better concurrency support

Error Handling:
- Add SentryFilter to prevent Bandit.HTTPError from missing Host headers from
  cluttering Sentry (common with bots/scanners)
- Configure custom 400 Bad Request error handling
- Filter out common bot/scanner paths from error reporting

All changes include comprehensive test coverage following TDD practices.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 18:19:49 -05:00
532a81c0b4
integrate /:call to main page 2025-07-13 10:36:58 -05:00
b1ee1f92f9
dont parse device identifiers on each insert 2025-07-10 15:16:01 -05:00
711d92ebb6
performance improvements 2025-07-08 10:03:52 -05:00
fc449ed5f9
en español 2025-07-05 15:51:39 -05:00
7ef3f59026
parsing improvements 2025-06-28 15:53:27 -05:00
f08330b46c
weather fixing 2025-06-25 11:40:04 -05:00
229c8f8305
fix messaging name 2025-06-24 14:29:47 -05:00
ce7c50caa1
refactor to use external parser 2025-06-24 14:22:09 -05:00