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
- Fix PacketCleanupWorkerTest to use relative timestamps based on
configured retention period rather than hardcoded 365-day assumption
(was failing when PACKET_RETENTION_DAYS env var is set to a small value)
- Fix capture_aprs.py to use timezone-aware datetime.now(timezone.utc)
instead of deprecated datetime.utcnow()
- Add bad_packets.txt to .gitignore
- Add mix task aprs.parse_file
- 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>