Commit graph

103 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
1d229e647b
chore(deps): update dependencies to latest versions
- credo: 1.7.16 → 1.7.17
- stream_data: 1.2.0 → 1.3.0
- swoosh: 1.22.1 → 1.23.0
- tidewave: 0.5.5 → 0.5.6
2026-03-15 14:11:17 -05:00
Renovate Bot
5ba27564d2 chore(deps): Update dependency phoenix_live_view to ~> 1.1.26 2026-03-04 19:30:16 +00:00
6072eebe5b
vendor heroicons SVGs, remove GitHub dependency
Only the 7 SVGs actually used are vendored into priv/heroicons/.
Also fixes the icon component path resolution (was missing the 24/
size directory) and corrects hero-x-mark/hero-map-pin icon names
that included an erroneous hero- prefix.
2026-03-03 13:34:23 -06:00
18f3cc41b3
chore(deps): update all Hex dependencies to latest versions
Updated dependencies:
- bandit: 1.10.2 → 1.10.3
- ecto_sql: 3.13.4 → 3.13.5
- error_tracker: 0.7.1 → 0.8.0 (minor)
- gettext: 0.26.2 → 1.0.2 (major)
- phoenix: 1.8.3 → 1.8.4
- phoenix_live_view: 1.1.24 → 1.1.25
- sourceror: 1.10.1 → 1.11.0
- spitfire: 0.3.6 → 0.3.7
- styler: 1.10.1 → 1.11.0
- swoosh: 1.22.0 → 1.22.1

All 948 tests passing 
2026-03-03 11:01:35 -06:00
13bc58e650
Convert JS hooks to TypeScript and update esbuild to 0.25.4
Convert app.js, info_map.js, error_boundary.js, and time_ago_hook.js
to TypeScript with proper typing for Phoenix hooks, Leaflet, DOM
interactions, and timer management. Update esbuild hex package to
~> 0.10 and binary to 0.25.4. Entry point changed to app.ts.
2026-02-20 12:27:00 -06:00
b08eba2c6b
Partition packets table by day and simplify cleanup
Convert the packets table to a time-partitioned table with daily
partitions (PARTITION BY RANGE on received_at). This replaces the
expensive CTE-based batch DELETE cleanup with instant DROP TABLE
partition drops — no dead tuples, no WAL pressure, no VACUUM needed.

- Add PartitionManager GenServer to create/drop daily partitions
- Simplify PacketCleanupWorker to delegate to PartitionManager
- Replace gridsquare/geocalc deps with local Maidenhead module
- Remove gettext_pseudolocalize dependency
- Fix Decimal comparison in packet consumer test
2026-02-20 11:25:16 -06:00
781fdd88a3
Remove dead modules, unused deps, and commented-out code
Delete 5 unused modules: Presence (untracked), LiveView ShutdownHandler
(unused mixin), RateLimiterWrapper (pointless delegation), Passcode
(only used by own test), MapLive.Utils (pure delegates).

Fix ShutdownHandler to not call deleted Presence. Inline ParamUtils
at call sites. Remove cachex dep and 27 stale entries from mix.lock.
Clean commented-out Exq/Redis config from application.ex.
2026-02-20 08:09:22 -06:00
871620223d
Performance improvements, code cleanup, remove sobelow
- Switch PacketProducer buffer from list to :queue for O(1) overflow handling
- Add cached leadership check via :persistent_term to eliminate GenServer.call
  bottleneck in packet distribution hot path
- Simplify packets_live coordinate extraction from 70 lines of nested
  conditionals to helper functions (extract_coordinate/2, format_coordinate/1)
- Remove debug logging from hot paths (packets.ex queries, PacketDistributor,
  app.js console.logs)
- Remove sobelow dependency (false positives blocking commits)
- Add 25 new tests for PacketProducer, coordinate helpers, and cached leadership
2026-02-19 14:51:01 -06:00
447a76b3cc
update 2026-02-18 14:14:49 -06:00
3148b241da
Add Tidewave dev dependency for browser-based debugging 2026-02-18 13:15:03 -06: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
9d9cd881c1
fix some tests 2026-02-09 15:32:09 -06:00
b2c25a152d
cleanup 2026-02-07 10:55:19 -06:00
e01e9d2a31 update deps 2025-12-30 13:35:11 -06:00
cfee654b75
Add Phoenix.CodeReloader listener to mix.exs
Fixes warning about missing Mix listener expected by Phoenix.CodeReloader.
2025-10-25 17:26:14 -05:00
26d93e36c7
fix: remove Exq dependency and Redis job queue
- Remove Exq dependency from mix.exs and application config
- Remove all Exq configuration from config files (config.exs, dev.exs, runtime.exs, test.exs)
- Update CleanupScheduler to run cleanup tasks directly using Task.start instead of queuing jobs
- Update PacketCleanupWorker documentation to remove Exq references
- Cleanup functionality preserved but now runs in supervised Tasks instead of job queue

This resolves the Redis connection error on startup by eliminating the dependency on external job queues.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:24:59 -05:00
6acc007360
refactor: remove Redis dependency for PubSub, use distributed Erlang
- Remove phoenix_pubsub_redis dependency from mix.exs
- Update PubSub configuration to use Phoenix's native distributed capabilities
- Simplify clustering logic - no longer requires Redis URL for PubSub
- Phoenix PubSub automatically distributes messages across connected Erlang nodes
- Benefits: lower latency, automatic failure handling, simpler deployment
- Redis still available for caching and job processing when needed
- Maintains backward compatibility for both clustered and non-clustered modes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 15:48:00 -05:00
6c49980360
add appsignal 2025-10-21 12:29:59 -05:00
93e19ff517
Remove all external dependencies and Sentry integration
- Remove external Leaflet CDN links from info page (now uses vendor bundles)
- Remove all Sentry error tracking integration:
  - Remove sentry dependency from mix.exs
  - Remove Sentry plugs from endpoint.ex
  - Remove Sentry logger handler from application.ex
  - Remove Sentry configs from dev.exs and prod.exs
  - Remove Sentry domains from runtime.exs check_origin
  - Remove Sentry JavaScript initialization
  - Delete sentry_filter.ex module
  - Remove Sentry loader script from root layout

The application now loads all assets locally with no external runtime dependencies.
2025-10-03 12:53:47 -05:00
9db39e91f7
update geo 2025-10-03 12:29:40 -05:00
5e5c933b8a
update deps 2025-10-03 12:27:51 -05:00
c2fcf534dd
update and format 2025-08-13 09:39:39 -05:00
Graham McIntire
decca93275
Merge pull request #38 from aprsme/feature/show-last-packet-for-callsign
Fix: Show all packets for tracked callsigns including non-position data
2025-07-30 14:16:08 -05:00
2795e9dda9
fix: Add lazy_html dependency and improve test robustness
- Added lazy_html dependency required by Phoenix LiveView tests
- Simplified test assertions to avoid accessing internal LiveView state
- All tests now use render() to verify UI behavior
- Fixed 61 failing LiveView tests across the codebase

Note: One pre-existing test failure in user_registration_live_test.exs
remains (invalid CSS selector syntax) but is unrelated to these changes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 14:14:49 -05:00
11dbf8215c
feat: Implement comprehensive performance optimizations
- Add database indexes for common query patterns (path, callsign, device, weather)
- Implement packet batching in LiveView to reduce client updates
- Create PreparedQueries module for frequently executed database queries
- Add KNN (K-nearest neighbors) spatial queries using PostGIS
- Implement configurable debouncing for map bounds and hover events
- Integrate with existing Redis cache for device lookups
- Optimize cleanup worker with batch processing (already implemented)

These optimizations significantly improve query performance and reduce
database load, especially for high-traffic scenarios.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 14:14:00 -05:00
48bc27e43c
fix: Resolve majority of dialyzer type errors
- Fix leader election guard test for :undefined pid
- Fix cpu_sup.util() pattern matching to handle numeric return
- Fix encoding_utils to always return explicit nil when needed
- Remove unused finite_float? function
- Fix signal handler to match :ok return from :os.set_signal/2
- Remove redundant catch-all pattern in database metrics
- Fix Gridsquare pattern matching in info_live template
- Remove unnecessary nil check for calculate_course result
- Fix get_packet_received_at to not check for nil (always returns DateTime)
- Remove redundant catch-all pattern in weather format_weather_value
- Fix query builder to use from(p in Packet) instead of bare Packet atom

Reduced dialyzer errors from 49 to 6. Remaining warnings are mostly
false positives from template compilation and overloaded function specs.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 13:30:21 -05:00
ee16f81ed9
Update Wallaby to 0.30.10 and suppress expected test error
- Update Wallaby from 0.30.0 to 0.30.10 to fix struct update deprecation warnings
- Suppress expected error output in BroadcastTaskSupervisor test using capture_log
- Keeps test output clean while still verifying error handling behavior
2025-07-29 12:44:12 -05:00
9a63c9ed63
Add comprehensive frontend integration tests with Wallaby
This commit implements browser-based integration testing for the Phoenix LiveView
application using Wallaby and ChromeDriver to test the complete user experience
including JavaScript interactions.

## Changes Made

### Testing Infrastructure
- Add Wallaby dependency for browser automation testing
- Configure Chrome driver with headless mode for CI/CD
- Set up Phoenix server integration for test environment
- Enable screenshot capture on test failures

### Integration Tests
- `test/integration/simple_integration_test.exs` - Basic homepage functionality
- `test/integration/map_integration_test.exs` - Map interface and routing tests
- Tests validate page loading, content rendering, and navigation

### CI/CD Integration
- Update GitHub Actions workflow to install ChromeDriver
- Add separate integration test step in CI pipeline
- Configure headless Chrome for automated testing

### Configuration Updates
- Enable Phoenix server in test environment for Wallaby
- Configure Wallaby with proper base URL and screenshot settings
- Initialize Wallaby application in test helper

## Features Tested
-  Homepage loads with APRS content
-  Main page structure renders correctly
-  Route navigation functions properly
-  Basic Phoenix LiveView functionality

## Next Steps
This provides a solid foundation for expanding to test:
- Interactive map controls and JavaScript functionality
- Real-time packet updates via LiveView PubSub
- User authentication flows and form submissions
- Mobile responsive behavior

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 12:21:53 -05:00
863000d6b8
Add Prometheus metrics support to APRS application
- Add telemetry_metrics_prometheus dependency
- Configure Prometheus exporter in telemetry module
- Add metrics endpoint to application endpoint
- Expose /metrics for Prometheus scraping

This enables the application to be monitored by the Prometheus stack.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 11:44:11 -05:00
1596e95eba
format 2025-07-27 11:16:16 -05:00
9270bc1aa5
Complete dialyzer specs and fix all warnings
- Add comprehensive type specs to all functions in Encoding module
- Add missing specs to private functions in EncodingUtils
- Fix compilation warnings (unused variables, deprecated Logger.warn)
- Fix dialyzer warnings about unreachable code and implicit nil returns
- Remove unused do_migrate/1 function
- Remove last references to erlc_paths and gleeunit dependency

All dialyzer specs now pass without warnings.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 11:13:14 -05:00
648402a610
Fix build errors and add complete dialyzer specs
- Remove erlc_paths and erlc_include_path from mix.exs (leftover from Gleam)
- Add comprehensive dialyzer specs to Encoding module
- Add missing dialyzer specs to EncodingUtils module
- Ensure all public and private functions have proper type specifications

This fixes the Docker build error about undefined erlc_paths function
and ensures full dialyzer compliance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 11:08:40 -05:00
865fc90871
Remove Gleam and convert encoding module to pure Elixir
- Convert Gleam encoding module to Elixir implementation
- Remove all Gleam dependencies from mix.exs
- Remove Gleam configuration files (gleam.toml, src directory)
- Update Dockerfile to remove mix_gleam installation
- Update EncodingUtils to use Elixir module instead of Gleam
- Remove Gleam references from documentation
- Clean up all Gleam-related build configuration

This simplifies the build process and removes the compilation issues
that were preventing successful Docker builds.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 11:05:24 -05:00
8b3e433e61
Fix Exq startup conflict causing crash loop
- Remove manual Exq startup from application supervision tree
- Add :exq to extra_applications in mix.exs for automatic startup
- Remove duplicate Exq configuration functions
- Let Exq start automatically via runtime.exs configuration

The issue was Exq being started twice - once manually in the supervision
tree and once automatically via configuration, causing "already_started" error.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:49:42 -05:00
Graham McIntire
1929b4c09b
Merge pull request #34 from aprsme/switch-oban-to-exq
Migrate background job processing from Oban to Exq
2025-07-26 18:40:30 -05:00
1f4aaf2a80
Migrate background job processing from Oban to Exq
- Replace Oban dependency with Exq for Redis-based background jobs
- Update PacketCleanupWorker to use Exq's perform/1 signature
- Add CleanupScheduler GenServer for periodic job scheduling
- Configure Exq with Redis connection and queue settings
- Update tests to work with Exq job format
- Maintain 6-hour packet cleanup schedule functionality

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 18:39:50 -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
194ff0006f
Add Redis PubSub support for distributed clustering
Configures Phoenix.PubSub.Redis adapter when clustering is enabled
and REDIS_URL environment variable is set. This allows PubSub
messages to be shared across Elixir nodes in a distributed
deployment, enabling proper real-time updates in multi-node setups.

- Add phoenix_pubsub_redis dependency (~> 3.0)
- Configure Redis adapter in runtime.exs for production
- Set pool size to 10 for better performance
- Include node name in Redis configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 10:05:41 -05:00
f7cf0d0d47
Implement advanced JavaScript optimization with conditional loading
- Created minimal, tree-shaken vendor bundles:
  * Core bundle (3KB): Always loaded utilities and theme management
  * Map bundle (255KB): Leaflet + plugins, loaded only for map pages
  * Chart bundle (205KB): Chart.js, loaded only for chart pages
  * Date adapter (50KB): Chart.js time scale support
- Total optimized size: 513KB JS + 12KB CSS (was 547KB + 17KB)
- Implemented conditional loading via VendorLoader utility
- Bundle loading triggered by LiveView hooks when needed
- Fixed Chart.js date adapter dependency loading
- Eliminated unused JavaScript from being sent to browsers
- Created separate esbuild configs for each optimized bundle

Performance improvements:
- Map pages: Core + Map bundles = 258KB (47% of original)
- Chart pages: Core + Chart + Adapter = 258KB (47% of original)
- Other pages: Core bundle only = 3KB (0.5% of original)
- Reduced initial page load by 94% for non-map/chart pages

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 14:05:18 -05:00
f4bc55ed39
Optimize JavaScript delivery by creating local vendor bundles
- Download external libraries locally to reduce CDN dependencies
- Create combined vendor bundles for JavaScript and CSS
- Replace CDN script tags with local bundles in layout template
- Add build scripts for vendor bundle creation and optimization
- Configure esbuild to process vendor bundles separately
- Total bundle size: ~512KB JS + 17KB CSS (optimized)

Benefits:
- Reduced external requests and CDN dependencies
- Better caching control and reliability
- Eliminated CORS and SRI integrity issues
- Faster page loads with bundled resources

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 13:56:12 -05:00
f4aabf56c0
Install Node.js in Docker to build vendor assets
- Add Node.js installation to Dockerfile
- Run npm install to get dependencies
- Build vendor bundle during Docker build
- Remove unnecessary assets.deploy.prod alias

This ensures all JavaScript dependencies are available during the build process.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 12:57:46 -05:00
6944b9829c
Fix Docker build by using pre-bundled vendor assets
- Add new mix alias 'assets.deploy.prod' that skips vendor bundling
- Copy pre-bundled vendor.js and vendor.css files in Dockerfile
- Prevents esbuild errors when npm packages aren't available during build

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 12:41:27 -05:00
63a87f3be1
Fix Docker build JavaScript import errors with vendor bundle
Fixed the esbuild errors during Docker build where npm packages couldn't
be resolved. The issue was caused by node_modules being excluded from
the Docker build context in .dockerignore.

Implemented a proper vendor bundle strategy following Phoenix 1.7+ patterns:

- Created vendor.js that bundles all npm dependencies (Leaflet, Chart.js,
  topbar) and their CSS files into a single pre-built bundle
- Added vendor esbuild profile in config.exs with proper CSS/image loaders
- Updated mix.exs to build vendor bundle before app bundle in assets.deploy
- Modified JavaScript imports to use globally loaded libraries from vendor
  bundle instead of importing from node_modules
- Added vendor.js script tag to root.html.heex before app.js

This approach avoids Docker build failures by pre-bundling all vendor
dependencies, eliminating the need for node_modules during production builds.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 12:32:39 -05:00
9b034cd211
vendor all js 2025-07-21 11:09:14 -05:00
7dc6c616a2
Bundle all vendor JavaScript files locally instead of loading from CDNs
This change eliminates all external CDN dependencies by bundling JavaScript
libraries locally using esbuild. All vendor files are now served from the
application's own assets, improving reliability and privacy.

Changes:
- Created assets/js/vendor.js to bundle all external libraries
- Added vendor bundle configuration to esbuild in config files
- Updated all templates to use local vendor.js instead of CDN scripts
- Created download-vendor-files.sh script to fetch vendor libraries
- Added vendor files to .gitignore (they're downloaded during setup)
- Updated CSS imports to include vendor stylesheets
- Added vendor build step to assets.deploy mix task

Bundled libraries:
- Leaflet 1.9.4 (mapping library)
- Leaflet.heat 0.2.0 (heatmap plugin)
- Leaflet.markercluster 1.5.3 (marker clustering)
- OverlappingMarkerSpiderfier 0.2.6 (overlapping marker handling)
- Chart.js 4.5.0 (charting library)
- chartjs-adapter-date-fns 3.0.0 (date adapter for Chart.js)

All functionality tested and working correctly with local bundles.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 09:52:39 -05:00
9c7a6f01dd minor updates for gleam 2025-07-20 18:08:28 -05:00
1a84eb594a
Fix Gleam compilation in Docker builds
- Mark gleam_stdlib and gleeunit with compile: false in mix.exs
- Copy pre-compiled Gleam BEAM files in Dockerfile
- Add explicit mix gleam_compile step before asset compilation
- Ensure priv/gleam directory is included in Docker build

This fixes the "Could not compile :gleam_stdlib" error during deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:11:08 -05:00
4af0f4a421
Fix JavaScript context binding issues in map component
- Fix "this.__view is undefined" error when calling pushEvent in event handlers
- Bind pushEvent context properly in all marker click and hover handlers
- Replace undefined sendBoundsToServer calls with saveMapState
- Ensure all event handlers check for pushEvent availability and type
- Use .bind(self) to preserve LiveView hook context in callbacks

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:05:15 -05:00
177f0746bc
Fix Gleam compile script error
- Remove gleam@@compile.erl from erlc paths to prevent compilation errors
- Add gleam@@compile.erl to .gitignore
- Update erlc_paths to only include 'src' directory
- This prevents Erlang from trying to compile Gleam's escript files

The error was caused by Erlang trying to compile a shell script that
starts with #\!/usr/bin/env escript as an Erlang source file.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:50:22 -05:00