## Summary
Complete implementation of the Unified Resource Model with new navigation.
## Features
- v2 resources API with identity matching across sources (Proxmox, Agent, Docker)
- Infrastructure page with merged host view
- Workloads page for all VMs/LXC/Docker containers
- Global search (Cmd/Ctrl+K) with keyboard navigation
- Mobile navigation with bottom tabs and drawer
- Keyboard shortcuts (g+key navigation, ? for help)
- What's New modal for user onboarding
- Report Incorrect Merge feature for false positive fixes
- Debug tab in resource drawer (enable via localStorage)
## Technical
- Async audit logging for improved performance
- WebSocket-driven real-time updates for unified resources
- Session-based auth achieves <2ms API response times
## Tests
- Backend: 78 tests passed
- Frontend: 397 tests passed
The reporting engine held a direct pointer to the metrics store, which
becomes invalid after a monitor reload (settings change, node config
save, etc.) closes and recreates the store. Use a dynamic getter closure
that always resolves to the current monitor's active store.
Also adds diagnostic logging when report queries return zero metrics,
and integration tests covering the full metrics-to-report pipeline
including reload scenarios.
Fixes#1186
Pro license holders running the standard Docker image/binary were
getting "Reporting engine not initialized" errors because the
reporting engine was only wired up in the enterprise build.
Now the core server initializes the reporting engine automatically
when the metrics store is ready, ensuring PDF/CSV report generation
works for all Pro license holders regardless of which binary they use.
The enterprise hooks are still honored if set, allowing the enterprise
build to override with its own implementation if needed.
Simplify server config by consolidating BackendHost and BackendPort into
a single BindAddress field. The port is now solely controlled by FrontendPort.
Changes:
- Replace BackendHost/BackendPort with BindAddress in Config struct
- Add deprecation warning for BACKEND_HOST env var (use BIND_ADDRESS)
- Update connection timeout default from 45s to 60s
- Remove backendPort from SystemSettings and frontend types
- Update server.go to use cfg.BindAddress
- Update all tests to use new config field names
Implements Phase 1-2 of multi-tenancy support using a directory-per-tenant
strategy that preserves existing file-based persistence.
Key changes:
- Add MultiTenantPersistence manager for org-scoped config routing
- Add TenantMiddleware for X-Pulse-Org-ID header extraction and context propagation
- Add MultiTenantMonitor for per-tenant monitor lifecycle management
- Refactor handlers (ConfigHandlers, AlertHandlers, AIHandlers, etc.) to be
context-aware with getConfig(ctx)/getMonitor(ctx) helpers
- Add Organization model for future tenant metadata
- Update server and router to wire multi-tenant components
All handlers maintain backward compatibility via legacy field fallbacks
for single-tenant deployments using the "default" org.
approval/store.go:
- Make Approve() idempotent - return success if already approved
- Handles double-clicks and race conditions gracefully
auth.go:
- Add dev mode admin bypass (disabled by default)
- When ALLOW_ADMIN_BYPASS=1, sets X-Authenticated-User header
server.go:
- Call router.StopOpenCodeAI() during shutdown
- Ensures AI service stops cleanly on server termination
The audit logging feature was showing the UI for Pro users but the
SQLiteLogger was never actually initialized - it fell back to the
ConsoleLogger which only writes to console and returns empty arrays
for queries.
This fix:
- Adds initAuditLoggerIfLicensed() helper to license_handlers.go
- Calls it when loading a persisted license at startup
- Calls it when activating a new license via API
- Creates SQLiteLogger with 90-day default retention when audit_logging
feature is enabled
The audit.db will be created in {dataDir}/audit/ when Pro is licensed.
- Add freebsd-amd64 and freebsd-arm64 to normalizeUnifiedAgentArch()
so the download endpoint serves FreeBSD binaries when requested
- Add FreeBSD/pfSense/OPNsense platform option to agent setup UI
with note about bash installation requirement
- Add FreeBSD test cases to unified_agent_test.go
Fixes installation on pfSense/OPNsense where users were getting 404
errors because the backend didn't recognize the freebsd-amd64 arch
parameter from install.sh.
Fixes#1091 - addresses all three documentation issues reported:
1. Binary path: Changed from /usr/local/bin/pulse-agent (which doesn't
exist in the main image) to /opt/pulse/bin/pulse-agent-linux-amd64
2. PULSE_AGENT_ID: Added to example and documented why it's required
for DaemonSets (prevents token conflicts when all pods share one
API token)
3. Resource visibility flags: Added PULSE_KUBE_INCLUDE_ALL_PODS and
PULSE_KUBE_INCLUDE_ALL_DEPLOYMENTS to example, with explanation
of the default behavior (show only problematic resources)
Also added tolerations, resource requests/limits, and ARM64 note.
Tables in Settings → Agents were not expanding to fill the container
width when full-width mode was enabled. Added `w-full` class to all
tables (Managed Agents, Kubernetes Clusters, and removed host tables)
so they properly expand in full-width layouts.
Fixes#1080
Major changes:
- Add audit_logging, advanced_sso, advanced_reporting features to Pro tier
- Persist session username for RBAC authorization after restart
- Add hot-dev auto-detection for pulse-pro binary (enables SQLite audit logging)
Frontend improvements:
- Replace isEnterprise() with hasFeature() for granular feature gating
- Update AuditLogPanel, OIDCPanel, RolesPanel, UserAssignmentsPanel, AISettings
- Update AuditWebhookPanel to use hasFeature('audit_logging')
Backend changes:
- Session store now persists and restores username field
- Update CreateSession/CreateOIDCSession to accept username parameter
- GetSessionUsername falls back to persisted username after restart
Testing:
- Update license_test.go to reflect Pro tier feature changes
- Update session tests for new username parameter
This commit adds enterprise-grade reporting and audit capabilities:
Reporting:
- Refactored metrics store from internal/ to pkg/ for enterprise access
- Added pkg/reporting with shared interfaces for report generation
- Created API endpoint: GET /api/admin/reports/generate
- New ReportingPanel.tsx for PDF/CSV report configuration
Audit Webhooks:
- Extended pkg/audit with webhook URL management interface
- Added API endpoint: GET/POST /api/admin/webhooks/audit
- New AuditWebhookPanel.tsx for webhook configuration
- Updated Settings.tsx with Reporting and Webhooks tabs
Server Hardening:
- Enterprise hooks now execute outside mutex with panic recovery
- Removed dbPath from metrics Stats API to prevent path disclosure
- Added storage metrics persistence to polling loop
Documentation:
- Updated README.md feature table
- Updated docs/API.md with new endpoints
- Updated docs/PULSE_PRO.md with feature descriptions
- Updated docs/WEBHOOKS.md with audit webhooks section
- Replace barrel import in AuditLogPanel.tsx to fix ad-blocker crash
- Remove all Enterprise/Pro badges from nav and feature headers
- Simplify upgrade CTAs to clean 'Upgrade to Pro' links
- Update docs: PULSE_PRO.md, API.md, README.md, SECURITY.md
- Align terminology: single Pro tier, no separate Enterprise tier
Also includes prior refactoring:
- Move auth package to pkg/auth for enterprise reuse
- Export server functions for testability
- Stabilize CLI tests