Commit graph

614 commits

Author SHA1 Message Date
437ccebbaa
Fix duplicate APRS-IS connections in clustered deployments
Prevent both AprsIsConnection and cluster-managed Is connection from
starting simultaneously. When clustering is enabled, only the cluster's
ConnectionManager should handle APRS-IS connections via leader election.

This resolves aprsc server disconnections caused by duplicate validated
clients with the same username (W5ISP-1).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 12:10:47 -05:00
94fad09901
Use Gossip strategy for Kubernetes clustering 2025-07-25 11:53:01 -05:00
187a607563
Fix Kubernetes node naming for distributed Erlang clustering 2025-07-25 11:47:37 -05:00
14ffefe2e9
Add Cluster.Supervisor directly to application supervision tree 2025-07-25 11:03:20 -05:00
35224327c0
Add debugging and validation for cluster topologies 2025-07-25 10:59:37 -05:00
17f5a162aa
Fix Cluster.Supervisor options handling 2025-07-25 10:57:10 -05:00
da589402af
Fix Cluster.Supervisor child spec configuration 2025-07-25 10:51:08 -05:00
67e293c77c
Fix Kubernetes cluster strategy configuration 2025-07-25 10:44:59 -05:00
4804bd16be
Add distributed Erlang clustering for single APRS-IS connection
Implement leader election to ensure only one APRS-IS connection across
multiple Kubernetes replicas. This prevents duplicate packet processing
and respects APRS-IS usage policies.

Key changes:
- Add leader election using :global registry
- Create connection manager for dynamic APRS-IS management
- Implement packet distribution from leader to all nodes
- Add Kubernetes headless service for node discovery
- Configure DNS-based clustering with libcluster
- Update deployment to support 3 replicas with clustering

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 10:30:29 -05:00
6c5714a49c
Fix right overlay panel cutoff issue
- Added missing CSS for slideover panel with proper width and positioning
- Fixed overflow issues by adding box-sizing: border-box
- Adjusted Track button padding from px-6 to px-4 to prevent cutoff
- Added whitespace-nowrap and flex-shrink-0 to prevent button text wrapping
- Ensured proper panel width of 352px on desktop with transform animations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 10:12:27 -05:00
cd5d8cc33f
Fix right sidebar overlay cutoff issue
- Added base CSS styles for slideover panel with proper positioning
- Increased right padding (pr-8) in content area to prevent button cutoff
- Set overflow to hidden on panel container to prevent scrollbar issues
- Ensures Track button and other content are fully visible

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 10:11:30 -05:00
80a35c5667
Update CLAUDE.md to emphasize formatting before commits
- Made it CRITICAL to always run mix format BEFORE committing
- Added Pre-Commit Checklist section with step-by-step process
- Emphasized this is non-negotiable to maintain code consistency

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 09:32:28 -05:00
935b70b4b1
Fix rate limiter header check bug
Fixed ArgumentError in rate limiter by replacing cond statement with
proper case pattern matching. The cond was incorrectly evaluating
assignment expressions as truthy values instead of checking if headers
were empty lists.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 09:30:59 -05:00
fb34553fe9
Add Cloudflare header support for real client IP
- Updated IP geolocation to check CF-Connecting-IP header first
- Added support for X-Real-IP header as additional fallback
- Updated rate limiter to use same header priority for consistency
- Headers checked in order: CF-Connecting-IP > X-Forwarded-For > X-Real-IP > remote_ip

This ensures proper client IP detection when the site is behind Cloudflare.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 20:29:48 -05:00
31bd5f5749
Switch back to raster map tiles
Disabled vector tiles by setting useVectorTiles to false.
The application will now use OpenStreetMap raster tiles instead.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 20:19:01 -05:00
f75b373dad
remove k8s 2025-07-24 19:52:36 -05:00
ce5724973c
Add 10.0.19.221 to allowed origins
Allow HTTP connections from internal IP 10.0.19.221 for k3s cluster access

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:51:58 -05:00
beb40cf625
Add rollout restart to deployment workflow
Force k3s to pull the latest image by adding rollout restart
after setting the image. This ensures the cluster always runs
the most recent build even when using the :latest tag.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:46:05 -05:00
c52adc8a9e
Fix Phoenix check_origin configuration and add kubectl docs
- Replace invalid wildcard domains (*.aprs.me) with explicit origins
- Phoenix doesn't support wildcard syntax in check_origin
- Added specific domains for aprs.me, sentry.io, and openstreetmap.org
- Updated CLAUDE.md with kubectl commands for debugging k3s deployment

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:40:15 -05:00
fe67866018
Update k3s deployment to use latest tag and correct registry
- Changed kubectl deployment command to use :latest tag
- Updated k8s deployment manifests to use ghcr.io/aprsme/aprs.me:latest
- This ensures k3s always pulls the most recent image from GitHub Container Registry

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:34:18 -05:00
816d699298
Fix k3s deployment to use correct Docker image tag
The deployment was using raw SHA but the Docker metadata action creates
tags with 'main-' prefix for the main branch. Updated kubectl command
to use the correct tag format: main-${github.sha}

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:28:28 -05:00
01cf1ee478
Fix Sentry.Event struct access error in SentryFilter
Replace get_in/Access usage with proper struct pattern matching to fix
UndefinedFunctionError when accessing Sentry.Event fields. The struct
doesn't implement the Access behavior, so we now use pattern matching
and direct field access instead.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:21:23 -05:00
e84dcb6bc0
clone submodules recursively 2025-07-24 18:20:56 -05:00
b8771afd14
remove docker security scan 2025-07-24 17:43:49 -05:00
12971b63e2
Manually compile vendored aprs dependency
The vendored dependency wasn't being found in the expected location.
This approach manually compiles it and copies the compiled files to
the correct location before running the main compilation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:42:33 -05:00
161562d130
Debug and fix aprs dependency compilation
Use compile.protocols and compile.elixir to avoid dependency checking.
Also add debug output to see if aprs is being compiled properly.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:40:08 -05:00
3c4b06dd0c
Fix Docker build by temporarily disabling gleam_compile alias
The issue is that mix compile alias includes gleam_compile which fails.
This workaround temporarily comments out the compile alias in mix.exs,
runs the standard mix compile, then manually copies Gleam BEAM files.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:37:37 -05:00
080b945a75
Use compile.elixir to avoid dependency checking
The mix compile task includes dependency checking which fails for vendored deps.
Using compile.elixir directly compiles only the Elixir source files.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:34:40 -05:00
bde7800d48
Fix Docker build by bypassing gleam_compile alias
The gleam_compile mix task fails in CI due to dependency checking issues.
This workaround copies the pre-compiled BEAM files directly and uses
mix compile without the custom alias.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:32:12 -05:00
423ba4f7ee
cleanup 2025-07-24 17:28:00 -05:00
8f9987cb5c
Fix Docker build by removing manual compilation step
The vendored aprs dependency is properly compiled by mix deps.compile
without needing a separate compilation step.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:26:00 -05:00
864e9f9f2f
Fix Docker build for vendored aprs dependency
The vendored aprs dependency wasn't being compiled properly in the Docker build.
Added explicit compilation step to ensure the dependency is built before mix deps.compile.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 17:23:02 -05:00
3f9f906858
cleanup 2025-07-24 17:18:02 -05:00
9193487c01
docker tweak 2025-07-24 17:15:10 -05:00
99d277f383
add deploy 2025-07-24 17:08:24 -05:00
9e45ffbf9a
ts tweak 2025-07-24 15:05:41 -05:00
206adb6b7d
back to raster 2025-07-24 12:02:28 -05:00
992f0f6483
csp change 2025-07-24 11:40:44 -05:00
ae8c74afbe
try vector tiles 2025-07-24 10:54:31 -05:00
688fc6ba95
Implement mobile web optimization and fix sidebar clipping
- Add comprehensive mobile viewport meta tags for better mobile experience
- Implement touch gesture support with long-press to show station info
- Create mobile-specific CSS with touch target optimization (44px minimum)
- Add safe area insets support for notched devices
- Position zoom controls at bottom-right on mobile for thumb accessibility
- Optimize map performance on mobile with canvas renderer
- Fix desktop sidebar toggle button clipping when slideover is open
- Improve responsive design for slideover panels and popups
- Add landscape mode and high DPI screen optimizations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 14:31:49 -05:00
095289d6f0
Add database indexes for weather data queries
- Add partial index on temperature column for weather stations
- Add compound index on received_at + temperature for time-based queries
- Add sender + temperature index for station-specific weather queries
- Add individual indexes on humidity, pressure, and wind_speed
- All indexes use WHERE clause to only include non-null values

These indexes will significantly improve performance for:
- Finding weather stations on the map
- Weather history queries
- Weather data filtering

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 14:07:08 -05:00
1e51d58af5
Fix missing zoom controls by adding vendor.css
The zoom controls were not displaying because the vendor.css file
containing Leaflet styles was not being included in the HTML template.
Added the missing stylesheet link to load vendor.css.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 13:26:01 -05:00
44ae82eb9b
Improve map tile loading reliability
- Add retry logic with exponential backoff for failed tiles (up to 3 attempts)
- Configure tile layer with optimized settings (keepBuffer, updateInterval)
- Add support for alternative tile providers (OSM DE, CartoDB)
- Update CSP to allow alternative tile providers
- Add error tile placeholder to prevent broken images

This should help with partial tile loading issues by retrying failed requests
and providing fallback options.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 13:22:45 -05:00
cd69de5131
Fix database creation on deployment
- Add create_database/0 function to handle database creation before migrations
- Make DeviceCache handle missing tables gracefully on startup
- Retry device loading after 5 seconds if initial load fails
- Prevent deployment failures when database doesn't exist yet

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 13:05:23 -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
c4fc59dc1e
Add pre-bundled vendor assets for Docker build
Force add vendor.js and vendor.css files that were gitignored
These files are needed during Docker build since npm isn't available

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 12:56:49 -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
53ce452cdf
Fix Docker build CSS import errors
Moved CSS imports from Tailwind config to JavaScript to let ESBuild handle them.
This fixes the Docker build error where Tailwind couldn't resolve node_modules paths.

- Removed CSS @import statements from app.css
- Added CSS imports to map.ts where Leaflet is used
- Configured ESBuild to handle CSS and image files
- Added missing topbar package to package.json
- Updated both dev and prod ESBuild configs

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 11:59:04 -05:00
b4206b63d1
Increase GPS drift threshold from 15m to 50m
Fixed issue where stationary stations like K5SGD-D were showing multiple
positions due to minor GPS accuracy variations. The previous 15-meter
threshold was too strict for typical GPS drift which can vary 5-30 meters.

- Increased default threshold in GeoUtils from 10m to 50m
- Updated packet processor to use 50m threshold for movement detection
- Verified with K5SGD-D showing ~24m variations that are now ignored

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 11:23:37 -05:00