You are viewing archived documentation for v0.7. Go to latest →

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_chunks record in PostgreSQL
  • ✓ Enqueue processing job in BullMQ
  • ✓ Hub-side acknowledgment (chunk marked acked only 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/me endpoint 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_members join 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_KEY on 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 .env environment 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_MODE env 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 hub to api, dispatcher under split profile
  • ✓ 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 .env generation
  • ✓ "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 (.env loaded 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_season flag 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:
    • ✓ satellite_config_overrides table (all nullable — null means use tenant default)
    • ✓ Config resolution: override ?? tenant_default across all config push paths
    • ✓ config_locked flag per satellite (admin-only toggle, blocks device changes)
    • ✓ GET/PUT /satellites/:id/config API (read effective config + raw overrides, write overrides)
    • ✓ MQTT config-request channel for device-initiated config changes (respects lock)
    • ✓ Mosquitto ACL updated for config-request publish
    • ✓ Web UI: satellite detail panel with override editor, lock toggle, reset to defaults
    • ✓ Mobile app: editable settings when unlocked, sends config-request via MQTT
  • ✓ Visual indicator on satellite card when using custom overrides (has_overrides flag, * markers)
  • ✓ Species profile pages:
    • ✓ GET /stats/species/:code API with aggregated stats, trend, hourly activity, satellites, confidence distribution, recent detections
    • ✓ SpeciesProfile page (/species/:code) with stats cards, charts, satellite breakdown, recent spectrograms
    • ✓ Species names clickable everywhere (dotted underline, links to profile page)
  • ✓ Expected species per location:
    • ✓ eBird API integration (recent observations within 25km, 30 days)
    • ✓ EBirdService with 24h in-memory cache
    • ✓ GET /stats/expected-species API (by satellite ID or lat/lng)
    • ✓ Cross-references with detected species (marks which ones we've seen)
    • ✓ Expected species section on satellite detail panel (pills with detected/not-detected indicators)
    • ✓ Optional: enable via EBIRD_API_KEY env var
  • ✓ Activity patterns:
    • ✓ Hour×day-of-week heatmap grid (HeatmapGrid component)
    • ✓ Per-satellite activity heatmap in satellite detail panel
    • ✓ Weekly Activity Pattern section on Analytics page with peak hours
    • ✓ Peak hours column on satellite table
    • ✓ API: GET /stats/activity-heatmap and /stats/satellite-activity
  • ✓ Satellites page redesign: expandable rows (3-column detail grid) replacing side panel
  • ✓ Shareable detection links:
    • ✓ HMAC-signed share tokens (no DB table, verified server-side)
    • ✓ Public share page /share/:id/:token with spectrogram + audio (no login required)
    • ✓ Public audio stream endpoint for shared detections
    • ✓ Share button on detection cards (copies link to clipboard)
  • ✓ Detection comments:
    • ✓ detection_comments table (migration 019)
    • ✓ GET/POST/DELETE /detections/:id/comments API
    • ✓ Inline comment section on detection cards (expandable)
    • ✓ Own comments deletable, admins can delete any
  • ✓ Species images: dedicated MinIO bucket (birdnet-species, separate from audio)

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)
  • Platform admin health toast (persistent notification when core service is down)

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)
  • Background recording real-world testing and hardening

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)
  • ✓ Update mechanisms for all components:
    • ✓ Hub/web/docs: git pull && docker compose up -d --build workflow (documented)
    • ✓ Pi satellite: birdnet-update.sh script (interactive + --force mode)
    • ✓ Pi satellite: remote update via MQTT from web UI (admin triggers, Pi executes script)
    • ✓ Android satellite: version check on connect + "Update available" banner
    • ✓ Version mismatch detection on satellite cards with "Update" button
    • Rolling updates with zero downtime for scaled API instances
  • Custom UI components (selects, radios, checkboxes) to replace native HTML elements
  • Complete documentation review
  • Docs site search functionality
  • API auto-documentation from route definitions
  • TypeScript types cleanup
  • Fix Node 24 url.parse() deprecation (DEP0169)