Commit graph

145 commits

Author SHA1 Message Date
Graham McInitre
1006fdaefc refactor: remove dead code, duplication, and over-abstractions
- Delete dead config keys and test file (typo'd aprsme_is_*, vacuous disable test)
- Remove duplicate function clauses and identical function pairs
- Rename misleading one_hour_ago variable to one_day_ago
- Strip stale Oban comment
- Remove TestHelpers time function duplicates
- Inline Aprsme.Schema module (only 1 caller)
- Deduplicate prod esbuild config
- Thin SymbolRenderer delegations, inline TimeUtils wrappers
- Remove redundant DeploymentNotifier GenServer polling
- Replace random fallback in get_callsign_key with sentinel
2026-07-21 10:36:49 -05:00
Graham McInitre
243a98df77 fix: security hardening and query performance improvements
- Session cookie: add encryption_salt and secure flag to endpoint
- CSP: remove unsafe-eval from script-src directive
- /metrics: wrap PromEx endpoint behind rate-limited pipeline
- LiveView signing_salt: move to env var in production config
- LiveView performance: defer heavy aggregation queries past initial mount
- SQL: replace correlated subquery with DISTINCT ON in get_heard_by_stations
2026-07-21 10:13:30 -05:00
7bdf21fb53
deps: ecto_sql 3.13→3.14, prom_ex 1.11→1.12, decimal 2.4→3.1, ecto 3.13→3.14; bump test pool for sandbox 2026-07-08 10:46:05 -05:00
6eda1c0290
fix: resolve 19 bugs across Elixir, JS/TS, and config
Critical:
- Remove :protected from WeatherCache ETS (conflicted with :public)
- Register Aprsme.ReplayRegistry in supervision tree
- Route :continue_replay dead message to :start_replay handler
- Add 5000ms timeout to unbounded :rpc.call calls
- Fix falsy lat/lng check rejecting valid 0 coordinates

Medium:
- Fix live_reload pattern (temp_web -> aprsme_web)
- Remove duplicate ecto_repos config
- Make DB SSL configurable via DB_SSL env var
- Track sizeCheckTimeout on self for cleanup in destroyed()
- Wrap pushEvent calls in try/catch
- Remove unused size variable in marker cluster icon
- Capture touch coords at touchstart instead of stale TouchEvent
- Demote console.log to console.debug in production code
- Add catch-all to normalize_bounds preventing GenServer crash

Style:
- Add missing @impl true annotations in is.ex
- Improve migration failure error message
- Use textContent instead of innerHTML for error messages
- Use proper type for longPressTimer instead of any
2026-06-21 11:47:07 -05:00
17838f05d3
Add Plausible Analytics server-side tracking and API Prometheus metrics 2026-06-04 19:37:54 -05:00
5569d8e2a0
Add user-agent to request logging metadata 2026-06-04 16:19:47 -05:00
51e068f3f1
Add PromEx Prometheus exporter and /metrics endpoint
Wire up prom_ex with built-in Application, Beam, Phoenix, PhoenixLiveView,
and Ecto plugins, plus a custom plugin that exposes the existing
app-specific telemetry (packet pipeline, spatial PubSub, repo pool,
postgres stats, insert optimizer) as Prometheus metrics.

Mount PromEx.Plug at /metrics — internal-only, intended to be scraped
by the cluster's external Prometheus through the kube-apiserver pod
proxy. K8s pod template now carries prometheus.io/{scrape,port,path}
annotations so the existing kubernetes-pods scrape job picks it up
automatically.

PromEx is disabled in the test environment.

Also harden the packet cleanup and partition manager tests with
Repo.delete_all setup hooks so they aren't poisoned by residual rows
committed outside a sandbox transaction in earlier runs (which were
inflating delete counts and triggering ATTACH PARTITION check_violation
errors against packets_default).
2026-05-08 10:41:06 -05:00
c711caff4e
Remove AppSignal; fix decrement trigger and stale test assertions
- Delete config/appsignal.exs (was never wired into mix.exs or any
  other config file)
- Migration: fix decrement_packet_sequence trigger to handle the case
  where currval() hasn't been called in the current DB session, matching
  the same exception handling already present in get_packet_count()
- Fix get_historical_packet_count test: invalid non-list bounds are
  silently ignored (no error), so assert is_integer not count == 0
- Add Repo.delete_all(Packet) setup blocks in PacketsOldestTest and
  PacketConsumerTest to clear any committed DB state before tests that
  depend on an empty packets table
2026-05-05 13:20:58 -05:00
ec0a64cf5f
faster tests 2026-04-24 19:00:24 -05:00
a377847122
chore: remove unused deps, replace resend with custom Swoosh adapter, fix test isolation
Remove faker, floki, igniter, ecto_psql_extras (zero usages), exvcr
(zero usages), and resend. Replace resend with Aprsme.Swoosh.ResendAdapter
using the already-present req dependency. Frees 23 packages total from
the lockfile including hackney, certifi, and the tesla dependency chain.

Fix two pre-existing test isolation bugs:
- signal_handler_test called the real ShutdownHandler.shutdown() via SIGTERM
  simulation without restoring state, causing page_controller_test to see
  shutting_down: true and return 503
- page_controller_test setup now resets ShutdownHandler state defensively
2026-04-24 13:04:18 -05:00
d87ef4dac5
config: disable SSL/TLS for database connections
Adds ssl: false to Repo config to disable database encryption.
2026-03-22 11:27:44 -05:00
df6431c899
Disable database SSL/TLS encryption
Removed DATABASE_SSL and DATABASE_SSL_VERIFY environment variable
handling and SSL configuration from database connection settings.
2026-03-20 12:56:38 -05:00
fcff4fa6f0
Fix packet retention config to read env var at runtime
Move packet_retention_days configuration from config.exs (compile-time)
to runtime.exs so it properly reads the PACKET_RETENTION_DAYS environment
variable at runtime instead of baking in the default value during build.

This fixes the issue where the app was using 7 days retention despite
PACKET_RETENTION_DAYS being set to 1 in the deployment, causing disk
to fill up with 54GB of old partition data.
2026-02-25 16:23:22 -06:00
cf97bf236a
Add client IP to request log metadata
Set Logger metadata from conn.remote_ip in the RemoteIp plug so
request logs include the client address.
2026-02-20 17:48:15 -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
75ceb73607
Fix Erlang clustering: use IP-based node names with DNS strategy
DNSSRV strategy resolves to IP-based names but nodes were named by
pod name, causing connection failures. Switch to DNS strategy with
IP-based node naming so libcluster discovery matches actual node names.
2026-02-19 16:01:20 -06:00
fa89c6d3ca
Add TCP backpressure to packet pipeline
When the PacketProducer buffer crosses 80% capacity, signal Aprsme.Is
to switch its TCP socket to passive mode, leveraging TCP flow control
to slow APRS-IS intake. Resume active mode when buffer drains below 30%.

A 30-second safety valve timer auto-resumes if backpressure gets stuck.
Disconnect/reconnect/terminate paths all clear backpressure state.
2026-02-19 15:31:51 -06:00
b5d7cf4a38
Replace ip-api.com geolocation with Cloudflare headers
Use CF-IPLatitude/CF-IPLongitude headers instead of making HTTP calls
to ip-api.com on every page load. Eliminates ~500ms latency, external
API dependency, and flaky tests.

Also disable test server to prevent port conflicts during development.
2026-02-19 15:01:49 -06:00
509f271eac
Improve packet pipeline reliability, security, and cleanup efficiency
- Fix XSS vulnerability in buildPopupContent fallback (escape callsign/comment)
- Add batch insert retry with individual fallback in PacketConsumer
- Add APRS-IS login response validation (logresp dispatch handler)
- Fix stale generation check bypass in HistoricalLoader
- Replace two-step SELECT+DELETE cleanup with single CTE-based batch DELETE
- Change default packet retention from 365 to 7 days
- Delete MapHelpers (100% duplicate of CoordinateUtils + BoundsUtils)
- Delete AprsIsConnection (dead code, second unused APRS-IS connection)
- Fix InfoMap hook memory leak (store/cancel setTimeout ref)
- Extract singleton loadMapBundle with callback queue in app.js
- Extract @heat_map_max_zoom constant in DisplayManager
- Add telemetry to cleanup worker and PacketProducer buffer overflow
- Track PacketProducer buffer_size as integer for O(1) length checks
- Remove duplicate bounds functions from index.ex
2026-02-19 14:11:48 -06:00
447a76b3cc
update 2026-02-18 14:14:49 -06: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
6b624e1365
more tests 2026-02-09 17:21:16 -06:00
9d9cd881c1
fix some tests 2026-02-09 15:32:09 -06:00
b2c25a152d
cleanup 2026-02-07 10:55:19 -06:00
2a310c6685
Fix test warnings and failures
- Add Phoenix.LiveViewTest import to ConnCase to fix warnings
- Disable AppSignal in dev and test (only enable in prod)
- Explicitly disable clustering in test environment
- Fix PacketDistributor to check cluster_enabled before calling LeaderElection
- Add Phoenix.CodeReloader listener to mix.exs

This prevents tests from trying to call cluster-specific GenServers
(ConnectionMonitor, LeaderElection) that don't exist in test mode.
2025-10-25 17:41:58 -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
282948db98
fix: resolve Chart.js date adapter error for weather charts
- Combine Chart.js and date adapter into single bundle to ensure proper loading order
- Add validation to skip chart rendering when insufficient weather data (< 2 points)
- Update vendor loader to not load date adapter separately
- Prevents date adapter errors when weather stations have limited data
2025-08-09 17:20:27 -04:00
808ba2dd30
cleanu p test 2025-08-05 13:00:35 -05:00
6e504f7209
fix: Configure Wallaby integration tests for GitHub CI
The Wallaby integration tests were timing out in CI. This adds proper
configuration for running browser tests in the CI environment.

Changes:
- Start ChromeDriver explicitly in the background on port 4444
- Pass CHROMEDRIVER_URL environment variable to tests
- Add chromedriver_base_url configuration to use env var if available
- Increase test timeout to 60 seconds for integration tests
- Add additional Chrome flags for better CI stability:
  - --disable-setuid-sandbox
  - --disable-extensions
  - --disable-background-timer-throttling
  - --disable-backgrounding-occluded-windows
  - --disable-renderer-backgrounding

These changes ensure ChromeDriver is properly started and accessible
in the CI environment, preventing connection timeouts.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-03 15:41:28 -05:00
b9cb8cf1a3
perf: Optimize test suite for maximum speed
Major performance improvements to test execution:
- Increase max_cases from 16 to 48 for better parallelization
- Increase DB pool size for concurrent tests
- Reduce DB timeouts and enable queue optimization
- Disable logging during tests (level: :error)
- Tag slow tests and exclude them by default
- Only seed devices for tests that need them
- Fixed log capture test for packet consumer
- Fixed flaky leader election test with proper timing

Performance improvements:
- Fast tests: 43.2s -> 24.1s (48% faster)
- All tests still pass with --exclude flags removed
- Created .test-commands with helpful aliases

Usage:
- mix test --exclude slow --exclude integration  # Fast development tests
- mix test  # All tests including slow ones

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 17:43:39 -05:00
f3b8f95ba4
fix: Disable ErrorTracker in test environment
Prevents database ownership errors during LiveView tests by disabling
ErrorTracker's database integration in the test environment.

This resolves the recurring "Handler ErrorTracker.Integrations.Phoenix
has failed and has been detached" errors that were occurring when
LiveView processes tried to write to the database without proper
ownership setup.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 14:26:18 -05:00
Graham McIntire
f967025808
Merge pull request #37 from aprsme/add-frontend-integration-tests
Add Frontend Integration Tests with Wallaby
2025-07-29 12:39:51 -05:00
79be23813e
Improve CI/CD stability for frontend integration tests
Address browser testing reliability in CI environments:

## CI/CD Improvements
- **ChromeDriver**: Use latest stable version instead of pinned version for better compatibility
- **Timeouts**: Add 10-minute timeout for integration tests to prevent CI hangs
- **Environment Variables**: Configure WALLABY_MAX_WAIT_TIME for CI-specific timeouts

## Wallaby Configuration Enhancements
- **Chrome Args**: Add CI-stable Chrome options (--no-sandbox, --disable-dev-shm-usage)
- **Window Size**: Set consistent 1280x720 window size for reproducible tests
- **Dynamic Timeouts**: Environment-configurable max wait time with sensible defaults
- **Pool Size**: Limit to single browser instance to prevent resource conflicts

## Benefits
-  More reliable test execution in CI environments
-  Better error handling and timeout management
-  Consistent browser behavior across environments
-  Reduced flakiness from resource constraints

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 12:26:35 -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
ef141d476f
Improve coordinate handling and add configurable position sensitivity
- Fix zero coordinate handling to distinguish between invalid coordinates and valid 0.0 (equator/prime meridian)
- Add to_float_safe() function that preserves nil for proper coordinate validation
- Add comprehensive coordinate validation with descriptive logging in JavaScript
- Make position change threshold configurable via application config (default: 0.001°)
- Add extensive test coverage for edge cases including nil coordinates and equator crossing
- Improve robustness for real-world APRS coordinate edge cases

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 12:06:56 -05:00
af4b58f61d
Fix code formatting 2025-07-29 10:32:32 -05:00
31b2f8fb91
Add SSL support for PostgreSQL connections
- Add DATABASE_SSL and DATABASE_SSL_VERIFY environment variables
- Configure Postgrex to use SSL with optional certificate verification
- Allow connecting to PostgreSQL with self-signed certificates
2025-07-29 10:31:04 -05:00
c509500320
format 2025-07-27 13:57:33 -05:00
6fdd39dc0e
Fix CI test failures and configuration issues
- Simplify APRS_PORT parsing to avoid syntax errors
- Disable Exq properly in test environment to prevent startup issues
- Disable Prometheus telemetry in test mode to avoid port conflicts
- Update telemetry module to conditionally start Prometheus metrics

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 13:51:43 -05:00
f8e075319e
Fix APRS_PORT parsing error causing application crashes
- Add robust integer parsing for APRS_PORT environment variable
- Fallback to default port 14580 if parsing fails
- Prevents crashes when environment variables contain unexpected values

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 13:45:56 -05:00
844c1b0a6c
Add configurable APRS_PORT environment variable support
- Make APRS-IS port configurable via APRS_PORT environment variable
- Defaults to 14580 (filtered port) if not specified
- Allows switching to 10152 (unfiltered port) for full packet stream

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 12:50:15 -05:00
8ddcb8000f
Fix Leaflet library loading race condition and enable Redis-free development
- Fix race condition in map bundle loading by waiting for script to load before initializing map
- Ensure Leaflet is properly exposed as window.L in map bundle
- Add Leaflet availability check in map initialization function
- Disable Exq background jobs in development environment to remove Redis dependency
- Remove invalid TelemetryMetricsPrometheus plug from endpoint
- Application now starts successfully without Redis in development mode

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 12:20:23 -05:00
1596e95eba
format 2025-07-27 11:16:16 -05:00
028dd50372
Fix Redis authentication error - don't send empty password
- Only include password in Exq config if it's not empty
- Prevents "ERR AUTH <password>" error when Redis has no authentication
- Build config dynamically to exclude empty password field

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:33:45 -05:00
46f68f3070
Fix syntax error in runtime.exs Redis configuration
- Wrap String.to_integer in try/rescue block properly
- Fix CompileError caused by rescue clause inside case statement
- Ensures runtime.exs can compile and load Redis configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:18:32 -05:00