BirdNET-NG Features
v0.1.0 — Core Platform
The foundation: distributed bird identification from capture to detection.
Satellite
- ✓ Audio capture from USB/I2S microphone via ALSA (
arecord) - ✓ 3-second chunking with configurable overlap
- ✓ WAV encoding at 48kHz mono (BirdNET native sample rate)
- ✓ Local disk storage (write-before-send)
- ✓ SQLite outbox queue (sql.js, persisted to disk)
- ✓ Simulated capture mode (sine wave) for development
- ✓ Replay capture mode (real bird audio from WAV files) for testing
- ✓ MQTT client with auto-reconnect
- ✓ Base64 audio payload with JSON metadata envelope
- ✓ Outbox drain loop with exponential backoff
- ✓ Configurable retention policy for local cleanup
- ✓ Satellite GPS coordinate reporting
- ✓ Live GPS via gpsd for Pi satellites
- ✓ Periodic telemetry reports (battery, storage, CPU, network)
Hub
- ✓ MQTT subscriber receiving audio chunks
- ✓ Store audio blobs in MinIO (keyed by
{tenant_id}/{satellite_id}/{chunk_id}.wav) - ✓ Insert
audio_chunksrecord in PostgreSQL - ✓ Enqueue processing job in BullMQ
- ✓ Hub-side acknowledgment (chunk marked
ackedonly after storage confirmed) - ✓ BullMQ consumer pulling audio processing jobs (async Python worker)
- ✓ Download audio from MinIO
- ✓ Run BirdNET TFLite model (via birdnetlib, tflite-runtime 2.14)
- ✓ Write detection results to PostgreSQL
- ✓ Basic species identification with confidence scores
- ✓ Geo-aware species filtering (location + date)
- ✓ Species range filtering based on location + month
- ✓ BirdNET location filter integration in inference worker
- ✓ Reduced candidate list for faster and more accurate inference
- ✓ Configurable "uncertain" confidence band (default: 0.4–0.7)
- ✓ Auto-requeue uncertain detections with lower threshold (0.05)
- ✓ Second pass updates confidence with GREATEST(old, new)
- ✓ Flag for human verification if still uncertain (pending_review)
- ✓ Frequency-based rarity model (first sighting + low frequency detection)
- ✓ Real-time alert generation on unusual detections
- ✓ WebSocket push to connected UI clients (toast notifications)
- ✓ Webhook support (Slack, custom URL)
- ✓ Per-tenant custom watchlists (tenant_settings, watchlist_species array)
Auth & Multi-Tenancy
- ✓ Email/password registration with bcrypt password hashing
- ✓ JWT cookie-based sessions (httpOnly, secure, 7-day expiry)
- ✓ Login and registration pages with form validation
- ✓ Auth-gated routing (unauthenticated users see only login/register)
- ✓ Auto-login after registration
- ✓ Logout with cookie clearing
- ✓
/api/auth/meendpoint returns current user + tenant memberships - ✓ Blocked user detection at login time
- ✓ Tenant registration and management
- ✓ API key generation scoped to tenant (viewer, member, admin, satellite roles)
- ✓ Row-level tenant isolation on all queries
- ✓ Tenant-scoped MinIO paths
- ✓ API key authentication middleware with role-based guards
- ✓ Tenant scoping enforcement (scoped keys cannot access other tenants)
- ✓ Internal API key for web frontend (cross-tenant admin)
- ✓ Users are global (no tenant_id on users table)
- ✓ Multi-tenant membership via
tenant_membersjoin table - ✓ Per-tenant roles: viewer, member, admin, owner
- ✓ Tenant selector in sidebar for users with multiple memberships
- ✓ Platform admin with cross-tenant access (via DB flag or env var)
- ✓ Platform admin hidden from tenant member lists
- ✓ Self-service tenant creation (gated by platform setting)
- ✓ nginx no longer injects
HUB_INTERNAL_API_KEYon API requests - ✓ All user auth flows through JWT cookies (set by login, forwarded by browser)
- ✓ Internal API key retained for backwards-compatible machine access only
Invite System
- ✓ Admin-generated single-use invite links
- ✓ Invite scoped to tenant + role (viewer, member, admin)
- ✓ 72-hour default expiry (configurable per invite)
- ✓ Registration via invite bypasses self-registration setting
- ✓ Invite link displayed with copy-to-clipboard
- ✓ Pending invite list with revoke capability
- ✓ Invite validation before user creation (no orphan accounts)
Admin Pages
- ✓ Platform tab: global user management table with search
- ✓ Platform tab: block/unblock users
- ✓ Platform tab: delete users with modal confirmation
- ✓ Platform tab: reset password with modal dialog
- ✓ Platform tab: platform admin accounts shown as read-only
- ✓ Platform tab: platform admin self-service password change
- ✓ Tenants tab: member list with role display
- ✓ Tenants tab: role change via dropdown (viewer/member/admin)
- ✓ Tenants tab: remove member with modal confirmation
- ✓ Tenants tab: invite link generation with role selection
- ✓ Tenants tab: pending invites list with revoke
- ✓ Tenants tab: tenant selector for multi-tenant admins
Settings
- ✓ Tenant settings: confidence thresholds (high, low, minimum) with sliders
- ✓ Tenant settings: offline timeout (minutes)
- ✓ Tenant settings: verification consensus (votes needed)
- ✓ Tenant settings: satellite retention (hours)
- ✓ Platform settings: self-registration toggle
- ✓ Platform settings: tenant creation toggle
- ✓ Platform settings: invite links toggle
- ✓ Settings API:
/api/settings/tenant(GET/PUT) - ✓ Settings API:
/api/settings/platform(GET/PUT)
Web UI
- ✓ Dashboard: satellite status cards, recent detections, species count
- ✓ Detection cards: 2-column flex layout with SpectrogramPlayer
- ✓ Tenant selector with "All Tenants" option
- ✓ Dark theme, responsive layout
- ✓ Spectrogram visualization (Cooley-Tukey FFT, Viridis colormap, 0–12kHz)
- ✓ Satellite offline detection with configurable timeout
- ✓ Fleet dashboard in web UI (satellite cards with telemetry)
- ✓ Alerts: offline, low storage, overheating, high packet loss
- ✓ WebSocket connection status indicator (Live / Reconnecting...)
- ✓ Toast notifications for action feedback (success and error)
- ✓ Modal confirmations for all destructive actions
- ✓ User menu in sidebar (name, email, platform admin badge, sign out)
Deployment
- ✓ Docker Compose for full 8+ container hub stack (9 with split mode)
- ✓ Traefik integration (HTTPS + WSS for MQTT)
- ✓ Four FQDNs (web, MQTT, MinIO console, documentation site)
- ✓ All configuration via
.envenvironment variables - ✓ Persistent storage via bind mounts
- ✓ Satellite install script for Raspberry Pi
v0.2.0 — Satellite Ecosystem
Recording intelligence, verification workflows, mobile app, and species enrichment.
Satellite Recording
- ✓ Profile definitions (dawn_chorus, night_migration, low_power, continuous)
- ✓ Sunrise/sunset calculation from GPS coordinates (NOAA solar algorithm)
- ✓ Recording scheduler pauses capture outside active windows
- ✓ Hub → satellite profile + filter settings push via MQTT
- ✓ Hub pushes config to all online satellites when tenant settings change
- ✓ Satellites apply config on reconnect
- ✓ Heartbeat interval configurable from tenant settings (default 30s)
- ✓ Per-satellite profile assignment in web UI
- ✓ Schedule preview on satellite cards (resolved sun times + windows)
- ✓ Night migration uses sunset-relative times (adapts to season)
- ✓ Lightweight keepalive every 30 seconds (QoS 1)
- ✓ Decouples online status from audio chunk sending
- ✓ Heartbeat state visible on satellite cards (Recording, Paused, Scheduled off)
- ✓ Telemetry upgraded from QoS 0 to QoS 1 for reliability
- ✓ Satellite version reported in heartbeat, stored on satellites table
On-Device Audio Filtering
- ✓ Adaptive noise floor + spectral peak SNR detection (replaced RMS + bird-band frequency ratio)
- ✓ All filter settings configurable from hub tenant settings (filter_enabled, filter_min_rms, filter_peak_snr, filter_bird_band_check, filter_noise_floor_alpha)
- ✓ Settings pushed to satellites via MQTT config channel when changed
- ✓ Satellites report noise_floor_rms in heartbeat telemetry
- ✓ Default thresholds: min RMS 0.003, peak SNR 1.5, noise floor alpha 0.02
- ✓ Reduces unnecessary uploads and processing
Verification
- ✓ Backend voting endpoint (confirm / reject / unsure)
- ✓ Configurable consensus threshold (default: 3, adjustable in tenant settings)
- ✓ Verification review queue in web UI (card-based with spectrogram + audio)
- ✓ Keyboard shortcuts (1=Yes, 2=No, 3=Unsure, arrows=navigate)
- ✓ Auto-advance to next unvoted detection
- ✓ Progress bar and vote tracking
- ✓ Verification statistics and user leaderboard
Data Export
- ✓ CSV/JSON export of detections (filterable, downloadable from UI)
- ✓ eBird checklist generation
- ✓ xeno-canto recording submission
- ✓ iNaturalist observation export
Multi-Language Bird Names
- ✓ Species translation service (38 languages, loaded from BirdNET label files)
- ✓ SpeciesName component with SpeciesI18nProvider context
- ✓ User preferences for primary and secondary display languages
Workers
- ✓ Worker registration and heartbeat
- [~] Contributed worker onboarding (partial: worker dashboard shows connected workers)
- ✓ Worker performance metrics (avg processing time, queue stats)
- ✓ Worker dashboard in web UI with IP-based worker dedup
Phone App
- ✓ Cross-platform mobile app (Capacitor)
- ✓ Android phone satellite app with in-app registration, telemetry, GPS
- ✓ Native AudioRecord plugin for Android
- ✓ Background mode for continuous recording
- ✓ In-app log viewer
- ✓ Tap-to-record status bar (recording rectangle is the toggle)
- ✓ Default state: paused (not recording)
- ✓ GPS gate: requires location before recording (auto or manual)
- ✓ Clear GPS/manual location toggle
- ✓ GPS auto-update toggle with configurable interval (30s–10min)
- ✓ Keep screen on toggle
- ✓ Settings redesigned as full page (not popup) with verbose chunk logging toggle
- ✓ All hub filter settings received and applied via MQTT
- ✓ Heartbeat keepalive (configurable interval, default 30s, QoS 1)
- ✓ Schedule display (read-only, from hub)
- ✓ Storage telemetry via Storage API
- [~] Push notifications for rare species (WebSocket toasts implemented, no native push yet)
Species & Analytics
- ✓ Bird thumbnails from Wikipedia (Wikimedia Commons API)
- ✓ Background download queue (max 2 concurrent, configurable delay)
- ✓ Wikimedia rate limiting: sliding 1-hour window, auto-throttle at 80%, pause at 95%
- ✓ Unauthenticated: 500 req/hr; with OAuth 2.0 token: 10,000 req/hr
- ✓ Wikimedia OAuth token and contact email configurable in Platform Settings
- ✓ Respects Retry-After header on 429 responses
- ✓ Permanent storage in MinIO (no TTL expiry)
- ✓ Proxy endpoint serves from MinIO (Wikipedia never hit at request time)
- ✓ Placeholder display while downloading (pulsing indicator)
- ✓ Lightbox with full-size image + Wikipedia link
- ✓ Platform admin cache management (stats, retry failed, clear)
- ✓ Species catalog page with sortable cards and rich stats
- ✓ Per-species: detection count, confidence, first/last seen, satellite count
- ✓ Sort: most detected, most recent, alphabetical, confidence, rarest, most satellites
- ✓ Detection map with Leaflet.js + OpenStreetMap
- ✓ Satellite markers colored by status, sized by detection count
- ✓ Popup with detection stats and top 5 species
- ✓ Detection trends over time (daily trend chart)
- ✓ Hourly species activity chart
- ✓ Top species summary
User Preferences
- ✓ Per-user language settings (primary_language, secondary_languages on users table)
- ✓ Date format preferences: primary display + secondary tooltip
- ✓ Date format options: relative, short, medium, long, ISO 8601
- ✓ User preferences API (PUT /api/auth/me/preferences)
- ✓ UserPreferences page in web UI
Responsive Web UI
- ✓ Hamburger menu on mobile (< 768px)
- ✓ Sidebar slides in as overlay with backdrop
- ✓ Responsive sidebar (scrollable, hidden scrollbar)
- ✓ Single-column card grids on mobile
- ✓ Scrollable tables
- ✓ Stacked filters
Versioning & Documentation
- ✓ Unified semver across all packages (version-bump script syncs all package.json + pyproject.toml)
- ✓ Version displayed in web UI sidebar and mobile app header
- ✓ Documentation site (Express + markdown-it) with version switcher
- ✓ CHANGELOG.md with structured release notes
- ✓ Release protocol documented
- ✓ Design system documented (buttons, badges, color palette)
v0.3.0 — User Management & Security
Account lifecycle, security hardening, and design consistency.
Account Management
- ✓ Account page: edit name, email, change password, language preferences
- ✓ Account self-deletion with confirmation (blocks sole tenant owners)
- ✓ Tenant ownership transfer
- ✓ User search filters (status, tenant)
- ✓ Platform admin auto-persisted from PLATFORM_ADMIN_EMAILS env var
- ✓ Auth resolves live user data from DB (not stale JWT)
Security
- ✓ Login rate limiting (20 attempts/IP/15min)
- ✓ Account lockout after 5 failed attempts (15min)
- ✓ Last login tracking (timestamp + IP)
Audit Log
- ✓ Comprehensive coverage of all user, admin, and detection actions with real client IPs (via X-Forwarded-For)
- ✓ Audit Log page for platform admins (paginated, color-coded)
Design System
- ✓ Unified CSS classes for all buttons (btn-primary, btn-secondary, btn-danger, btn-ghost)
- ✓ Button sizes: btn-sm (tables), default (modals), btn-lg (forms)
- ✓ Hover, disabled, active states in CSS (no inline JS)
- ✓ Unified badge classes (online, offline, degraded, muted, accent, rare, danger)
- ✓ Responsive layout with mobile hamburger menu
- ✓ Version display in sidebar
v0.4.x — Audio Intelligence
Smart filtering, SpectrogramPlayer, GPS per detection, satellite management.
Smart Audio Filtering
- ✓ Adaptive noise floor + spectral peak SNR detection (replaced RMS ratio)
- ✓ All filter settings configurable from hub tenant settings, pushed to satellites via MQTT
- ✓ Settings: filter_enabled, filter_min_rms, filter_peak_snr, filter_bird_band_check, filter_noise_floor_alpha
- ✓ Satellites report noise_floor_rms in heartbeat telemetry
- ✓ Spectrogram blank start fix (trim mobile AudioRecord startup silence)
SpectrogramPlayer
- ✓ Unified spectrogram + audio player component on detection cards
- ✓ Click-to-seek on spectrogram, drag to select region for loop playback
- ✓ Playback cursor line synced with spectrogram
- ✓ Signal boost (1x–20x via Web Audio GainNode), speed control (0.25x–2x)
- ✓ Volume slider with mute toggle, download button
- ✓ Times displayed with centisecond precision
- ✓ Vote buttons (Yes/No/Unsure) under confidence bar
GPS & Detection Data
- ✓ GPS coordinates stored per audio chunk and per detection
- ✓ GPS required for inference — chunks without coordinates rejected with clear log message
- ✓ "No GPS" warning on satellite table and detail panel
Satellite Config & Heartbeat
- ✓ Hub pushes filter config to all online satellites when tenant settings change
- ✓ Satellites apply config on reconnect
- ✓ Configurable heartbeat interval from tenant settings
- ✓ Satellite version reported in heartbeat, stored in DB
- ✓ Version mismatch warning (amber) when satellite != hub version
- ✓ Separate Connection (online/offline) and State (recording/paused) columns
Satellite Management
- ✓ Satellite table layout with sortable columns, search by name, filter by status
- ✓ Satellite count (online/total) in header
- ✓ Slide-in side panel on row click (General, Hardware, Schedule, Hub Configuration, Actions)
- ✓ Smooth slide animation on panel open/close
- ✓ Date format preferences (primary display + secondary tooltip)
- ✓ Workers page: satellite name in recent jobs table
v0.5.x — Scalable Architecture
Hub service split, service registry, system monitoring, audit, deployment improvements.
Hub Service Split
- ✓ Hub runs in three modes via
HUB_MODEenv var:full,api,dispatcher - ✓
full(default): single process, unchanged behavior - ✓
api: stateless Fastify HTTP + WebSocket server, horizontally scalable - ✓
dispatcher: MQTT ingester, satellite monitor, detection watcher, webhook dispatcher, species image worker (single instance) - ✓ Redis pub/sub event bridge between API and dispatcher (detection alerts to WebSocket)
- ✓ Lightweight MqttConfigPusher in API mode for pushing config to satellites
- ✓ Image worker stats via Redis, settings polled from DB
- ✓ Docker Compose: service renamed from
hubtoapi,dispatcherundersplitprofile - ✓ Split mode:
docker compose --profile split up -d, API scalable with--scale api=N - ✓ MQTT connection resilience: auto-reconnect with 10s wait for scaled API instances
Service Registry & Monitoring
- ✓ Service registry via Redis with auto-discovery (keys
birdnet:registry:{service}:{instanceId}, 30s TTL) - ✓ System page in Platform Admin section showing all service instances
- ✓ Per-instance rows with IP address, version, uptime, memory usage
- ✓ Per-worker job stats (processed, succeeded, failed, avg duration)
- ✓ Satellites summary section with registered/online/offline/degraded counts
- ✓ Inference queue stats in data summary
- ✓ Expandable detail rows for additional per-instance information
- ✓ Infrastructure service IPs resolved via DNS
Comprehensive Audit Logging
- ✓ 30 audit actions covering all user, admin, and detection operations
- ✓ Real client IPs via
X-Forwarded-For(trustProxy enabled) - ✓ Audit actions for: login, register, profile, password, satellites, settings, votes, webhooks, tenants, cache
UI & Navigation
- ✓ Sidebar reorganization: Workers → Platform, Satellites → Tenant Admin
- ✓ Verification merged into Detections page as status filter
- ✓ Satellite registration from web UI with complete
.envgeneration - ✓ "Registered" satellite status for newly created satellites (before first connection)
- ✓ Dashboard: removed audio player from recent detections
Deployment & Infrastructure
- ✓ Node.js 24 LTS across all services
- ✓ MQTT switched from MQTTS (port 8883) to WSS (port 443) — no extra firewall ports needed
- ✓ Removed MQTTS TCP router from Docker Compose
- ✓ Traefik 3.x Method matcher fix
- ✓ Dotenv added to Pi satellite (
.envloaded automatically) - ✓ Pi satellite docs: complete setup guide with prerequisites, ALSA, GPS, registration, systemd
- ✓ Deployment docs reorganized by package (hub, workers, satellites, docs)
- ✓ Satellite comparison table
- ✓ Version-based roadmap (v0.1–v1.0)
v0.6.x — Detection Intelligence
Timeline, verification accuracy, first-of-season detection, and documentation audit.
Detection Timeline
- ✓ Sessions API: groups audio chunks into sessions (5-minute gap boundary)
- ✓ Timeline API: returns chunks + detections for a session time range
- ✓ Timeline page with session list (satellite, date, duration, chunk/detection/species counts)
- ✓ Visual timeline bar: chunks as positioned bars, detections highlighted with confidence colors
- ✓ Click any chunk to hear audio via SpectrogramPlayer
- ✓ Species legend with detection counts per session
- ✓ Full-width horizontal layout: metadata row + inline timeline bar per session
- ✓ Expand/collapse sessions with animated timeline height transition
- ✓ Species filter pills: click to pin, hover to preview — highlights matching chunks on timeline
- ✓ Chunk hover/selection highlights with confidence-colored bars
- ✓ Dimmed detection colors in expanded view for better contrast
- ✓ Hide empty sessions by default (toggle to show)
- ✓ SpectrogramPlayer fixed-height rendering (no layout flicker)
- ✓ Time labels moved below timeline bar
Verification & Accuracy
- ✓ Species accuracy stats API (per-species confirmed/rejected/pending/unverified counts)
- ✓ Accuracy percentage on Species cards (green/amber/red based on confirmed ratio)
- ✓ Verification feedback loop: accuracy calculated from community votes
First of Season
- ✓ DetectionWatcher checks for first-of-season sightings (spring/summer/fall/winter)
- ✓
is_first_of_seasonflag on detections table - ✓ Green "First of season" badge on detection cards
- ✓ First-of-season alert generated and event emitted
Detections Page
- ✓ Voting mode toggle (persisted in user preferences, hidden by default)
- ✓ Vote buttons moved under spectrogram, full width, with hover effects
- ✓ Existing votes loaded and displayed (allows changing votes)
- ✓ Confidence moved to inline label under species name (no more full-width bar)
- ✓ Species search filter
- ✓ Sort options: newest/oldest, highest/lowest confidence, species A-Z/Z-A
User Preferences
- ✓ Time display format preference (12h, 24h, with/without seconds)
- ✓ FormattedTime component respects user preference
- ✓ Voting mode preference persisted per user
- ✓ SpectrogramPlayer toolbar: compact speed/boost (icon or value, not both), unified accent color
Page Layout & UI System
- ✓ Fixed header (page-header + page-toolbar) / scrollable content (page-scroll) / fixed footer (page-footer)
- ✓ Consistent prev/next pagination footer: Page X of Y, Showing N to M of Total
- ✓ OverflowMenu component for grouping secondary actions (exports behind ⋮ button)
- ✓ Subtle scrollbar styling (6px, transparent track, faint thumb)
- ✓ Mobile: toolbar joins scroll area on < 768px, footer stays fixed
Server-Side Sorting, Filtering & Pagination
- ✓ Detections: speciesSearch, sortBy (date/confidence/species), prev/next pagination with total
- ✓ Sessions: filter (with-detections/empty/all), sortBy (date/duration/detections/species/chunks)
- ✓ Species: server-side search, sort (6 options), pagination (moved from client-side)
- ✓ Satellites: server-side search, status filter, sort (name/status/last_seen/detections), pagination
- ✓ Platform Users: sort (name/email/joined/last_login), pagination
- ✓ Audit Log: action type filter, user search
- ✓ Members: role filter, sort (name/role/joined), pagination
Documentation
- ✓ Fixed 19 documentation inaccuracies across 11 files
- ✓ Corrected migration count, container count, Node.js version, MQTT channels
- ✓ Updated configuration variable names, audio filtering description, permission model
- ✓ Fixed sidebar page listings and design system CSS details
- ✓ Design system docs: page layout system, overflow menu, scrollbars
Version Roadmap
v0.7.0 — Species & Location Context
- Per-satellite config overrides (filter settings, recording profile — moved from v0.6.0)
- Visual indicator on satellite card when using custom overrides
- Species profile pages (habitat, seasonality, frequency range, call types)
- Expected species per location (eBird integration or BirdNET location model)
- Activity patterns (peak hours per satellite, daily/weekly heatmaps)
- Shareable detection links (public URL with audio + spectrogram)
- Detection comments (community annotation)
v0.8.0 — Smart Alerts & Communication
- Custom alert rules engine (species, confidence, time, location conditions)
- Alert channels: email, Slack, Telegram, webhook
- Absence alerts (no activity = possible hardware issue)
- Trend alerts (diversity drop, unusual patterns)
- Scheduled automatic exports (cron-based, per tenant)
v0.9.0 — Analytics & Visualization
- Biodiversity indices (Shannon, Simpson, species richness per location)
- Migration pattern visualization (seasonal arrival/departure)
- Weather correlation (weather API integration)
- Detection map: per-detection GPS markers, heatmap layers, clustering
- Enhanced dashboard with time-series charts
- Location comparison (Site A vs Site B)
v0.10.0 — Mobile & Field Experience
- On-device inference (TFLite on phone for immediate feedback)
- Field notes (text, weather, photos paired with detections)
- UI language / i18n (web + mobile interface translations)
- Chunk history with filter reasons
- Native push notifications
- Real-time audio stream from satellite (delayed playback)
v0.11.0 — Model & Data Management
- Multiple BirdNET model versions
- A/B testing, performance comparison dashboards
- Audio re-analysis when models improve
- Adjacent clip stitching for longer recordings
- Data lifecycle (retention enforcement, cold storage archival)
- Research export (structured datasets)
v1.0.0 — Production Ready
- Security audit & hardening (GDPR erasure path)
- Two-factor authentication (TOTP)
- Session management (view and revoke active sessions)
- Email notifications (registration, password reset, rare species)
- Operational tooling (Prometheus metrics, backup strategy, disaster recovery)
- Easy update mechanisms for all components:
- Hub/web/docs:
docker compose pull && docker compose up -dworkflow - Pi satellite: one-command update script (
git pull && pnpm install && pnpm build && systemctl restart) - Android satellite: OTA update check or in-app update notification
- Version mismatch detection and admin notification (already partially done via heartbeat)
- Rolling updates with zero downtime for scaled API instances
- Hub/web/docs:
- Complete documentation review
- API auto-documentation from route definitions
- TypeScript types cleanup