All notable changes to BaluHost will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- (plugin-market) idempotent marketplace public-key provisioning helper
- (plugin-market) per-deploy marketplace signature smoke-check
- (plugin-market) config keys + route 502 mapping for index signing
- (plugin-market) fail-closed index signature gate in MarketplaceService
- (plugin-market) detached ed25519 signature verify util
- (plugins) rewrite Documentation tab tier-first with live scope catalog
- (plugin-sandbox) external-plugin scope-picker modal in PluginsPage (Phase 5b)
- (plugin-sandbox) frontend scope-catalog client + is_external/requested_api_scopes types (Phase 5b)
- (plugin-sandbox) success audit plugin_sandbox_spawned on external enable (Phase 5a follow-up)
- (plugin-sandbox) scope-picker backend -- grant_api_scopes threading + is_external/requested_api_scopes (Phase 5b)
- (plugin-sandbox) Gap C -- external plugins surface static UI in get_ui_manifest (Phase 5b)
- (plugin-sandbox) static nav_items/dashboard_widgets in PluginManifestUI (Phase 5b)
- (plugin-sandbox) scope catalog module + GET /scope-catalog (Phase 5b)
- (plugin-sandbox) provision baluhost-plugin user, scoped sudoers, wrapper install
- (plugin-sandbox) root-owned hardened spawn wrapper + arg-validation tests
- (plugin-sandbox) wire spawn-hook selection + fail-closed audit into PluginManager
- (plugin-sandbox) hardened_spawn + scrub_env + select_spawn_hook (auto-detect, fail-closed)
- (plugin-sandbox) config for hardened worker spawn (user + wrapper path)
- (plugin-sandbox) route dual-path — manage external plugins via manifest, no exec (Phase 4)
- (plugin-sandbox) catch-all proxy route with caps + header allowlist + scrubbing (Phase 4)
- (plugin-sandbox) PluginManager dual-path — external spawns supervisor, no host exec (Phase 4)
- (plugin-sandbox) dispatch forwards query+headers, timeout + in-flight cap (Phase 4)
- (plugin-sandbox) production-wired CapabilityRouter factory (Phase 4)
- (plugin-sandbox) worker Plugin-SDK + loader + register(host) authoring contract (Track B Phase 3)
- (plugin-sandbox) supervisor routes cap_call to CapabilityRouter via in-flight context (Track B Phase 3)
- (plugin-sandbox) core.system_metrics + core.notify capabilities (Track B Phase 3)
- (plugin-sandbox) CapabilityRouter default-deny + storage.* (Track B Phase 3)
- (plugin-sandbox) SandboxSupervisor spawn/handshake/dispatch/stop (Track B Phase 2b)
- (plugin-sandbox) worker entry point with health/echo handler + RpcChannel.wait_closed (Track B Phase 2a)
- (plugin-sandbox) cross-platform host<->worker transport (UDS prod / TCP dev) (Track B Phase 2a)
- (plugin-sandbox) add duplex RpcChannel with correlation IDs (Track B Phase 1)
- (plugin-sandbox) add RPC frame codec + message envelope (Track B Phase 1)
- (plugin-sandbox) remove main-context pluginSDK/pluginLoader (close audit gap)
- (plugin-sandbox) declare optical_drive api_scopes + min_runtime_abi
- (plugin-sandbox) expose min_runtime_abi; migrate storage_analytics to BaluHost.api
- (plugin-sandbox) runtime storage proxy; wire into window.BaluHost
- (plugin-sandbox) host bridge storage channel (per-user, quota-aware)
- (plugin-sandbox) per-user plugin_storage service + _storage routes
- (plugin-sandbox) plugin_storage model + migration
- (plugin-sandbox) feed theme + ABI floor into the sandbox host
- (plugin-sandbox) compile plugin-runtime.css + link from host.html
- (plugin-sandbox) full window.BaluHost surface + theme apply in runtime
- (plugin-sandbox) theme handshake + ABI gate in host bridge
- (plugin-sandbox) scope_denied audit route + bridge firing
- (plugin-sandbox) persist declared api_scopes into granted_api_scopes on enable
- (plugin-sandbox) expose granted_api_scopes via ui manifest, wire PluginPage
- (plugin-sandbox) InstalledPlugin.granted_api_scopes column + migration
- (plugin-sandbox) manifest api_scopes + min_runtime_abi fields
- (plugin-sandbox) PluginSandboxHost component, wire PluginPage to the sandbox
- (plugin-sandbox) serve framable host.html bootstrap + CORS, middleware carve-out
- (plugin-sandbox) in-iframe runtime SDK + separate vite runtime build
- (plugin-sandbox) host bridge controller with policy-enforced api channel
- (plugin-sandbox) scope catalog + default-deny api policy matcher
- (plugin-sandbox) message envelope protocol + validators
- (core) global exception handlers + 5xx scrubber net (B3 / GAP-10)
- (core) add ServiceError exception hierarchy (B3)
- (sleep) UI toggle + i18n for suspend-on-core-uptime-exit
- (sleep) frontend types + history label for suspend-on-exit
- (sleep) arm + fire true suspend on core-uptime window end
- (sleep) schema + trigger + get_config for suspend-on-exit
- (sleep) add core_uptime_suspend_on_exit column + migration
- (#258) hoist fritzbox secret-key sets to module-level frozensets
- (notifications) route firebase.py output through logger (no print)
- (core) curate error leaks in backup/vcl/plugins/misc routes (B3 / AP6)
- (core) curate error leaks in power/monitoring/smart/sleep routes (B3 / AP6)
- (core) drop detail=str(e) leak wrappers in benchmark.py (B3 / AP5)
- (core) scrub exception text from marketplace route details (B3 / AP4)
- (core) scrub error leaks in vpn.py routes (B3 / AP3)
- (core) scrub error leaks in cloud.py routes (B3 / AP2)
- (core) drop detail=str(e) leak wrappers in fans.py (B3 / AP1)
- (plugin-market) harden smoke-check main() to always exit 0
- (plugin-market) drop redundant Body() marker, document 3.14 annotation fix
- (client) include vite-env.d.ts in test tsconfig so tsc -b resolves build globals
- (plugin-sandbox) drop unused listPermissions import in scope-picker test
- (plugin-sandbox) /ui/manifest resolves ABI from each plugin's discovered manifest (Phase 5b Gap C)
- (plugin-sandbox) strip unix: scheme before socket chown + skip symlinks in dir tree (Phase 5a I-1)
- (plugin-sandbox) grant plugin-group UDS+dir access in hardened_spawn (I-1) + audit user + deploy src-check
- (plugin-sandbox) install wrapper to /usr/local/sbin/ (root-owned path)
- (plugin-sandbox) disable_plugin hard-kills on stop() failure (no orphaned worker)
- (plugin-sandbox) toggle external predicate manifest-check + disable-path test (Phase 4 Task 6 review)
- (plugin-sandbox) correct proxy error-code docstring + precheck/scrub tests (Phase 4 Task 5 review)
- (plugin-sandbox) manifest-conditioned load_plugin exec-guard + adjust multipath tests for sandboxed externals (Phase 4 Task 4 review)
- (plugin-sandbox) unique per-spawn UDS socket path (no collision across workers)
- (plugin-sandbox) in-flight registration inside semaphore + cap/headers tests (Phase 4 Task 2 review)
- (plugin-sandbox) notifier uses injected session_factory + test (Phase 4 Task 1 review)
- (plugin-sandbox) unguessable cap request token + scrubbed worker context (Track B Phase 3)
- (plugin-sandbox) require full context in supervisor.dispatch (no silent user_id=0)
- (plugin-sandbox) auto-disable on non-SupervisorError restart failure
- (plugin-sandbox) close WorkerListener if spawn hook fails (Track B Phase 2b)
- (plugin-sandbox) WorkerListener.close() must not await wait_closed()
- (plugin-sandbox) declare msgpack dependency (was only in working tree)
- (plugin-sandbox) add LIFECYCLE_RESULT response type; revert read-loop to Phase-1 form (Track B Phase 2a)
- (plugin-sandbox) normalize decode_payload failures to FrameError for clean drop (Track B Phase 1)
- (#258) redact secret-key material + drop OSError/404-wrap leaks in service layer
- (plugin-sandbox) hoist load_manifest to module top-level; strengthen min_runtime_abi test
- (plugin-sandbox) bound _storage gate carve-out to exact namespace; tidy tests + 413 route test
- (plugin-sandbox) guard runtime message listener to window.parent only
- (plugin-sandbox) explicit undefined check on ABI gate; clarify interim theme handling
- (plugin-sandbox) drop constructor parameter property (erasableSyntaxOnly)
- (plugin-sandbox) escape host.html interpolation (CodeQL XSS) + drop unused test var
- (plugin-sandbox) navigate boundary + scopeCatalog tests + lint cleanups (final review)
- (plugin-sandbox) tighten _audit gate carve-out to exact route + bound audit body (Task 10b review)
- (plugin-sandbox) stabilize bridge lifecycle, recreate only per plugin session (Task 6 review)
- (plugin-sandbox) make host.html/CORS/carve-out tests actually execute (Task 5 review)
- (security) use realpath+startswith barrier in _validate_backup_dir
- (security) use direct is_relative_to guard in _validate_backup_dir
- (security) validate custom backup_path against allowed storage roots
- (security) tighten CSP connect-src to 'self' (audit Härtung #8)
- (security) dedicated TOTP_ENCRYPTION_KEY w/ VPN-key fallback (Posten 3 #3)
- (security) dedicated CLOUD_ENCRYPTION_KEY w/ SECRET_KEY-derived fallback (Posten 3 #1)
- (security) tighten nginx auth_limit 10r/s -> 5r/m on /api/auth/ (audit HÄRTUNG)
- (security) trust nginx X-Forwarded-For for real client IP (audit #9 follow-up)
- (security) compare service token as bytes to avoid 500 on non-ASCII header (audit #2 hardening)
- (security) route mobile debug output through logger, drop FCM token from logs (audit #4)
- (security) avatar extension from validated MIME, not user filename (audit #3)
- (security) constant-time service-token compare (audit #2)
- (security) reject inactive users in get_current_user_optional (audit #1)
- (security) validate commit SHA in rollback() too (audit #6 completion)
- (security) validate Pi-hole upstream DNS as IPs before container shell (audit #7)
- (security) validate commit SHA before git checkout (audit #6)
- (security) WebDAV user isolation via Path.resolve() (audit #5)
- (security) lower file_upload rate limit 50000->300/min (Posten 5 #1)
- (security) fail-fast on NAS_MODE=dev under ENVIRONMENT=production (Posten 5 #5)
- (security) cap WebSocket connections per user at 5 (Posten 5 #2)
- (security) bound chunked upload to declared total_size (Posten 5 #3)
- (security) restrict admin SSRF targets to LAN hosts (Posten 4)
- (deps) bump cryptography to >=48.0.1 (Dependabot #53)
- (deps) bump vite to 7.3.5 and override undici to 7.28.0
- (security) VPN-key plaintext hard-fail in prod + widen admin-db redaction (Posten 3 #2/#4)
- (security) admin-gate SSH connectivity-test and start endpoints (audit #4)
- (security) WS endpoint rejects access tokens fail-closed (audit #5)
- (security) sanitize plugin.homepage href against javascript: URLs (audit #3)
- (admin) make loadOwners unmount guard actually work (#247)
- (sleep) keep schedule loop sleep-at-start; adjust suspend-on-exit test mocks
- (files) sanitize upload filename to prevent cross-user path traversal
- (backup) prevent tar-slip in restore via data filter
- (lint) drop unused vars, catch bindings, and imports (#210)
- (lint) remove useless rethrow catches (#210)
- (lint) empty e2e catch blocks (#210)
- (lint) prefer-const in AdminDatabase (#210)
- (install) bind POSTGRES_PASSWORD/USER via psql vars instead of interpolating (#219)
- (mobile) push device_removed on automatic expiry/deactivation (#228)
- (mobile) tie refresh-token TTL to device authorization validity (#227)
- (tauri) commit pinned Cargo.lock to fix brotli build conflict
- (api) return v1 router directly to survive FastAPI 0.137 nesting (#234)
- (deps) pin esbuild to >=0.28.1 to close RCE alert (#47)
- (readme) refresh README files for currency (sandbox/signing, prod facts)
- (claude) refresh CLAUDE.md indexes incl. Track C signing surface
- (spec) align Track C design with shipped impl (CSV env + BadGatewayError)
- (plan) correct Task 5 interface descriptor to plain CSV (not JSON array)
- (plan) review fix — CSV list-env convention to match config.py
- (plan) implementation plan for Track C marketplace index signing
- (plugin-market) add deploy automation to Track C spec
- (plugin-market) pin key-provisioning to empty default (defer/fill-before-deploy)
- (plugin-market) spec for Track C — ed25519 index signing
- (plan) review fixes — reuse docs.dangerousPermissions, commit-footer constraint, hooks-count decision
- (plan) implementation plan for two-tier PluginDocumentation rewrite
- (plugin-sandbox) spec for two-tier PluginDocumentation rewrite
- (plugin-sandbox) document bundled vs external trust tiers (Phase 5a follow-up)
- (plugin-sandbox) apply critical-review fixes to Phase 5b plan
- (plugin-sandbox) Phase 5b implementation plan (scope catalog, picker, Gap C)
- (plugin-sandbox) Phase 5b spec — scope catalog, scope-picker, Gap C UI surfacing
- (plugin-sandbox) correct Phase 5a spec to as-built (install path + socket/FS reachability)
- (plugin-sandbox) Phase 5a implementation plan — hardened worker spawn
- (plugin-sandbox) Phase 5a spec — hardened worker spawn (low-priv user + netns + rlimits)
- (plugin-sandbox) renumber Phase 4 plan to sequential integer tasks (2b->3, +1)
- (plugin-sandbox) fold critical-review fixes into Phase 4 plan
- (plugin-sandbox) Track B Phase 4 implementation plan (7 tasks, TDD)
- (plugin-sandbox) correct Phase 4 spec — granted_api_scopes already exists (Track A)
- (plugin-sandbox) Track B Phase 4 design — request-proxy + PluginManager dual-path
- (plugin-sandbox) Track B Phase 3 plan (Capability-Layer + Plugin-SDK)
- (plugin-sandbox) Track B Phase 2b plan (SandboxSupervisor)
- (plugin-sandbox) Track B Phase 2a plan (transport + worker runner)
- (plugin-sandbox) make Phase-1 RPC tests Windows-portable (loopback TCP)
- (plugin-sandbox) Track B Phase 1 implementation plan (RPC foundation)
- (plugin-sandbox) add frontend Plugin-Documentation update to Track B scope
- (plugin-sandbox) Track B backend-isolation design spec
- (plugin-sandbox) correct storage_analytics migration example to own-routes + empty scopes
- (plugin-sandbox) correct ui primitive count to 17 in ABI history
- (plugin-sandbox) author migration guide + runtime ABI doc
- (plugin-sandbox) apply plan review corrections
- (plugin-sandbox) Phase 3-5 implementation plan (TDD, task-by-task)
- (plugin-sandbox) Phase 3-5 design spec (runtime UI/theme/storage, migration, e2e)
- (plan) final-review fixes — X-Frame-Options carve-out, runtime dev-serving, test robustness
- (plan) plugin frontend iframe sandbox — Phases 1-2 (bridge + API policy)
- (spec) plugin frontend iframe sandbox (Track A)
- AP0 implementation plan (foundation + 5xx net)
- add 5xx scrubber net + work-package structure to error-leakage spec
- spec for global exception handler + error-leakage fix (B3 / audit GAP-10)
- implementation plan for suspend-on-core-uptime-exit
- spec for suspend-on-core-uptime-exit option
- implementation plan for ESLint CI gate (#210)
- spec for ESLint CI gate (#210)
- translate PRODUCTION_DEPLOYMENT_NOTES.de.md to German (#217)
- (presence) mount heartbeat in AppRoutes, pause while idle warning visible (#222)
- (presence) pause heartbeat via paused/enabled options (#222)
- (client) presence detection card on sleep page + i18n (#214)
- (client) presence heartbeat hook mounted in Layout (#214)
- (client) presence types + heartbeat API function (#214)
- (sleep) presence guards for escalation/schedule/suspend + inhibitor + status (#214)
- (sleep) exclude presence heartbeat from auto-wake + HTTP-RPM (#214)
- (sleep) POST /api/system/sleep/presence heartbeat endpoint (#214)
- (sleep) presence schemas + heartbeat rate-limit key (#214)
- (sleep) presence tracker service (#214)
- (sleep) presence_sessions model + sleep_config presence columns (#214)
- (deploy) deploy-fork workflow for self-hosted fork instances (#207)
- (ci) skip-guards for secret-dependent workflows in forks (#207)
- (ci) fork toggles for tauri/tui builds (#207)
- (ci) fork toggles for e2e + raid loopback, mdadm runner pinned (#207)
- (ci) configurable backend-test runner for forks, upstream pinned to ci-sandbox (#207)
- (ci) configure-ci.sh applies ci-config.conf as repo variables (#207)
- (ci) add fork CI config template (#207)
- (deploy) wire 14-optional-features into installer chain + prompts (#182)
- (deploy) module 14-optional-features runs opted-in feature setups (#182)
- (deploy) optional-feature catalog + dispatcher with offline test (#182)
- (deploy) add ENABLE_* optional-feature flags to installer config (#182)
- (audit) log SMB user toggle via audit logger (#195)
- (audit) log NFS export mutations via audit logger (#195)
- (deploy) whitelist install-power-sudoers.sh in deploy sudoers (#126)
- (deploy) call install-power-sudoers.sh in SYNC_PERMISSIONS block (#126)
- (deploy) install-power-sudoers.sh — idempotent baluhost-power provisioning (#126)
- (tui) dpkg-deb packaging script for standalone binary
- (tui) PyInstaller entry script for standalone binary
- (tui) persist access token on login for CLI reuse
- (tui) require admin role for RAID screen action + tests (from review)
- (tui) Power screen app-restart/shutdown behind ConfirmDialog
- (tui) api.system.delete_array() (local-channel RAID delete)
- (tui) ConfirmDialog modal + confirm_matches type-to-confirm helper
- (tui) api.users create/update/set_password/delete write ops
- (tui) api.users.list_users() read-only wrapper
- (tui) api.logging query_audit() + filter_logs() helper
- (tui) api.system storage() + raid_status() wrappers
- (tui) api.monitoring current cpu/memory/network wrappers
- (tui) main builds BackendClient (--socket/--server); drop files TUI command
- (tui) remove file-browser screen + dashboard nav (out of scope per spec)
- (tui) app holds BackendClient; drop direct-DB admin seeding + file-browser nav
- (tui) JWT-only LoginScreen over BackendClient (drop direct DB)
- (tui) api.auth.me() to fetch current user
- (tui) api.system channel-status + app restart/shutdown
- (tui) api.auth.login() with typed 2FA/error handling
- (tui) BackendClient httpx wrapper with JWT + verb passthrough
- (tui) resolve_transport() for UDS/TCP selection
- (nfs) add NFS tab to System Control page
- (nfs) NFS management card + i18n (de/en)
- (nfs) typed api/nfs client
- (nfs) admin-only CRUD + status routes
- (nfs) request/response schemas with path/clients validation
- (nfs) export config service (validators, regenerate, apply, status)
- (nfs) NfsExport model + migration
- (activity) admin all-users feed + admin-only system-logs link
- (activity) re-point useActivityFeed to /api/activity with action mapping
- (activity) typed api/activity client for /api/activity/recent
- (activity) scope=all admin view on /api/activity/recent
- (activity) service all_users view + user attribution on ActivityItem
- (updates) releases list links to GitHub (commit_short now nullable)
- (updates) render release notes as markdown; drop dev-channel UI
- (updates) mirror GitHub-releases contracts in the API client
- (updates) DevUpdateBackend returns markdown release notes
- (updates) ProdUpdateBackend reads release-notes/check/releases from GitHub
- (updates) CHANGELOG.md offline fallback parser
- (updates) GitHub Releases client + positional since-last-stable helpers
- (updates) GitHub-releases settings + reshape release-notes schemas
- (tui) delete context.py (no importers after CLI port)
- (tui) main status/users over BackendClient; drop reset-password cmd + --mode
- (tui) move reset-password to backend/scripts (out of TUI package)
- (tui) port status CLI to api.* (drop get_context/app.*)
- (tui) port users CLI to api.users (drop get_context/app.*)
- (tui) RAID screen — direct local-channel delete + ConfirmDialog (drop get_context/token)
- (tui) drop unused Static import in users screen (from review)
- (tui) UserManagementScreen CRUD via api.users (drop direct DB)
- (tui) drop unused Container import in dashboard (from review)
- (tui) AuditLogViewer fetches via api.logging (drop direct DB)
- (tui) Dashboard widgets fetch via BackendClient (drop direct DB/psutil)
- (tui) drop dead test attrs + double token-set (from cutover review)
- (tui) PowerActionsScreen uses app.client (drop get_context)
- (tui) SmartScreen uses app.client (drop get_context)
- (tui) ServiceHealthScreen uses app.client (drop get_context)
- (tui) tidy api.system error msg + document channel-status auth ordering
- (tui) cover 2FA token + transport-error paths in api.auth tests
- (tui) address review (imports to top, clear_token/put/delete tests, annotation)
- (nfs) dedupe card heading, move mount_target to path column, drop unused i18n keys
- (nfs) drop redundant PK index; assert created_at in model test
- (activity) null-guard file_size, doc success/hook module, add error-path test
- (activity) Literal scope type + tidy route-scope tests
- (activity) top-level User import + clarify all_users docstring
- (updates) remove dev-channel update wiring from UpdatePage
- (updates) remove dead development-branch update path
- (presence) sync paused ref in effect to satisfy react-hooks/refs (#222)
- (lifespan) one-shot expiration-warning catch-up on startup (#229)
- (sleep) run expiration-warning catch-up after resume from suspend (#229)
- (notifications) collapse overdue-warning backlog to one message, skip post-expiry (#229)
- (notifications) warner sends due/overdue warnings instead of dropping them (#229)
- (updates) check_for_updates compares via version_sort_key (#120)
- (updates) use isdecimal() in version_sort_key; add crash + list-sort tests (#120)
- (updates) SemVer-correct version_sort_key; stable ranks above its pre-releases (#120)
- (ci) cap tag-sync step with timeout + continue-on-error (#223)
- (ci) sync pre-release tag into /opt/baluhost after deploy tagging (#223)
- (i18n) Umlaut-Tippfehler in presence modeHint (#214)
- (sleep) timeout fallback parity in get_status presence read (#214)
- (sleep) coerce presence_mode through PresenceMode enum (Pylance) (#214)
- (sleep) remove duplicate presence heartbeat schemas (#214)
- (sleep) use ORM query delete for typed rowcount in cleanup_expired (#214)
- (install) close save_config umask window, widen test guard (#212)
- (install) verify-script errexit fix + config-write hardening (#212)
- (install) modules 06/07 persist generated secrets via save_config (#212)
- (install) run installer modules in child bash processes (#212)
- (test) mdadm loopback fixture waits out async udev node removal (#207)
- (deploy) deploy-fork runner fallback + env-pattern for install dir (#207)
- (ci) explicit e2e toggle on live job, consistent guard placement (#207)
- (ci) configure-ci.sh surfaces gh delete errors, scoped parts array (#207)
- (login) make '2FA use backup code' an actual toggle and allow hex backup codes
- (ci) reconcile rootless Podman state + self-test linger/podman info on ci-runner bootstrap (#127)
- (deploy) use @@BALUHOST_USER@@ in NFS/Samba sudoers instead of hardcoded user (#196)
- (audit) rollback before failure-audit + cover NFS update failure branches (#195)
- (backup) includes_config writes a real secret-free snapshot, not an empty stub (#176)
- (sync) scheduled syncs no longer report success while doing nothing (#175)
- (files) remove dead check_active_uploads() stub (#177)
- (scripts) reset_password checks empty before mismatch (from review)
- (tui) dev BackendClient defaults to :8000 (actual start_dev port, not :3001)
- (nfs) reject control chars/whitespace in export path (prevent exports injection)
- (logging) scope file-access stats (by_user) to own user for non-admins
- (logging) scope dev-mode mock file-access logs for non-admins too
- (logging) scope file-access logs to own user for non-admins
- (updates) harden public release-notes fallback (review follow-up)
- (plan) expiry-warner sleep catch-up implementation plan (#229)
- implementation plans for updater version fixes (#223, #120)
- design spec for updater version fixes (#223, #120)
- register presence service in services CLAUDE.md
- register usePresenceHeartbeat in hooks CLAUDE.md
- (plan) review fixes - harden _is_user_present, clarify insertion points (#214)
- (plan) presence-aware suspend implementation plan (#214)
- (spec) presence-aware suspend design (#214)
- (plan) installer bash-module execution fix plan (#212)
- (security) list new fork-CI codeowner paths in Layer 1 (#207)
- link fork CI/self-hosting guide from CONTRIBUTING + README (#207)
- (deploy) self-hosting guide accuracy fixes from review (#207)
- (deploy) bilingual self-hosting + fork CI guide (#207)
- (security) document fork-config layer + mdadm runner pin (#207)
- (ci) annotate fromJSON quoting + gate detection in ci-check (#207)
- (ci) state install-dir default in config template (#207)
- (plans) review fix — warn on ignored runner labels (#207)
- (plans) implementation plan fork-friendly CI/CD (#207)
- (specs) mdadm loopback tests pinned to GitHub-hosted runners (#207)
- (specs) design fork-friendly CI/CD config + deploy-fork (#207)
- align stale Hardware OS line with Debian-only restriction (#182)
- link feature-dependency matrix + Debian-only note from README/DEPLOYMENT (#182)
- (deploy) central feature dependency matrix + Debian-only note (#182)
- (plan) apply review fixes — stdin guard, apt-update guard, full feature test coverage (#182)
- (plan) optional feature modules + dependency docs implementation plan (#182)
- (spec) optional feature modules + dependency docs design (#182)
- (ci) implementation plan for loop-device mdadm integration CI (#185)
- (ci) spec for loop-device mdadm integration CI (#185)
- (audit) implementation plan for NFS/Samba audit logging (#195)
- (audit) spec for NFS/Samba share-mutation audit logging (#195)
- (deploy) implementation plan for PPD-sudoers provisioning (#126)
- (deploy) spec for PPD-sudoers deploy provisioning (#126)
- (tui) .deb packaging + CI plan (plan B of standalone-deb)
- (tui) plan A review fixes (docstring examples + dedup git rm)
- (tui) app.*-free cleanup plan (plan A of standalone-deb)
- (tui) standalone TUI .deb artifact design spec
- (tui) destructive-ops implementation plan (plan 5)
- (tui) supply verbatim import old_string in users-crud plan (from review)
- (tui) users-screen CRUD port implementation plan (plan 4)
- (tui) drop unused DataTable import from dashboard port (from review)
- (tui) read-only screen ports implementation plan (plan 3)
- (tui) clarify power.py guard block in cutover plan (from review)
- (tui) transport-cutover implementation plan (plan 2)
- (tui) note channel-status auth ordering for plan 2 (from review)
- (tui) foundation implementation plan (plan 1 of 3)
- (tui) companion-rebuild design spec (UDS-only, admin/recovery focus)
- (nfs) implementation plan for NFS network shares (#183)
- (nfs) design for NFS network shares (#183)
- (deploy) replace weak default ADMIN_PASSWORD in prod example (#180)
- (deploy) align .env.production.example with systemd deployment (#180)
- (contributing) align git workflow with main-only model (#179)
- add Contributor Covenant Code of Conduct (#188)
- (readme) fix broken documentation links (#178)
- (activity) implementation plan for own-vs-all + leak fix
- (activity) design for activity-feed own-vs-all + leak fix
- (todo) sync roadmap status with current code state
- (updates) frontend plan for update page via GitHub Releases (plan 2/2)
- (updates) clarify _run_dev_update must stay in backend plan
- (updates) backend plan for update page via GitHub Releases (plan 1/2)
- (updates) spec for update page via GitHub Releases
- (admin) PIN-login policy settings card
- (settings) Desktop-app PIN management section (2FA-gated)
- (client) PIN login option on the Login screen (Tauri-only)
- (client) isTauri flag + PIN/auth-policy API client
- (auth) local-channel login-pin + grace window on verify-2fa
- (auth) PIN management endpoints (status/set/remove, TOTP-gated)
- (auth) admin auth-policy endpoints (pin window + kill switch)
- (auth) pin_service (hash/grace/lockout) + clear PIN on 2FA disable
- (auth) PIN policy validator + PIN schemas
- (auth) pin columns on users + auth_policy singleton + migration
- (notifications) admin toggles for desktop disable/enable notifications
- (notifications) type desktop_notifications pref in update payload
- (desktop) emit desktop disabled/enabled notification on success
- (notifications) add desktop event gate + emit helpers
- (notifications) add desktop_disabled/enabled event types, configs, cooldowns
- (devices) sleep-window awareness + bandwidth panel in Schedules tab
- (devices) load bandwidth limits + sleep preflight in device hook
- (devices) support ?tab= deep-linking into device tabs
- (client) proportional size bars in game library list
- (games) filter Proton/runtime tools from libraries
- (client) show Game Libraries card in Storage tab
- (client) GameLibrariesCard component
- (client) games API client + types
- (games) GET /api/games/libraries endpoint
- (games) provider aggregation service with dev mock
- (games) SteamProvider with provider interface
- (games) GameLibrary response schemas
- (games) minimal VDF parser for Steam metadata
- (energy) import-aware, gap-capped interval energy primitive
- (power-tab) custom date range picker for cumulative + instant charts
- (dateUtils) custom chart range format + localRangeToUtcIso helper
- (energy-api) optional start/end range args on cumulative client
- (energy) custom start/end query params on cumulative endpoints
- (energy) arbitrary start/end window in get_cumulative_energy_total
- (energy) arbitrary start/end window in get_cumulative_energy_data
- (plugins) number/retention field renderer (presets + unlimited) in plugin settings
- (smart-device) poller applies per-plugin configured retention
- (tapo) add configurable retention_days (0=unlimited) to plugin config
- (system-permissions) i18n + Desktop toggle in permissions section
- (system-permissions) i18n strings for System Permissions (en+de)
- (system-permissions) add can_toggle_desktop to frontend API types
- (system-permissions) delegate desktop enable/disable via can_toggle_desktop
- (admin) add Retention sub-tab to the database analytics view
- (system-permissions) persist can_toggle_desktop in service + audit
- (system-permissions) add can_toggle_desktop to permission schemas
- (system-permissions) add can_toggle_desktop column + migration
- (admin) RetentionSettings editor component
- (smart-device) trigger daily sample cleanup from poller loop
- (smart-device) category-wide sample retention preserving imported rows
- (monitoring) retention API excludes POWER and rejects it on update
- (api-keys) move admin tab to System Control, delete on revoke
- (statusbar) translate live pills in the frontend via key+params renderer
- (statusbar) emit i18n keys from backup/desktop/always_awake collectors
- (statusbar) emit i18n keys from sleep/vpn/temp/scheduler collectors
- (statusbar) emit i18n keys from power/pihole/uploads/sync/raid collectors
- (statusbar) add live label + value i18n keys (de/en) with parity test
- (statusbar) add i18n key fields to PillState schema (expand phase)
- (power) add 'enable desktop' quick action to PowerMenu
- (sync) remove redundant /sync page and dead code
- (devices) move BandwidthLimitsPanel into device-management
- (power-tab) dedupe range-arg derivation; fix popover re-open + Escape
- (energy) drop dead total empty-window branch; style/docstring cleanup
- (smart-device) isolate per-plugin cleanup failures in poller loop
- (smart-device) per-plugin sample cleanup (0=unlimited)
- (admin) hoist metric config to shared module, add uptime/gpu
- (smart-device) capture now once + document no-await cleanup gate invariant
- (power) remove dead energy.cleanup_old_samples (replaced by smart-device retention)
- (monitoring) drop POWER from RetentionManager (smart-device samples owned elsewhere)
- (api-keys) drop now-unused revoked_at/revocation_reason columns
- (statusbar) drop legacy label field, require label_key (contract phase)
- (settings) accept backup codes in the PIN 2FA-code field
- (settings) make PIN buttons show disabled state + clarify 2FA code is required
- (settings) style the Remove PIN button (btn-danger is undefined)
- (notifications) persist reserved desktop_notifications pref key
- (ui) label power menu actions as BaluHost, drop accent from brand name
- (scheduler) point Sync tab button to /devices?tab=schedules
- (scheduler) point Sync tab button to /sync via client-side nav
- (games) read game size from .acf SizeOnDisk (fixes 0 B entries)
- (client) pluralize game count (1 game vs N games) via i18next count_one/other
- (energy) period-stats energy uses gap-capped integration (matches chart)
- (energy) Total = carry-forward sum of per-device curves (closes #157)
- (energy) gap-capped import-aware integration in get_cumulative_energy_data
- (energy) reject wholly-future custom range (clamp before order check)
- (power-tab) pass custom range on price-edit refresh (fixes tsc -b + 422 in custom mode)
- (energy) restore period pattern on cumulative endpoints; document end clamp
- (plugins) ignore empty number input so clearing the field doesn't trigger the unlimited sentinel
- (dev) start_dev defaults SKIP_SETUP=true (correct env name) so fresh dev DB skips wizard
- (admin) use handleApiError + plural approxDays + a11y/step in RetentionSettings
- (statusbar) show pill icons in the config Live Preview
- (statusbar) drop removed label field from AlwaysAwakePill test fixtures
- (ui) portal ConfirmDialog to document.body so it centers on the viewport
- (security) use SHA-256 for advisory-lock key derivation
- (power) correct boost-rules response type
- (security) scrub exception text, weak hash, cleartext password (CodeQL)
- (ssh) pin remote host keys via TOFU instead of AutoAddPolicy
- (power) serve dynamic-mode capabilities to follower workers (fix intermittent 400)
- (auth) frontend implementation plan for Tauri PIN login (plan 2/2)
- (auth) concrete router registration + accurate remote-channel test note in PIN plan
- (auth) backend implementation plan for Tauri PIN login (plan 1/2)
- (auth) spec for Tauri PIN login (2FA-gated, local-channel only)
- (readme) merge redundant Reference System / Production Stack sections
- (notifications) implementation plan for desktop-disable notifications
- (notifications) spec for desktop-disable/enable notifications
- drop deleted sync modules from components/hooks CLAUDE.md
- (sync) refresh api/sync header + CLAUDE.md row after cleanup
- (plan) de-tangle SchedulesTab steps, simplify dead-ref check
- (plan) consolidate sync schedules into /devices
- (spec) consolidate sync schedules into /devices
- (plan) filter tools, fix sizes, proportional-bar list
- (spec) also fix 0B sizes (.acf SizeOnDisk) and add proportional-bar list
- (spec) filter Proton/runtime tools from game libraries
- (games) note VDF comment limitation; assert available in swallow test
- (games) document game_libraries service module
- (plan) prefix new test files test_games_* to avoid basename collisions
- (plan) Steam game library storage implementation plan
- (spec) Steam game library in storage usage (provider-extensible)
- (energy) note conservative under-count for malformed imports in _interval_energy_wh
- (energy) note why period-stats doesn't reuse _load_parsed_online_sorted
- (plan) record 4dp total_kwh rounding in Task 3 (matches sibling fn)
- (energy) consistent key access + unit/contract notes in integration helpers
- (energy) implementation plan for gap-capped consumption integration (#159)
- (energy) spec for import-aware gap-capped consumption integration (#159)
- (claude) ask before opening a GH issue for out-of-scope side-findings
- (energy) document custom range invariant + custom axis format row
- (power) clarify period_label placement in plan Task 2
- (power) implementation plan for custom date range (Power tab)
- (power) spec for custom date range in System Monitor Power tab
- (plugins) implementation plan for per-plugin smart-device retention config
- (plugins) spec for per-plugin smart-device retention config (Tapo)
- (system-permissions) note UI rename vs kept backend identifiers
- (monitoring) implementation plan for retention UI + smart-device retention
- (monitoring) spec for retention UI + smart-device sample retention
- reposition BaluHost as a self-hosted home server platform
- (statusbar) refine i18n plan after self-review
- (statusbar) implementation plan for live status-strip i18n
- (statusbar) spec for live status-strip i18n (Option A1)
- (power) i18n strings for PowerMenu disable-desktop action (de+en)
- (power) add 'disable desktop' quick action to PowerMenu
- (power) show dynamic-mode governor in power status pill
- (power) show active preset + level in power status pill
- (2fa) readable contrast for 'Verification Code' label in setup modal
- (2fa) readable contrast for secret + backup codes in setup modal
- (deploy) hard-sync git on deploy + rollback to survive dirty tracked files
- (power) implementation plan for PowerMenu disable-desktop action
- (power) spec for PowerMenu quick 'disable desktop' option
- (power) implementation plan for preset in power status pill
- (power) spec for showing active preset in power status pill
- (statusbar) i18n for desktop pill + display-mode (de/en)
- (statusbar) map Monitor icon for desktop pill
- (statusbar) display-mode select in PillRow for configurable pills
- (statusbar) usePillConfig carries display_mode
- (statusbar) frontend types for desktop pill + display_mode
- (statusbar) display-mode filter + validation for desktop pill
- (statusbar) add collect_desktop collector
- (statusbar) add display_mode to status bar schemas
- (statusbar) add display_mode column + migration
- (statusbar) add desktop pill to catalog + PILL_IDS
- (display-switch) start desktop before switching outputs
- (desktop) add Desktop toggle panel to Sleep page
- (desktop) allow service user to start/stop/restart sddm via sudoers
- (desktop) add /system/sleep/desktop status/enable/disable endpoints
- (desktop) add DesktopService singleton
- (desktop) add dev + linux desktop control backends
- (desktop) add DesktopState/DesktopStatus schemas
- (power-ui) allowlist editor + boost-now control (local-only)
- (power-ui) authority toggle + drift/unenforceable badges (local-only)
- (power-ui) show live CPU frequency with target band as secondary
- (power) boost-rule CRUD + boost-now endpoints (local-only); forward target override
- (power) boost-rule CRUD + boost-now endpoints (local-only)
- (power) wire game-session watcher to demand system with hysteresis
- (power) pure boost-rule process matching (game-session + glob)
- (power) power_boost_rules model + migration + seeded game-session rule
- (power) PPD authority service + local-only authority endpoints
- (power) wire 2s enforcement loop (primary, authority-gated)
- (power) enforce current profile with drift detection + re-assert
- (power) centralize desired config with 400MHz floor + boost override
- (power) add read_enforcement_state() to CPU backends
- (sleep) query logind CanSuspend via D-Bus, not phantom
systemctl can-suspend - (deploy) install + sync hardware sudoers (closes #131)
- (desktop) update toggle panel copy for DPMS behavior
- (desktop) toggle displays via DPMS instead of stopping sddm
- (deploy) use @@BALUHOST_USER@@ token in power sudoers template
- (power) make PPD acquire idempotent; build authority response via plain helper
- (power) chain power migrations onto current head (b48340a96a5a)
- (power) derive status freq_range from active preset (+400 floor), not defaults
- (power) guard PUT boost-rule re-fetch race; test enabled=false disabling
- (power) primary-gate boost override; reset absent-ticks when rules vanish
- (power) fail authority-enable when PPD acquire fails; tidy ppd_authority (running_loop, status, logs)
- (power) log drift once per episode while still re-asserting each tick
- (power) flag cap_unenforceable on apply failure + cover re-assert-sticks path
- (update) derive service user/group from install dir owner
- (monitoring) lift BaluHost card above chart when breakdown open
- (monitoring) hide Frontend (dev) in prod, overlay RAM breakdown
- (plan) KDE desktop pill for the status bar (12 tasks, TDD)
- (spec) KDE desktop pill for the topbar status strip
- (plan) record response:Response requirement for rate-limited handlers
- (plan) fix verified-fact errors in desktop-toggle plan
- (plan) desktop (KDE/SDDM) toggle under Sleep + display-switch guard
- (power) implementation plan for CPU power authority
- (power) 2s tick, preset-derived cap (400 floor), per-rule boost target
- (power) spec for CPU power authority (enforced cap + allowlist boost)
- (statusbar) i18n-driven wake pill (always-awake + core-hours variants)
- (statusbar) always-awake pill falls back to active Kernbetriebszeit
- (updates) don't label pre-release builds as "Stable"
- (deps) bump axios to ^1.16.0 to patch 4 advisories
- (ci) derive pre-release tag from last stable + patch bump
- (statusbar) VPN-Pill zeigt verbundene Peers statt roher Client-Anzahl
- (plan) status-strip wake pill implementation plan (2026-05-29)
- (spec) status-strip wake pill — always-awake + kernbetriebszeit fallback (2026-05-29)
- (statusbar) gate bottom upload bar by show_bottom_upload setting
- (statusbar) register Status Bar tab under System Control
- (statusbar) admin config tab with dnd reorder + live preview
- (statusbar) sortable PillRow with locked-visibility handling
- (statusbar) usePillConfig admin config hook
- (statusbar) i18n statusBar namespace (de/en) + tab label
- (statusbar) mount TopbarStatusStrip in the desktop topbar
- (statusbar) TopbarStatusStrip container with preview support
- (statusbar) pill renderer switch
- (statusbar) always-awake pill with live countdown
- (statusbar) lucide icon-name resolver
- (statusbar) native polling hook with pause-when-hidden
- (statusbar) useCountdown hook with re-anchor
- (statusbar) tone-aware Pill primitive
- (statusbar) typed frontend API client
- (statusbar) API router for config + state with audit logging
- (statusbar) add status_polling rate-limit key
- (statusbar) collect_state with role filter and sort order
- (statusbar) config update with locked-visibility guard + diff
- (statusbar) aggregator service config read with seed-on-read
- (statusbar) collector registry covering the full catalog
- (statusbar) backup collector (in-progress + 24h failure window)
- (statusbar) scheduler collector (active count + job names)
- (statusbar) always-awake collector with countdown formatting
- (statusbar) collectors for power/pihole/uploads/sync/raid/sleep/vpn/temp
- (statusbar) 11-pill catalog with drift test
- (statusbar) pydantic schemas for config and state
- (statusbar) add status_bar_pill_config and status_bar_settings tables
- (i18n) BaluHost memory unit labels (en/de)
- (ui) per-unit BaluHost memory breakdown in MemoryTab
- (client) MemorySample.baluhost_memory_breakdown type
- (api) expose baluhost_memory_breakdown in /monitoring/memory/current
- (monitoring) get_baluhost_memory_breakdown() per-unit RSS map
- (monitoring) first-match-wins routing in process_tracker.collect_samples
- (monitoring) expand BaluHost process patterns to all systemd units
- (setup-ui) show remote-channel banner when not local
- (tauri) main entry + window-global injection for api.ts
- (tauri) proxy.rs forwarding HTTP to /run/baluhost/local.sock
- (tauri) scaffold src-tauri/ with Cargo + tauri.conf
- (client) Tauri-aware API base URL via window global injection
- (users-ui) gate bulk-delete via LocalOnlyAction
- (plugins-ui) gate install/uninstall via LocalOnlyAction
- (raid-ui) gate destructive buttons via LocalOnlyAction
- (client) add LocalOnlyAction component + i18n keys
- (client) add useChannelStatus hook (no react-query, follows useGpuPresence pattern)
- (client) add getChannelStatus API client
- (users) gate bulk-delete via require_local_admin
- (vpn) gate sync-server-keys via require_local_admin
- (raid) gate destructive array operations via require_local_admin
- (plugins) gate install/uninstall via require_local_admin
- (setup) gate wizard endpoints via require_local_or_setup_secret
- (backend) add require_local_or_setup_secret for setup wizard
- (backend) add require_local_admin dependency with audit logging
- (backend) add GET /api/system/channel-status endpoint
- (backend) wire ChannelMarkerMiddleware into app factory
- (backend) add ChannelMarkerMiddleware with provider injection
- (backend) add channel + loopback-fallback settings fields
- (client) hide 0°C dead sensors + clarify renamed sensors
- (client) advanced settings, GPU manual-mode toggle, GPU badge, sensor label
- (client) curve type selector + 5 typed curve editors
- (power-dev) add simulated AMD GPU fan to dev backend
- (client) SensorsPanel with rename + composite sensor modal
- (api) extended FanInfo schema + GPU manual-mode endpoint
- (api) sensor label + composite sensor endpoints
- (power) wire TempSourceRegistry + evaluate_curve into FanControlService
- (power) AMD GPU manual-mode unlock helper with state restore
- (power) GPU fan recognition + EINVAL diagnostic capture
- (power) add fan_curve_eval with 5 curve types and post-processing
- (power) add GPU, Disk, and Mix temperature sources
- (power) add TempSource protocol + registry with hwmon source
- (models) add TempSensorLabel, CompositeTempSensor; extend FanConfig
- (db) add fan overhaul migration (labels, composites, fan_config columns)
- (ci) bootstrap script for ci-runner sandbox
- (client) render OsAutoSuspendCard on Sleep page
- (client) OsAutoSuspendCard component
- (client) i18n keys for OsAutoSuspend (de + en)
- (client) sleep.ts adds getOsAutoSuspend / setOsAutoSuspend
- (sleep) inspector surfaces KDE/GNOME idle suspend as info issue
- (deploy) install module 13-power-helpers (helper + sudoers)
- (deploy) sudoers template + logind idle helper script
- (sleep) add GET/PUT /os-auto-suspend routes with audit log
- (sleep) os_auto_suspend service-layer get/set
- (sleep) ActivePmDetector with D-Bus probes and 30s cache
- (sleep) GnomeAdapter via gsettings
- (sleep) KdeAdapter.write (atomic, preserves other sections)
- (sleep) KdeAdapter.read parses ~/.config/powerdevilrc
- (sleep) LogindAdapter.write via sudo helper
- (sleep) LogindAdapter.read with drop-in merge
- (sleep) scaffold os_auto_suspend module with shared protocol
- (sleep) add OsAutoSuspend schemas (response, update, action enum)
- (nginx) opencode reverse-proxy site (LAN-only HTTPS on :8443)
- (sleep) add _reconcile_sleep_inhibitor helper covering always-awake
- (statusbar) drop unused anchorRef in useCountdown
- (sleep) schedule loop delegates inhibitor management to reconcile helper
- (statusbar) scheduler pill click-through to /schedulers (was dead /admin/schedulers)
- (statusbar) resolve pill name i18n key (strip namespace prefix) in config tab
- (statusbar) render dynamic pill icon via createElement (lint: static-components)
- (statusbar) satisfy verbatimModuleSyntax and react-jsx in build
- (statusbar) skip malformed collector output instead of failing /state
- (statusbar) sync collector reports only conflicts + collector polish
- (statusbar) add server_default to status bar migration columns
- (ci) don't persist GITHUB_TOKEN in tagging checkout
- (client) add baluhost_memory_breakdown to CurrentMemoryResponse type
- (tauri) skip WS/SSE in Companion to prevent ErrorBoundary on login
- (tauri) route remaining proxy-bypassing URL constructions through buildApiUrl
- (tauri) route bare fetch('/api/...') calls through buildApiUrl
- (tauri) rewrite Origin header so backend CORS accepts proxy calls
- (tauri) drop /api from injected base URL; restore CSP
- (tauri) drop strict CSP that blocked initialization_script
- (tauri) regenerate icon as RGBA
- (tests) use new event loop in chunked_upload fixture teardown
- (deploy) align local-channel service EnvironmentFile with existing convention
- (backend) audit-log + constant-time compare in setup-secret gate
- (fans) suppress amdgpu/nouveau hwmon duplicates of gpu:* sources
- (fans) SMART summary in SHM; disk:* sources fed from there
- (monitoring) publish GPU sample in telemetry SHM snapshot
- (ci) target deploy-production on 'prod'-labeled runner only
- (ci) install passt for rootless Podman bridge networking
- (security) renumber new ci-runner gap to 8 (was 11)
- (sleep) detect KDE/GNOME via pgrep instead of session-bus probe
- (ci) address code review on bootstrap script
- (sleep) release inhibitor synchronously when manual sleep/suspend clears always-awake
- (sleep) reconcile inhibitor at startup also when always-awake is active
- (plan) topbar status strip — phase 2 (frontend strip) + phase 3 (config tab)
- (plan) topbar status strip — phase 1 backend implementation plan
- clarify live-only contract for baluhost_memory_breakdown
- note that _find_processes is no longer called by collect_samples
- clarify process_tracker docstrings + test comments (Task 1 follow-up)
- (spec) topbar status strip refresh — 11 pills incl. Always Awake/Scheduler/Backup (2026-05-27)
- (plan) RAM per-unit breakdown implementation plan
- (spec) RAM per-unit breakdown design (2026-05-27)
- companion app install guide
- (plan) tauri companion + local-channel gate implementation plan
- (spec) tauri companion app + local-channel gate
- add fan overhaul design spec and implementation plan
- (security) document ci-sandbox runner and ci-tests environment
- implementation plan for self-hosted backend tests
- spec for self-hosted backend tests with rootless Podman sandbox
- (plan) OS auto-suspend bidirectional implementation plan
- (spec) OS auto-suspend bidirectional design
- (sleep) document dual purpose of core_uptime_inhibitor field
- (client) wire History import button into SmartDeviceCard
- (client) TapoHistoryImportModal with DE/EN i18n
- (client) smart-devices.ts history import wrapper
- (api) POST /smart-devices/{id}/import-history endpoint
- (tapo) plugin.import_history() — admin history backfill entry point
- (tapo) import service with idempotency + conflict resolution
- (tapo) mock history fetcher for dev mode
- (tapo) TapoHistoryFetcher for hourly/daily/monthly buckets
- (smart-device) add ImportHistoryRequest/Response schemas
- (energy) preserve imported samples in cleanup_old_samples
- (notifications) user-configurable trash retention slider (1-7 days)
- (notifications) Inbox/Trash tabs with restore + delete-forever
- (notifications) frontend types + trash API functions
- (notifications) hourly trash cleanup job (Firebase-independent)
- (notifications) add DELETE /{id} + DELETE /trash endpoints
- (notifications) add POST /{id}/restore endpoint
- (notifications) add GET /notifications/trash
- (notifications) cleanup_expired_trash respects per-user retention
- (notifications) add empty_trash() for bulk hard-delete
- (notifications) add delete_permanently() for hard delete
- (notifications) add restore() to bring a row back from trash
- (notifications) dismiss now writes deleted_at timestamp
- (notifications) expose deleted_at + trash_retention_days in schemas
- (notifications) migrate is_dismissed → deleted_at with 1-7d retention
- (user-menu) wire Quick-Settings into the dropdown
- (quick-settings) UserMenuQuickSettings container with Modal
- (quick-settings) add TwoFactorPromptSection + i18n keys
- (quick-settings) add ByteUnitSection
- (quick-settings) add LanguageSection
- (quick-settings) extract TwoFactorSetupFlow from settings card
- (quick-settings) lazy 2FA status store with React hook
- (ui) add closeOnOverlayClick and closeOnEscape props to Modal
- (sleep) live validation + max-hint for always-awake datetime picker
- (sleep) always-awake custom datetime button (capped 7d)
- (sleep) mount OsSleepSettingsBanner at top of Sleep page
- (sleep) OsSleepSettingsBanner component
- (sleep) i18n strings for os-settings banner + custom datetime
- (sleep) frontend api client for os-settings
- (sleep) GET /api/system/sleep/os-settings (admin)
- (sleep) add OsSleepReportResponse + 7-day always-awake cap
- (sleep) wire os_sleep_inspector with systemctl + cache + resilience
- (sleep) add os_sleep_inspector classifier rules
- (sleep) add os_sleep_inspector INI parser and platform guard
- (tui) add SMART / disk-health screen
- (tui) add Service Health & Restart screen
- (tui) add Power Actions screen (sleep/wake/suspend/WoL)
- (tui) acquire JWT on login to authenticate API-driven screens
- (sleep) always-awake hint in SleepConfigPanel schedule block
- (sleep) always-awake banner in SleepModePanel
- (sleep) mount AlwaysAwakePanel on Sleep page
- (sleep) AlwaysAwakePanel component
- (sleep) API client types for always-awake
- (sleep) audit log + API tests for always-awake toggle
- (sleep) update_config handles always-awake clear/disable correctly
- (sleep) expose always-awake in status + config responses
- (sleep) manual sleep/suspend clears always-awake override
- (sleep) always-awake guard in schedule loop + escalation + expiry cleanup
- (sleep) always-awake guard in idle detection loop
- (sleep) _clear_always_awake helper with audit logging
- (sleep) _is_always_awake helper
- (sleep) add always_awake columns to SleepConfig
- (sleep) pydantic schemas for always-awake override
- (stats) wire CLI main with --check and --write modes
- (stats) add idempotent marker-based text splice
- (stats) render markdown for project stats and inline test counts
- (stats) add compute_stats() aggregator
- (stats) add tracked_files() and path filters
- (stats) add count_test_functions() via AST
- (stats) add count_lines() with wc -l semantics
- (ci) switch auto-merge to pre-release tags
- (ci) add release-stable.yml for manual stable promotion
- (version) add useVersionDisplay hook for badge consumers
- (updates) show Pre-Release badge in UpdateOverviewTab
- (version) add is_prerelease field and useVersionDisplay hook
- (updates) set is_prerelease=False on dev backend
- (updates) tag-based version detection with is_prerelease
- (schemas) add is_prerelease to VersionInfo
- (scripts) add insert_changelog_section.py
- (scripts) add generate_changelog_section.py
- (scripts) add --dry-run flag to bump_version.py
- (tapo) align import service with live path per review
- (tapo) clean up TapoHistoryFetcher per review
- (notifications) drop stale include_dismissed from frontend API client
- (notifications) drop include_dismissed param, update dismiss docs
- (notifications) swap include_dismissed for trashed_only
- (pihole) align UI with app design system + i18n
- (settings) use TwoFactorSetupFlow in TwoFactorCard
- (sleep) drop frozen=True on OsSleepReport (mutable containers)
- (tui) drop unused monkeypatch fixture, add missing type hint
- (scripts) clean up classify branch and enforce CLI mutex
- (scripts) collapse redundant branch and relocate dry-run tests
- (tapo) decode entries as EnergyDataIntervalResult objects (not ints)
- (tapo) use correct EnergyDataResult attribute names
- (notifications) persist trash_retention_days on preferences update
- (quick-settings) open 2FA modal from user menu
- (notifications) model server_default + remove unused import + portable boolean default
- (impersonation) make banner full-width and push layout down
- (quick-settings) close dropdown on 2FA modal open + lock Modal X button
- (dashboard) make expanded CPU/GPU card fully opaque
- (sleep) suppress phantom lifecycle.suspend pushes during core uptime
- (sleep) discard systemctl result when line count mismatches query
- (tui) correct API paths + field names for sleep/SMART screens
- (tui) escape Rich markup + unique row keys + non-admin smart guard test
- (tui) guard None row-key + cover non-list services response
- (tui) skip JWT call when backend offline + clear stale token on relogin
- (alembic) re-parent always_awake migration onto gpu_caps head
- (tui) remove duplicate action_logs that bypassed auth check
- (sleep) correct preset i18n key casing in AlwaysAwakePanel
- (sleep) always-awake panel — track active preset, fix expiry leak + rollback
- (gpu-power) publish capabilities for followers + unblock body routes
- (stats) normalize CRLF when comparing README in main
- (stats) normalize CRLF in replace_between_markers for Windows
- (stats) drop redundant exclude_init on db_migrations and exercise alembic scope
- (stats) resolve relative paths against ROOT in count helpers
- (plan) notifications trash + retention implementation plan
- (spec) notifications trash + retention design
- (plan) notifications trash + retention implementation plan
- (spec) notifications trash + retention design
- (plans) user quick-settings dropdown implementation plan
- (specs) user quick-settings dropdown
- (plans) backend refactor backlog implementation plan (2026-05-08)
- (plans) TODO for core-uptime polkit denial on prod (BaluNode)
- (plan) sleep page OS-settings banner + always-awake custom datetime
- (spec) sleep page OS-settings banner + always-awake custom datetime
- (plans) add 2026-05-08 TUI critical fixes plan
- (tui) mark action_logs fix + 3 critical screens as done in audit
- (rules) retire development branch from git workflow rule
- (readme) wire stats markers and remove inline counts from architecture tree
- (superpowers) plan README stats automation
- (commands) add release-stable slash command
- (commands) simplify release PR slash command
- (superpowers) add release flow pre-release default plan
- (superpowers) add release flow pre-release default spec
- Core Uptime RTC Guard: New
CoreUptimeRtcGuardlistens to logind'sPrepareForSleepD-Bus signal and pre-arms an RTC wake alarm (rtcwake -m no -t <next_core_start>) for any suspend that bypasses BaluHost (e.g.mate-screensaver, KDE-Plasma, manualsystemctl suspend). Closes the gap where third-party suspends outside an active core-uptime window left the server suspended past the next window start.
- Polkit rule template now also grants
org.freedesktop.login1.inhibit-delay-sleepto the BaluHost service user (re-run the install / update path or manually update/etc/polkit-1/rules.d/50-baluhost-inhibit-sleep.rules).
- Added
dbus-next>=0.2.3,<1.0.0(pure-Python async D-Bus client).
- Sleep: capability badges correctly detect Suspend and Wake-on-LAN —
systemctl can-suspendandethtoolnow run via sudo so polkit/CAP_NET_ADMIN restrictions don't make working features look unavailable (#70)
- Deploy: use
@@-token in polkit inhibit-sleep rule template sopkla-check-authorizationparses the user list correctly (#69)
- Alembic: shorten
gpu_power_multi_workerrevision id to fitalembic_version.version_numvarchar(32)column (#68)
- GPU Power: multi-worker DB schema for runtime state, power demands, and command queue
- GPU Power: cross-worker command queue with DB-backed runtime state
- GPU Power: primary/follower role wiring into GPU manager startup
- GPU Power: tests covering follower routing, command queue, and DB-backed demands (#67)
- GPU Power: GPU power manager is now safe across multiple Uvicorn workers — followers no longer race the primary on sysfs/
nvidia-smiwrites
- Power: multi-worker DB schema for runtime state, demands, and command queue
- Power: cross-worker command queue with DB-backed runtime state
- Power: primary/follower role wiring into worker startup
- Power: tests covering follower routing, command queue, and DB-backed demands (#66)
- Deploy: grant AMD GPU sysfs write access to the service user
- Power: CPU power manager is now safe across multiple Uvicorn workers
- Sleep:
logindblock-sleep inhibitor that holds an inhibitor lock while a core-uptime window is active - Deploy: install polkit rule allowing the service user to take sleep inhibitors
- Sleep: Core operating hours — define windows during which the system must stay awake
- Sleep:
CoreUptimeWindowmodel,core_uptime_enabledconfig column, and Alembic migration - Sleep: pure helpers for window matching, Pydantic schemas for windows
- Sleep: REST endpoints for core uptime windows + frontend API client
- Sleep: core uptime panel with per-window edit card, banner, and suspend warning (i18n)
- Sleep: clamp suspend
wake_atand skip auto-escalation during core uptime - Sleep: suppress scheduled sleep, auto-wake on core uptime start, block auto-idle during windows
- Sleep: expose core uptime block in status + config responses
- Migration: extend
metrictypeenum withPOWERandUPTIMEbefore seeding the GPU row
- Disk Monitor: read
/proc/mdstatdirectly instead of spawning anmdadmsubprocess - Sleep: tighten schemas, drop forward references and unused imports, single
now()per schedule tick - Dependencies: bump
postcssto 8.5.10 inclient/
- GPU Monitoring: backend protocol with AMD sysfs and dev mock backends,
GpuMetricCollectorwith orchestrator hookup,GpuSamplemodel and migration - GPU Monitoring: NVIDIA backend via
nvidia-smi, prefer real GPU over mock when available - GPU Monitoring: API routes (
/api/monitoring/gpu/{info,current,history}), frontend API client,useGpuPresencehook - Dashboard: GPU quick-stat card with presence gating, combined CPU+GPU dashboard panel with split vendor-colored glow, temperature display, GPU usage chart, and chevron-toggled expand
- System Monitor:
GpuTabwith presence-gated registration, click-to-expand details - GPU Power Management: Pydantic schemas, database models and migration, backend protocol with dev mock, AMD sysfs backend, NVIDIA
nvidia-smibackend, DRM display connector detector - GPU Power Management: plugin event hook registry, JSON config persistence, three-state machine manager, FastAPI lifespan wiring, capability-validated API routes, admin status dashboard registration, typed frontend API client, admin UI card on Power Management page
- Notifications: lifecycle category — startup, shutdown, suspend, and resume push notifications with cooldowns and downtime context
- Notifications:
SystemLifecycleEventmodel, migration, sync+async helpers (format_duration_human,german_trigger_label), routing config, "Alle löschen" archive action, "clear all" dismiss button - Monitoring:
NvidiaSmiBackendfor monitoring stack - UI: themed thin scrollbar for sidebar navigation
- Docs: GPU monitoring design spec and implementation plan, GPU power management design and implementation plans, lifecycle push notifications spec and plan, service-layer structural code-quality audit, TUI feature audit, refreshed README LOC stats
- Notifications: include
lifecycleinNotificationCategoryEnum - Dashboard: redirect plugin panel placeholder to
/plugins, apply hover glow via inline style - i18n: repair UTF-8 mojibake in
system.json(de/en) - CI: patch
shutil.whichin NVIDIA backend tests so detection logic proceeds on runners withoutnvidia-smi
- GPU Power: card styling matches existing app conventions
- Dashboard:
CpuGpuPanelaligned with sibling card design and hover effect
- Plugins: return 503 instead of 500 when marketplace setup fails
- CI: use fast-forward-only merge when syncing main → development to avoid merge commits
- Security policy (SECURITY.md) with private reporting channels and coordinated disclosure process
- GitHub issue templates (bug report, feature request) with structured forms
- Contributing guide: clarify that all PRs must target
development;mainis release-only
- Plugins: manifest model and multi-path plugin manager
- Plugins: dependency resolver with core-version gating
- Plugins: installer pipeline with download, checksum verification, pip-install, and atomic swap
- Plugins: plugin SDK with
validate/packCLI, registered asbaluhost-sdkentry point - Plugins: marketplace service with index fetching and conflict detection
- Plugins: marketplace API routes with permission gating
- Plugins: Marketplace tab on the Plugins page with search, install and conflict dialog
- Plugins: update-check service with scheduler integration and push events
- Docs: plugin marketplace design spec; Plugins page documentation updated with
device:controlpermission, smart-device hooks, and marketplace hint
- Dependencies: bump pytest to 9.x
- Plugins: in-repo
baluhost-plugins/prototype imported and marked as deprecated in favor of the external marketplace repo
- Scheduler: dedupe sync_check history entries and emit push notification on scheduled sync success
- Auth: dev-mode admin→user impersonation with banner, user-menu switcher, audit logging, and e2e happy-path test
- Auth: optional
impersonated_byclaim on access tokens, dev impersonation route handler with startup warning - Login: dynamic admin credentials hint on dev login page, served via
/api/system/modedev_credentialsfield - Setup: language selector on the welcome page
- Manual: redesigned chapter landing page with intro and "Start" CTA
- Notifications: filter category preferences in user view to only show admin-routed categories
- Security: update axios to 1.15.0 to resolve critical vulnerabilities
- Unused
theme.pngasset
- Notifications: redesign category settings table with error/success/mobile/desktop columns
- Notifications: delivery-status endpoint for device availability
- Notifications: emit scheduler completed notifications
- Notifications: per-admin mobile preference check in push delivery
- Notifications: CategoryPreference type update and getDeliveryStatus API
- System Monitor: click-to-expand for per-thread CPU charts
- UI: use logo image on loading screen
- Notifications: scope mobile gate to admin devices only in _send_push_sync
- Pi-hole: normalize Pi-hole v6 query statuses for analytics
- Dependencies: update Vite to 7.3.2 to fix security vulnerabilities
- Power menu: sleep and suspend options for admins
- Notifications: emit sync-completed event when mobile folder sync finishes
- Notifications: filter out empty notifications and add time_ago for WebSocket-delivered items
- Cloud: include OAuth credentials in rclone config for token refresh
- Cloud export: scope upgrade endpoint — "Grant write access" now redirects to OAuth
- Manual: cloud import setup guide (DE/EN) with DuckDNS and OAuth instructions
- Cloud: connection deletion failing when import jobs exist (ForeignKeyViolation)
- Routing: /backups redirect for legacy notification URLs
- Tests: docs route tests updated for unauthenticated access
- Manual: overview landing page with card-based navigation (replaces flat grid)
- Manual: complete bilingual DE/EN translations for all user manual articles
- Setup: user manual feature card on welcome screen
- Setup: user manual drawer in setup wizard
- Docs: allow unauthenticated access to docs endpoints
- Style: refined hover effects on docs overview cards
- Notifications: correct backup notification
action_urlto valid route
- Power: cumulative/instant chart mode toggle for energy chart
- Notifications: use optimistic updates and sync context on dismiss
- Schedulers: allow all authenticated users to view scheduler list
- Notifications: normalize timezone-naive
expires_atfrom PostgreSQL to UTC-aware before datetime comparison in device expiration check
- Firebase: device selector in test notification UI
- Firebase: initialize Firebase SDK and EventEmitter in scheduler and monitoring worker processes — push notifications were silently failing since the scheduler was extracted into a separate process (Feb 2026)
- Firebase: accept string device_id without int conversion
- Samba: allow mixed-case usernames in validation regex
- Cloud: improve OAuth redirect handling and error responses
- Tests: update stale imports in logging tests after services reorganization
- Notification Routing — Admin-configurable notification categories for non-admin users
- Admins can assign notification categories (RAID, SMART, Backup, Scheduler, System, Security, Sync, VPN) per user
- New
user_notification_routingdatabase table with per-category boolean flags - Admin endpoints on
/api/users/{id}/notification-routingfor viewing and updating GET /api/notifications/my-routingread-only endpoint for users to see assigned categories- Routed users receive both push (Firebase) and in-app (WebSocket) notifications
- User's own NotificationPreferences (quiet hours, channel opt-out) respected after routing
- Per-user notification copies created for routed users so they appear in notification list
- Frontend toggle UI in user edit modal with category icons and descriptions
- Read-only badge display in user's notification settings showing assigned categories
- Audit logging for routing changes
- Dependencies — Audit logger added as FastAPI dependency for cleaner injection
- Sleep: use atomic rtcwake suspend to fix scheduled wake-up failure
- Security: add defense-in-depth username validation for Samba
- Security: harden config defaults and add production validators
- Refactor: add
ensure_db()context manager to deduplicate session boilerplate - Refactor: remove legacy
sys.modulesbackward-compat shims
- Sleep-Aware Sync — Automatic syncs respect admin sleep schedules
GET /api/sync/preflightendpoint for clients to check sync availability- Server-side guard rejects auto/scheduled syncs during sleep with 503 + Retry-After
X-Sync-Triggerheader distinguishes auto vs manual sync requests- Auto-wake middleware skips wake for auto/scheduled syncs during sleep
- Sync schedule validation prevents creating schedules in planned sleep windows
- Frontend sleep conflict warnings on schedule form and schedule list
- Client integration guide for BaluDesk (C++/Electron) and BaluApp (Kotlin/Android)
- Pi-hole — Clickable column sorting on all Pi-hole tables
- Auth: log notification emit errors instead of silently swallowing them
- Sync: make
auto_vpnmigration safe whensync_schedulestable is missing - Sync: recreate sync tables erroneously dropped by refresh token migration
- Power Permissions — Granular per-user power action delegation for mobile app users
- Admins can grant individual permissions: Soft Sleep, Wake, Suspend, Wake-on-LAN
- New
user_power_permissionsdatabase table with foreign keys to users - Implication logic: enabling Soft Sleep auto-enables Wake, enabling Suspend auto-enables WoL (and reverse)
GET /api/system/sleep/my-permissionsendpoint for mobile app permission fetching- Admin endpoints on
/api/users/{id}/power-permissionsfor viewing and updating - Power action endpoints (
/soft,/wake,/suspend,/wol) now accept delegated users, not just admins - Audit logging for permission changes and delegated power actions
- Frontend toggle UI in user edit modal (Settings > Users) with implied-permission indicators
- Setup Wizard — First-time configuration wizard for fresh BaluHost installations
- Admin account creation, user setup, file access configuration
- Welcome screen with cat logo, progress indicator, security-guarded endpoints
- Frontend integration with gated routing (blocks app until setup completes)
- Integrations Tab — New tab in Settings for managing cloud provider credentials
- Per-provider cards (Google Drive, OneDrive, iCloud) with configuration status and capability badges (Import/Export)
- Inline OAuth credential forms for Google Drive and OneDrive
- Admin overview table showing all users' configured integrations
- iCloud displays "Import only" hint (login remains in Cloud Import wizard)
- VPN Page Unification — Unified VPN management page with profile CRUD
- VPN profile creation/editing with Modal component
- Fritz!Box upload UI replaced by profile-based workflow
- CloudConnectWizard simplified — inline OAuth configuration removed, redirects to Settings > Integrations for unconfigured providers
- Update service reads version from
pyproject.tomlinstead of git tags - User manual overhauled for v1.23.0
- SQLite race condition on dev startup — stagger worker starts
- Plaintext admin password removed from deployment notes
- Modal rendering via portal to escape ancestor stacking contexts
- VPN profile form and list restyled to dark theme
- Unused toast import removed from VPNProfileForm
- VPN Profile Export — Export VPN profiles as QR code or file download
- QR code generation for configs under 1800 bytes (scanner-compatible threshold)
- Automatic fallback to download mode for large OpenVPN profiles with embedded certs/keys
- Export dialog with copy-to-clipboard, direct download, and config preview
- Full audit logging for export operations
- Release Workflow — Label-based release automation via PR (
release:patch/minor/major)
- VPN Profiles section added to VPN Management page for admin workflow
- SQLite Lock Contention — Added
busy_timeout=30s, WAL mode, andcommit_with_retrywith exponential backoff for background workers (PiHole collector, scheduler, WebDAV) - Mobile Device last_sync — Device tracking middleware now updates
last_syncon file upload/download/sync operations; sync folder updates propagate to parent device - File Permissions — Use shareable users endpoint for permission/ownership dialogs
- Storage Permissions & Notifications — Shared
baluhostLinux group infrastructure with setgid for safe multi-process file ownership on RAID mounts- New
STORAGE_PERMISSION_ERRORnotification event with FCM push to admin mobile devices - 5-minute cooldown per path prevents notification spam
_emit_permission_errorhelper catches OS PermissionError in all file operations (upload, delete, rename, move, create folder)- New
storage_groupconfig setting (default:baluhost)
- New
- Docs-as-Manual — Dynamic manual tabs served from backend docs API
/api/docs/indexand/api/docs/articleendpoints with DocsServiceuseDocsIndexanduseDocsArticlehooks, DocsGroupTab component- Multilingual docs with
.de/.ensuffix convention andmanual-index.json
- HTTPS/SSL — Nginx HTTPS template and self-signed certificate setup with client trust guide
- User Home Storage Indicator — Storage usage display per user in FileManager
- Samba
force groupnow usesstorage_groupsetting instead of service user name - Samba system users created with
--group baluhostfor storage group membership - systemd service template uses
Group=baluhost - Samba setup script accepts
STORAGE_GROUPvariable
- PermissionError on RAID mounts — All file operations now catch OS-level PermissionError and return 403 instead of 500
- Startup PermissionError — Handle permission errors on RAID mountpoints during startup gracefully
- Dependabot — Patched 5 security vulnerabilities
- Frontend — Removed unused title destructuring in ArticleView
- Added CLAUDE.md files for all backend and frontend sub-modules
- Storage permissions design spec and implementation plan
- Cloud Export — Share files to cloud providers (Google Drive, Dropbox, OneDrive) with OAuth2 integration, upload/share-link adapters, scope checks, and retry support
- Cloud Shares tab in SharesPage with stats and job list
- Unified ShareFileModal with internal + cloud export tabs
- Full i18n support (en + de)
- Integration tests for export flow
- User Manual Page — Three-tab layout (Setup, Wiki, API Reference) with markdown rendering, replacing the old ApiCenterPage
- ArticleCard, ArticleView, VersionBadge components
- useManualContent hook with initial cloud-import article
- Storage Permissions — Permission constants and helpers applied across upload, folder creation, and home directory operations
- Sortable Tables — Reusable SortableHeader component and useSortableTable hook with 3-stage sort cycle (asc → desc → default)
- Sortable columns in FileListView (Name, Size, Modified, Owner)
- Sortable columns in SharesPage (all 3 tabs)
- Sortable columns in PiholeLocalDns (Domain, IP)
- Sortable columns in UserTable (all columns)
- Upgraded AdminDataTable to 3-stage sort cycle
- SSL Setup — Self-signed SSL setup script for LAN deployments
- Removed old ApiCenterPage (replaced by UserManualPage)
- Removed unused Docker and monitoring stack files
- Added
@tailwindcss/typographyandreact-markdowndependencies
- FileManager — Owner name display for non-admin users now resolved correctly
- TypeScript — Relaxed useSortableTable generic constraint, fixing 157 TS errors
- Pi-hole — Handle naive datetimes from SQLite in ad discovery background poll
- Cloud Export — Type safety fixes and added delete_file to adapter base class
- Manual — TypeScript error in lucide icon resolution
- Storage — Permissions applied consistently across upload, folder creation, and home dirs
- Stabilized getValueForSort reference to avoid unnecessary re-sorts in sortable tables
- Sync Folder Update — PUT endpoint for updating sync folder configuration (remote path, sync type, auto-sync, status)
- File Checksum — Expose file checksum in directory listing response for client-side change detection
- Smart Device — Use
anyio.from_thread.runfor async calls from sync worker threads, preventing event-loop errors
- Mobile Device Naming — User-chosen device name from QR generation is now persisted and applied when the device registers, instead of being replaced by the auto-detected app name
- Energy Dashboard — Fixed power_monitor reading using wrong key (
current_power→watts), causing dashboards to always show 0W - File Upload Rate Limits — Increased from 20 to 1000 requests/min to prevent throttling during bulk uploads
- Fan Control UI — Hide backend badge in production mode
- Power Manager — Handle race condition when power demands register before backend initialization
- Centralized Version Bumping —
scripts/bump_version.pysyncs version across pyproject.toml, package.json, and CLAUDE.md from a single source of truth- Supports
patch,minor,majorkeywords or explicit version numbers
- Supports
- VPN Endpoint Parsing — Strip port and URI scheme from
public_endpointbefore building WireGuard config, preventing malformed endpoints likehttp://example.com:51820:51820
- Release command now uses
bump_version.pyinstead of manual multi-file edits
- Push Notification Wiring — Event emitters now called by RAID, scheduler, and monitoring services
- RAID: degraded/rebuilt notifications for both dev and production backends
- Scheduler: failure notifications for periodic APScheduler job callbacks
- Monitoring: CPU temperature alerts (≥80°C warning, ≥90°C critical) and disk space alerts (≤15% low, ≤5% critical)
- New
emit_disk_space_critical_syncconvenience function
- Login UX — Password visibility toggle on login screen
- Uptime Monitoring — Sleep state tracking in uptime visualization
- Added
backend/data/to gitignore
- VPN Mode Clarity — Clearly distinguish Router-VPN (FritzBox) from NAS-VPN (WireGuard) in the UI
- Backend:
vpn_fallbackboolean in mobile token response —truewhen auto-mode silently fell back to NAS-VPN - MobileDevicesPage: VPN type buttons relabeled to "Router-VPN (FritzBox)" / "NAS-VPN (WireGuard)", amber WoL warnings when NAS-VPN is selected or is the only available option, fallback notice in QR dialog
- VpnManagement: New NAS-VPN info card with server initialization status, active client count, and permanent WoL warning
- i18n: German and English translations for VPN management section
- Backend:
- Ad Discovery — New Pi-hole feature that identifies unblocked ad-serving domains via heuristic pattern-matching and community blocklist cross-referencing
- Heuristic scorer with substring and regex pattern matching (ReDoS-protected via ThreadPoolExecutor timeout)
- Community matcher: downloads, caches (gzip), and cross-references domains against 5 default community blocklists (OISD, Hagezi, Steven Black, EasyList, AdGuard)
- SSRF protection on all blocklist download URLs (HTTPS-only, private/loopback IP rejection)
- Custom blocklist builder: create lists, add/remove domains, deploy as Pi-hole adlists with per-list token auth
- Analyzer orchestrator combining heuristic + community scoring with configurable weights
- Background task (DnsQueryCollector pattern) for periodic automatic analysis
- 29 API endpoints under
/api/pihole/ad-discovery/with rate limiting and audit logging - Full frontend UI: Ad Discovery tab with suspects table, patterns panel, reference lists panel, custom lists panel
- Dev mode support: hardcoded ad domains for testing without network access, 5-minute background interval
- 6 new database tables with Alembic migration and default seed data (27 patterns, 5 reference lists)
- Plugin Capability Contracts — Runtime validation of poll data against capability contracts at startup
- Plugin SDK Design Spec — Design documentation for hooks, registry, and CLI
- Ad Discovery bulk-action: use correct
backendproperty on PiholeService (was_backend)
- Sleep schedule stuck state — When
suspend_system()failed, state stayed on TRUE_SUSPEND permanently, blocking schedule re-triggers, manual wake, and auto-wake middleware. Now reverts to SOFT_SLEEP on failure. - Sleep resume path — After successful suspend resume, state transition was rejected by
_exit_soft_sleep()guard. Fixed by setting state to SOFT_SLEEP before calling exit.
- Fritz!Box Wake-on-LAN — TR-064 SOAP integration for remote WoL via Fritz!Box router
- FritzBoxConfig model, migration, API routes with auth and audit logging
- Fritz!Box config UI and API client in frontend
- WolRequest extended with
methodfield for Fritz!Box delegation - Sleep panel button integrates Fritz!Box WoL
- Remote Server WoL — Wake-on-LAN support for remote server profiles
wol_mac_addresscolumn on ServerProfile with schemas and migration- SSH-fail-to-WoL fallback in server start endpoint
- WoL badge and fallback result display in server profile UI
- MAC address field in server profile form
- WoL Improvements — MAC address auto-detection and validation
get_own_mac()via/proc/net/route(Linux) with dev-mode fallback- Detected MAC shown as suggestion in SleepConfigPanel
- Shared MAC address validator with tests
- MAC validation wired into WolRequest and SleepConfigUpdate
- Multi-worker sleep init — Sleep service supports multi-worker initialization
- Refactored file service: extracted virtual directory listings from route to service layer
- Refactored fan control: extracted schedule and profile logic into separate modules
- Models use
TYPE_CHECKINGfor relationship type imports (cleaner circular import handling) - Added
Mappedtype annotations across models (server_profile, vpn_profile, vcl, etc.) - Fixed Pydantic field definitions to use
Field(default=)instead of positional defaults
- VPN profile config validation: pass enum directly instead of
.value - Energy sample parser now supports plugin PowerReading format
- Correct RAID import path and worker return type
- Smart service import path in jobs.py
- Sync schedule calculation handles nullable
time_of_day - SleepConfigUpdate field ordering after validator insertion
- Type annotations and SQLAlchemy usage fixes across power, update, versioning, and schema modules
- pytest-cov pin updated from
<5.0.0to>=7.0.0,<8.0.0
- FastAPI 0.115.6 → 0.135.1 (+ Starlette 1.0.0)
- plugp100 5.1.5 → 5.1.7
- coverage 7.13.4 → 7.13.5
- pytest-cov 7.0.0 → 7.1.0
- Plugin Badge System — purple "Plugin" badge on plugin-contributed pages, nav items, and sections (like AdminBadge but for plugins)
- Plugin Settings UI — dynamic settings form in plugin detail sidebar, rendered from plugin's JSON Schema config
- Tapo Plugin Config —
panel_devicessetting to select which devices appear in dashboard panel, third-party compatibility hint - Power Graph Device Tabs — switch between "Total" (aggregated) and individual device views in System Monitor Power tab
- Aggregated Energy Endpoint —
GET /api/energy/cumulative/totalsums energy data across all power-monitoring devices - Conditional PowerTab — Power tab in System Monitor only visible when a plugin with
power_monitorcapability is active - Dashboard Panel Navigation — clicking the Tapo power panel navigates to System Monitor Power tab
- plugp100 Monkey-Patch — workaround for
InvalidAuthenticationsuper() bug in plugp100 v5.x
- Plugin documentation rewritten for hobby developers (friendlier tone, clearer explanations, EN + DE)
- Smart device auth errors now show "Authentication failed" instead of cryptic "Library error: super() argument 1 must be a type, not str"
- PowerTab field name alignment with SmartDevice state format (
watts/current/energy_today_kwh) - PostgreSQL RETURNING clause compatibility in migration
- Multi-worker plugin registration (lazy-sync across Uvicorn workers, catch duplicate Pluggy registration)
- Capabilities JSON string deserialization from some DB drivers
- plugp100
InvalidAuthenticationauth error handling across poll, turn_on, turn_off, get_power
- Smart Device Plugin Framework — generic IoT device management with capabilities system (Switch, PowerMonitor, Dimmer, ColorLight, etc.)
- Tapo Smart Plug Plugin — TP-Link Tapo integration rebuilt as plugin with Switch + PowerMonitor capabilities
- Dashboard Plugin Panels — plugins can provide dashboard widgets with gauge/stat/status/chart renderers via WebSocket + REST
- Plugin i18n — translation support for plugin UI (en/de)
- SHM-to-WebSocket bridge — shared memory based real-time device state updates
- Smart Device test suite — 159 tests for the new plugin framework
- Tapo → SmartDevice migration — all Tapo-specific models, schemas, routes replaced by generic SmartDevice API (
/api/smart-devices/) - Energy service — migrated from PowerSample/TapoDevice to SmartDeviceSample with JSON data storage
- Frontend PowerTab/EnergyMonitor — rewritten to use SmartDevice API
- Alembic migrations — data migration from legacy tables + drop of
tapo_devices/power_samplestables
- Broken import paths after service refactoring into subpackages
- Type safety issues found by pyright across backend
- Notification service null safety checks
- File service type annotations, closure capture, SQLAlchemy expressions
- Monitoring collector import and type signature issues
- Frontend icon lookup and chart gradient uniqueness
- Mock session factory and dashboard panel translations in tests
- Plugin system README and architecture docs
- Smart device plugin research and design specs
- Dashboard Plugin Panel System design spec
- Mobile QR dialog — auto-close on successful device registration
- Import paths — correct all broken module references after service reorganization into subpackages (power/, hardware/, sync/, versioning/, scheduler/)
- Runtime crashes — fix wrong attribute access in RAID status and audit log routes
- Sync schedule management — fix weekday mapping, add edit/delete support, resolve device name display
- Type safety — add null checks, input validation, SQLAlchemy
Mapped[]annotations, and proper type casts across 46 backend files - Token validation — reject tokens missing
subclaim in JWT and WebSocket auth - Sleep/service endpoints — make request bodies optional to prevent 422 errors on empty requests
- Relative time formatter — display future dates correctly in device list
- Deprecated patterns and name collisions removed
- Security audit report (2026-03-16)
- Static analysis report (ruff + mypy)
- Plugin permission enforcement — runtime middleware validates plugin permissions before execution
- Security: inactive user rejection — JWT authentication now rejects users with inactive accounts
- Security: metrics endpoint auth — Prometheus
/metricsendpoint requires admin authentication - Security: token lifecycle — enforce 15min access token TTL, type-safe refresh tokens, revoke on logout
- SMART device type override cached to reduce noisy retries
- Frontend notification socket consolidated into single effect to prevent duplicate connections
- Version now read from installed package metadata at runtime
- TTL cache added for aggregated storage info, telemetry poll interval reduced
- Obsolete plan files and PGP key
- Monitoring uptime bars showing no data for short time ranges
- Update service using actual version in changelog instead of literal "latest"
- Test coverage for pure-logic and DB-CRUD services (Batch 1)
- Test coverage for async services and dev-mode stubs (Batch 2)
- Test coverage for plugin manager and cloud scheduler (Batch 3)
- Update service reads version from pyproject.toml instead of installed package metadata
- Readable permissions on update status files for deploy script
- Storage tab capacity values and SSD cache filtering corrected
- v1.16.0 changelog corrected to only include changes since v1.15.6
- Per-device storage API —
GET /api/system/storage/devicesendpoint for individual disk breakdown - Storage tab redesign — Multi-segment donut chart with clickable panels per device
- Uptime tab redesign — Status-page-style visualization with improved layout
- Client unit tests — Tests for API modules, hooks, and lib utilities (Vitest)
- Backend refactoring — Extracted FritzBox VPN, VCL admin/tracking, RAID routes, optical drive, sleep/fan backends into dedicated modules
- Client refactoring — Extracted UpdatePage tabs, TwoFactorCard, StorageTab, mobile/admin-db/files APIs into standalone modules
- ESLint errors in PluginPage, UploadProgressBar, and catch blocks
- Pre-existing TypeScript errors and test mock data alignment
- SSD cache filter to only show arrays with actual cache devices
- Distinct colors for storage donut chart segments
- Live fallback for uptime history endpoint
- Audit report updated with resolution status review (64→78/100)
- Project stats and outdated documentation refreshed
- Dynamic GitHub release badge in README
- Uptime tracking — New UptimeSample model with server + system uptime, historical DB persistence, 30-day retention
- Uptime API endpoints —
GET /api/monitoring/uptime/currentand/historywith live fallback computation - Uptime tab — System Monitor > System > Uptime with live counters, restart detection, and area chart
- Dashboard dual uptime — Server uptime as main value, system uptime as subtitle, clickable to uptime tab
- BaluPi setup — Admin route, setup component, and API client for Pi device management
- Pi mode guards — Disable notifications and plugins in Pi mode to avoid unnecessary requests
- SystemInfo schema — Added
system_uptimefield to/api/system/inforesponse
Großflächiges Refactoring: DB-Calls aus Routes in Service-Layer extrahiert, SQLAlchemy 2.0 Mapped-Style Migration und Frontend Error-Handling vereinheitlicht.
- Routes → Services — DB-Calls aus 10+ Route-Modulen (user, device, mobile, samba, monitoring, sync, shares, cache, pihole, firebase) in Service-Layer extrahiert
- SQLAlchemy models — Mobile und rate_limit_config auf SQLAlchemy 2.0 Mapped-Style migriert
- Frontend error handling — Shared
getApiErrorMessagein 18 Components eingesetzt - Logging — print-Statements durch Logger ersetzt, Validator dedupliziert, Cache gebunden
- Import paths — Import-Pfade und kleinere Issues über mehrere Services korrigiert
- Notifications — FCM High Priority und Sound für zuverlässige Push-Delivery
- Update version label — Version-Label auf stable vs dev build vereinfacht
- Sync heartbeat — DB-Writes in Thread-Pool ausgelagert
- Firebase push delivery — 30 neue Tests für Push-Notification-Delivery
Redesign der Settings-Seite, dynamische API-Dokumentation und Entfernung des nie genutzten Email-Notification-Features.
- Settings storage tab — Neuer Storage-Tab mit System Storage Ring, VCL Quota und SSD Cache Sektionen
- API Center docs — Endpoint-Dokumentation wird dynamisch aus dem OpenAPI-Schema generiert
- FCM push notifications — Event-driven und Admin-Notifications via Firebase Cloud Messaging
- Power sample retention — Power Samples werden jetzt vom Retention Management erfasst
- Settings profile tab — Vereinfacht, Avatar-Upload und Email-Sektion entfernt
- Audit logger paths — Import-Pfade nach Modul-Restrukturierung korrigiert
- API Center rate limits — Rate Limits Management mit dynamischem Endpoint-Matching wiederhergestellt
- Email notifications — Komplettes SMTP-Email-Feature entfernt (war nie in Produktion aktiv)
Fix für hängendes Update-Progress und neuer Cancel-Mechanismus für laufende Updates.
- Update cancel — Laufende Updates können jetzt über die UI abgebrochen werden (dev: asyncio cancel, prod: systemd stop)
- Update progress i18n — Fehlende Übersetzungen für die Update-Progress-Anzeige (DE+EN)
- Unified test runner — Neues Test-Runner-Script für kombinierte Backend/Frontend-Tests
- Update progress stuck at 5% — Dev-Mode-Updates crashten durch geschlossene DB-Session in _notify_progress()
- Prod update staleness — Status-File wird jetzt in die DB synchronisiert, gestoppte systemd-Units werden erkannt
- Update cancel timezone — UpdateHistory.cancel() nutzt jetzt konsistent UTC statt lokale Zeitzone
- CI workflows — Redundante Workflows entfernt
Admin-UI für Firebase-Credential-Verwaltung, Test-Notifications aus dem Admin-Panel, verbesserte Notification-Zuverlässigkeit und Backend-Refactoring.
- Firebase config UI — Neuer Firebase-Tab unter System Control > Network zum Hochladen, Anzeigen und Löschen von Firebase-Credentials mit Hot-Reload
- Firebase test notifications — Test-Benachrichtigungen aus der Admin-UI senden, inkl. manuellem FCM Token
- Development branch updates — Update-Support für den Development-Branch
- Backend modularisierung — Lifespan und Service Registry in eigene Module extrahiert
- Pillow dependency — Upper-Version-Constraint entfernt
- FCM push delivery — Push-Benachrichtigungen an mobile Geräte korrigiert
- Test notifications — Verbesserte Behandlung für Geräte ohne Push-Token
- Update service — repo_path Traversal in ProdUpdateBackend korrigiert
- Notification retry — Retry-Logik und Scheduler Grace Period erweitert
- Device removal push — Push-Benachrichtigung bei Geräte-Entfernung + Import-Pfad Fix
- Idle detection — Mobile Browser Timer-Freeze im Background behandelt
Neues File-Activity-Tracking-System mit Recent-Files-API, Auto-VPN-Option für Sync-Schedules und verbesserte VPN-Konfigurationsgenerierung mit konfigurierbarem DDNS-Endpoint.
- File activity tracking — Neues System zur Erfassung von Dateiaktivitäten mit Recent Files API
- Sync auto-VPN —
auto_vpnFeld für Sync-Schedules mit UI-Toggle zum Aktivieren/Deaktivieren - Dev build flag —
is_dev_buildFlag in Version-Info für bessere Build-Erkennung
- VPN config generation — Konfigurierbarer DDNS-Endpoint und Server Public Key in generierten Configs
- VPN server key — Server Public Key wird von laufendem wg0 Interface gelesen statt neu generiert
- Files routes — Pylance Static-Analysis-Warnungen in Files-Routes behoben
- Worker imports — sys.path korrigiert für App-Module-Imports in Workern
- CI — Development-Branch wird nach PR-Merge zu main synchronisiert
- Sync tests — Sync-Scheduler-Service und Route-Tests hinzugefügt
Notification-Einstellungen in die Settings-Seite integriert, verbesserte Rate-Limiter-Konfiguration und mehrere Bugfixes für Notifications und Pi-hole.
- Notification Settings tab — Benachrichtigungseinstellungen als neuen Tab in die Settings-Seite verschoben
- Rate-Limiter — File/Sync-Limits erhöht und neue
mobile_sync-Kategorie hinzugefügt - Notifications — Naive datetime in
time_ago-Berechnung korrekt behandelt - Notifications — System-Benachrichtigungen (user_id=NULL) für Admin-Benutzer eingeschlossen
- Pi-hole — 127.0.0.1 statt localhost verwenden um ConnectError nach Deploy zu vermeiden
- i18n — Fehlende Notification-Center-Übersetzungsschlüssel ergänzt
- Frontend — Unbenutzte eta-Variable im Layout.tsx Restart-Handler entfernt
Neues Backend-Log-Monitoring mit Echtzeit-Streaming, überarbeitetes Power-Menü in der Header-Leiste und umfassende API-Dokumentation im API Center.
- Backend Logs monitoring — Neuer Backend Logs Tab im System Monitor mit REST + SSE Endpoints und Log-Buffer-Service mit Subscriber-Support
- PowerMenu dropdown — Header-Buttons für Shutdown/Logout durch kompaktes Dropdown-Menü ersetzt
- Restart API endpoint — Neuer System-Restart-Endpoint
- API Center documentation — ~115 fehlende API-Endpoints dokumentiert
Kritischer Bugfix für das Energy Dashboard auf PostgreSQL (Production), plus neue Features für Versionsverfolgung und Mobile Sync.
- Version history tracking — Erfasst jede gestartete Version+Commit in der DB mit Startzähler
- Version history UI — Neue Sektion im Verlauf-Tab zeigt alle jemals gelaufenen Versionen
- Delete sync folder endpoint — Mobile Sync-Ordner können jetzt gelöscht werden
- Dev commit messages — Dev-Version-Sektion zeigt Commit-Messages und Dev Build Badge
- Energy dashboard 500 on PostgreSQL —
get_hourly_samples()nutzte SQLite-spezifischesfunc.strftime(), jetzt cross-database kompatibel mitdate_trunc()für PostgreSQL - Dashboard error handling —
get_current_power()ValueError wird jetzt im Dashboard-Handler abgefangen - CI auto-tag — Globale Git-Config für auto-tag im geklonten Repo
Upload-Queue für Mobile-Geräte und Verbesserungen an der Update-Seite (Dev-Branch-Indikator, Versions-Tab jetzt auch in Production sichtbar). Speicher-Anzeige nutzt jetzt verfügbaren statt freien Speicher.
- Upload queue endpoint — Neuer API-Endpoint und Schemas für Mobile-Upload-Queue
- Dev branch indicator — Update-Seite zeigt aktiven Branch im Dev-Modus
- Versions tab in production — Versions-Tab jetzt auch in Production sichtbar
- Memory info — Verfügbarer Speicher statt freiem Speicher für akkurate Anzeige
- Version sync — Korrekte Version in
__init__.pyundpackage-lock.json - CI auto-tag — Git-Identität für auto-tag im Merge-Workflow
- pytest-cov — Coverage-Reporting zu Test-Dependencies hinzugefügt
Admin-UI zum Bearbeiten von .env-Konfigurationsdateien direkt aus der Web-Oberfläche. VPN-Typ-Auswahl (Full Tunnel / Split Tunnel) bei der Mobilgeräte-Registrierung und mehrere VPN-Bugfixes.
- System Variables page — Admin-UI für .env-Bearbeitung mit Kategorie-Gruppierung und Sensitive-Value-Masking
- VPN type selection — Full/Split Tunnel Auswahl bei Mobile-Registrierung
- VPN config type endpoints — Backend-Unterstützung für vpn_type Parameter
- VPN FORWARD rule — Fehlende iptables FORWARD-Regel für VPN-Return-Traffic
- VPN encryption — Sichere Encryption-Wrapper und Endpoint-URL-Bereinigung
- QR code loading — Verbesserte Resilienz beim Laden von VPN-QR-Codes
- VPN Server Troubleshooting Guide
Worker Health Status im Scheduler Dashboard zeigt jetzt den Zustand aller Worker-Prozesse an. Stale Executions werden korrekt als CANCELLED markiert, und ein neuer Mobile Power Summary Endpoint erweitert die Mobile-API.
- Worker health status — Scheduler Dashboard zeigt Worker-Prozess-Status
- Mobile power summary — Neuer API-Endpoint für mobile Energieübersicht
- Stale execution recovery — CANCELLED statt FAILED für abgebrochene Executions
- WebSocket StrictMode — Verzögerter Connect verhindert ECONNRESET
- Frontend API URLs — Korrekte URLs in allen API-Clients
- Scheduler heartbeat — Timezone-naive Heartbeat-Behandlung
- CI release workflow — Liest Version aus pyproject.toml statt PR-Titel
Umfangreiche Bugfixes für den Windows Dev-Mode: QR-Codes werden jetzt korrekt als SVG gerendert, WebSocket-Notifications funktionieren über den Vite-Proxy, und die Monitoring-Architektur nutzt einheitlich den monitoring_worker-Prozess.
- API versioning headers — Infrastructure for API version negotiation
- Token display in QR dialog — Reveal/copy registration token manually
- DEV_FAST mode —
DEV_FAST=1disables hot-reload and uses 2 workers
- Unified monitoring architecture — Dev and prod both use monitoring_worker process via SHM IPC
- Windows SHM support — Shared-memory IPC falls back to
%TEMP%/baluhost-shmon Windows - Dynamic dev update versioning — Mock versions derived from installed package version
- Dev sampling intervals — Reduced frequencies for better dev performance
- Reorganized service imports — Updated to match new service package structure
- QR code SVG fallback — Manual SVG generation when Pillow is unavailable
- QR code MIME type — Auto-detect PNG vs SVG from base64 prefix
- WebSocket URL — Use Vite proxy instead of hardcoded
127.0.0.1:3001 - Scheduler timezone — Handle naive
started_attimestamps in duration calculation - psutil sensors — Handle missing temperature sensors on Windows
- DNS query collector — Cross-database compatibility fix
- DateTime arithmetic — SQLite compatibility for timezone-aware datetimes
- bcrypt bumped to 4.x
- cryptography upper bound widened to <47.0.0
- WireGuard server config generation —
generate_server_config()buildswg0.conffrom DB state (server keys + active client peers) - Live config sync —
apply_server_config()writes config and runswg syncconffor seamless reload without disconnecting clients - Auto-sync on client changes — Server config automatically updates when clients are created, revoked, or deleted
- LAN routing via VPN — Client AllowedIPs now include LAN subnet (
192.168.178.0/24) for webapp access over VPN POST /api/vpn/sync-server— Admin-only endpoint to manually trigger server config regeneration- WireGuard setup script (
deploy/scripts/setup-wireguard.sh) — One-time server setup:/etc/wireguard/, IP forwarding, sudoers, systemd service, optional Pi-hole DNS - Sudoers template (
deploy/install/templates/baluhost-wireguard-sudoers) — Scoped sudo rules for WireGuard management - VPN config settings —
vpn_lan_network,vpn_lan_interface,vpn_include_lan,vpn_config_path
- Deploy scripts — Fixed
PGPASSWORDextraction and.env.productionsourcing for Alembic migrations - CI workflow — Added
workflow_dispatchtrigger, fixedDEPLOY_PATfor auto-merge
Native Systemd-Deployment mit CI/CD-Pipeline: automatisierter Deploy bei Push auf main, Datenbank-Backups vor jedem Deploy, atomisches Rollback, und Nginx für statisches Frontend.
- CI/CD pipeline — GitHub Actions CI Check workflow (backend tests + frontend build)
- Auto-deploy — Production deploy workflow triggered on push to main via self-hosted runner
- Auto-merge — PRs to main automatically merge when CI checks pass
- Deploy script (
ci-deploy.sh) — Atomic deploys with pre-deploy DB backup, Alembic migration, health checks, and automatic rollback - DB backup/restore scripts —
db-backup-daily.sh(14-day retention cron) anddb-restore.shfor manual recovery - Migration script (
migrate-to-opt.sh) — One-time migration from/home/sven/projects/BaluHostto/opt/baluhost - Systemd monitoring template — Templated
baluhost-monitoring.servicewith placeholder system - Deploy sudoers template — Passwordless systemctl for deploy user
- Self-hosted runner — Setup docs and health check script (
deploy/runner/) - Emergency runbook — Step-by-step rollback and DB restore procedures
- Infrastructure docs — Production architecture overview
- Backend service template — Updated to 4 workers, added primary lock cleanup and PostgreSQL dependency
- Systemd module — Extended to include monitoring service
- Nginx config — Verified SPA fallback and API proxy for static frontend serving
- CI test compatibility — Patched SessionLocal at all import sites for CI environment
- 62 CI test failures — Resolved missing .env, SQLite advisory lock compat, SessionLocal bypass
- Move endpoint — Corrected variable name and SQLite advisory lock compatibility
- qrcode dependency — Moved from dev to core dependencies
- Deploy scripts — Fixed npm build and manual uvicorn handling
- Hardware commands — Added sudo for mdadm, smartctl, fan PWM in deploy scripts
Comprehensive security hardening from audit remediation (20 fixes), new Pi-hole features (analytics dashboard, stored query log, DNS query collector), and mobile responsiveness improvements across the Pi-hole UI.
- Pi-hole analytics dashboard — DNS query statistics with period selector, summary cards, and timeline charts
- DNS query collector — Background service collecting Pi-hole queries into local database for historical analysis
- Stored DNS query API — Endpoints for searching and filtering collected DNS queries
- DNS query database models — New tables and Alembic migration for query storage
- Registration restriction — Configurable
registration_enabledsetting to disable public user registration - Nginx Pi-hole proxy — Reverse proxy config for Pi-hole web UI at baluhole.local
- Auto .local DNS registration — Automatically register local DNS records in Pi-hole on startup
- CI workflows — Added pytest and Vitest to GitHub Actions CI pipeline
- VPN key encryption — Server and preshared keys now encrypted at rest with Fernet (AES-128-CBC)
- WebSocket auth — Uses scoped short-lived tokens instead of long-lived access tokens
- CSP headers — Strict
script-src 'self'in production, relaxed only in dev mode - CORS policy — Restricted methods and headers to required set instead of wildcards
- TOTP encryption — Dedicated
TOTP_ENCRYPTION_KEYseparate from VPN key - Brute-force tracking — Bounded with TTLCache instead of unbounded dict
- Monitoring buffer — Replaced
list.pop(0)withdeque(maxlen)for O(1) performance - Notification queries — Optimized with COUNT and GROUP BY instead of fetching all rows
- Directory listing — Fixed N+1 query pattern with bulk metadata fetches
- README — Complete rewrite reflecting current project state
- Pi-hole mobile responsiveness — Scrollable tabs, wrapping forms, responsive grids across 9 components
- Change password validation — Now uses Pydantic schema with password strength enforcement
- Refresh token validation — Added Pydantic schema for token request body
- Admin password in production — Rejects default password on startup
- Timing-safe auth — Dummy hash comparison on failed user lookup prevents timing attacks
datetime.utcnow()deprecation — Replaced withdatetime.now(timezone.utc)across codebase- CI test failures — Resolved 68 test failures across 11 test files
list_filesblocking — Converted to sync def to prevent event loop blockingdebug=Falsedefault — Only enabled in dev mode, preventing debug leaks in production
- Obsolete artifacts — Removed generated HTML reports, backup files, and stale data from git tracking
Stable release laying the groundwork for BaluPi companion device support (handshake protocol, snapshot export, Pi frontend build pipeline), adding Pi-hole DNS integration for VPN, and several backend/frontend improvements.
- BaluPi handshake groundwork — HMAC-SHA256 signed notification service and snapshot export for future Pi integration
- Pi build pipeline — Separate frontend build target for Raspberry Pi with tree-shaken desktop-only pages
- PiDashboard page — View-only dashboard skeleton for Pi (NAS status, energy, storage, Pi health)
- Pi-hole DNS integration — Backend service + frontend page for managing Pi-hole from BaluHost
- VPN DNS via Pi-hole — Use Pi-hole as DNS server for VPN clients when active
- VCL tracking mode — Automatic/manual mode with per-file tracking rules
- VCL ownership reconciliation — Admin tool to scan and fix version ownership mismatches
- Dedicated monitoring worker — Offloads CPU/RAM/network sampling to separate process in production
- GitHub Actions workflow — Auto-deploy Pi frontend to BaluPi on release
- Chunked upload — Increased chunk size to 32MB and concurrent writes to 16
- Vendor chunk splitting — Better browser caching via separate vendor bundles
- Update channel — Renamed "beta" to "unstable" for clarity
- UpdatePage — Show actual version stability instead of update channel name
- Plugin loading — Add token dependency to prevent stale closure
- Monitoring API — SHM fallback to serve fresh data in multi-worker production
- Scheduler timeline — Improved mobile responsiveness
- Fan control — Use round() instead of int() for PWM-percent conversion
- Prerelease tags — Mark unstable and rc tags as prerelease in GitHub Actions
- E2E tests — Fix StrictMode auth race condition causing navigation redirect; fix mock data schemas and missing mock routes
- Release workflow — Handle existing releases on tag force-push instead of failing with 422
- Split UserManagement.tsx into hook + 5 sub-components
- Split SyncSettings.tsx into hook + 5 sub-components
- Split DeviceManagement.tsx into hook + 6 sub-components
- Split scheduler_service.py into scheduler/ sub-package with 3 modules
- Split benchmark_service.py into benchmark/ sub-package with 7 modules
- Split smart.py into smart/ sub-package with 7 modules
Prerelease with VCL per-file tracking mode, a dedicated monitoring worker process for production, and several major frontend/backend refactors.
- VCL tracking mode — Automatic/manual mode with per-file tracking rules; users control which files are versioned
- VCL ownership reconciliation — Admin tool to scan and fix version ownership mismatches after file transfers
- VCL tracking panel — New Settings → VCL tab for managing tracking rules and exclusions
- File-level VCL toggle — Shield icon in FileManager to enable/disable versioning per file
- Monitoring worker process — Dedicated process for telemetry, disk I/O, power monitor, and orchestrator in production (SHM-based IPC)
- Shared
formatRelativeTime— Reusable relative time formatter inlib/formatters.ts - Vendor chunk splitting — Manual Rollup chunks for react, recharts, i18n, and lucide-react
- SchedulerTimeline mobile — Responsive bar widths, conditional hour labels, tighter spacing on small screens
- PWM percent conversion — Use
round()instead ofint()to prevent truncation loss
- Refactored DeviceManagement — Split 997-line monolith into hook + 6 sub-components (133 LOC page)
- Refactored scheduler service — Split
scheduler_service.pyintoscheduler/sub-package with 3 modules - Refactored benchmark service — Split
benchmark_service.pyintobenchmark/sub-package with 7 modules - Refactored SMART service — Split
smart.pyintosmart/sub-package with 7 modules - Renamed update channel — "beta" → "unstable" for clarity
- Production monitoring — Web workers read from SHM with DB fallback instead of running monitoring in-process
- i18n for Tapo smart devices — DE/EN translations for all Tapo device settings strings
- Apple/iOS SMB compatibility — SMB settings for Apple device compatibility
- Production process manager — start_prod.py no longer kills backend when non-critical worker crashes
- Fan control temperature sensor — Read CPU temp sensor instead of board sensor (~26°C)
- Refactored power manager — Split power/manager.py into 5 sibling modules
- Refactored update service — Split update_service.py into update/ sub-package with 7 modules
- Refactored RAID service — Split raid.py into raid/ sub-package with 7 modules
- Refactored file operations — Split files/operations.py into path_utils, access, and storage modules
Feature-rich release adding a notification event system, VCL blob storage, improved file sharing, and extensive multi-worker production fixes.
- Notification event system — Backend event emitters with cooldowns, snooze, and sync notifications across services
- Notification UI — Grouping, snooze controls, and archive page
- VCL blob migration — Migration service with admin UI for VCL storage
- Configurable VCL storage path — Dedicated storage path with info endpoint
- File sharing permissions — Granular per-user permissions and user list endpoint for shares
- Storage breakdown — Cache/VCL-aware storage usage visualization
- ByteSizeInput component — Unit-aware byte size editing in forms
- Binary/decimal byte units — User setting to toggle between binary (GiB) and decimal (GB) display
- Persistent fan curve profiles — DB-backed fan curve presets
- Releases list — Show available releases on the update page
- Ownership transfer — Cascade VCL versions and quota on file ownership transfer
- Disk I/O on secondary workers — Add DB fallback for
/disk-io/currentand deriveavailable_disksfrom DB data when memory is empty - RAID member disks in monitoring — Filter RAID member disks from disk I/O monitoring
- Multi-worker deployment — Stabilize with sticky sessions and DB fallbacks for all monitoring endpoints
- Fan control on secondary workers — Initialize read-only, detect write permission at startup
- Fan disappearance — Prevent fan data loss on transient hwmon scan failures
- Server uptime — Initialize start time at module import for consistent multi-worker uptime
- Disk I/O detection — Improve initial detection and polling speed
- CPU/memory endpoints — Add DB fallback on secondary workers
- Settings page — Fix slow load and broken quota display
- Cache system — Replace bcache SSD cache with file-level cache system
- Public share links — Removed public share link UI and backend in favor of granular user-based sharing
Major release adding robust multi-worker support, security fixes, and frontend architecture improvements.
- Primary worker guard — File-lock-based primary election for multi-Uvicorn-worker deployments; background services only run on the primary worker
- Service heartbeat system — Primary worker writes service status to DB every 15s; secondary workers read from DB for accurate dashboard data
- DB fallback for Network & Power widgets — Secondary workers fall back to database when in-memory buffers are empty (fixes intermittent "Offline" on dashboard)
- Folder sizes in file manager — Display cumulative folder sizes in the file listing
- Desktop sync folder tracking — Track and display sync badges on synced folders
- Modular installation system — Script-based installer with security fixes
- Detached update runner — Updates run via
systemd-runto survive service restarts - NotificationContext — WebSocket connection lives above route level, survives navigation
- Global 401 interceptor — Axios + raw fetch handlers trigger centralized auth expiration
- Privilege escalation via /register — Hardcode
role="user"in registration; removerolefield fromRegisterRequestschema - User list access control — Restrict
GET /api/users/to admin-only (was any authenticated user) - Sort field enumeration — Whitelist sortable fields in user list endpoint
- HSTS over HTTP — Only send
Strict-Transport-Securityheader when request arrived over HTTPS - Primary lock race condition — Open lock file in append mode without unlinking (prevents dual-lock on separate inodes)
- Stale lock file — Clean up via
ExecStartPre/start_prod.pyinstead of in-process unlink - Blob URL memory leak — FileViewer uses ref for proper cleanup on unmount
- useAsyncData loading state — Set
loading=trueon reload - Mixed timezone datetimes — Handle tz-aware/naive datetime comparison in device sorting
- Real disk space checks — Use actual disk space in production instead of quota-only
- Streaming uploads — Write chunks directly to disk (non-blocking I/O via
asyncio.to_thread) - Upload rate limits — Increased to 50,000/min (effectively unlimited)
- Non-blocking upload metadata — Nginx upload tuning for large files
- Stampede protection —
calculate_used_bytes()prevents concurrent filesystem scans - Search debounce — 300ms debounce on UserManagement search input
- AuthContext — AbortController for
/mefetch, cleanup on unmount - useNotificationSocket — Stabilized with refs, token from AuthContext (not localStorage)
- alert() → toast — Replaced browser alerts with
react-hot-toastin Settings, MobileDevices pages
- useMemoizedApi hook — Deleted unused hook
- RegisterRequest.role field — Removed to prevent client-side role assignment
Adds 6-digit code-based pairing for BaluDesk desktop clients.
- Desktop Pairing Backend — DB model, service, API routes (
/api/desktop-pairing/*), rate limits, and Alembic migration for code-based desktop client authentication - Desktop Pairing Dialog — Frontend component with 6-digit code input, device confirmation/deny flow, and auto-open via
?pair=1URL parameter - i18n — Pairing translations for EN and DE
- Pairing Dialog integration — Moved button and dialog from unused
SyncPrototype.tsxtoDeviceManagement.tsxwhere/devicesroute actually renders
- Root directory cleanup — Deleted obsolete scripts, moved utilities to
tools/
Patch release with test infrastructure fixes and CI pipeline simplification.
- Raid API tests — Mock
apiClient(axios) instead ofglobalThis.fetch, fixingAxiosError: Network Error - ErrorBoundary test — Correct
ThrowingComponentreturn type tonever - Test setup — Use
globalThis.ResizeObserverinstead of deprecatedglobal - Test TypeScript config — Add dedicated
tsconfig.test.jsonfor test files
- Playwright CI — Mocked E2E tests no longer require backend; Playwright
webServerconfig handles dev server automatically - Playwright CI — Bump Node.js from 18 to 20 to fix Vite
crypto.hasherror - Live E2E CI — Moved secret check earlier, removed redundant frontend server, simplified service wait logic
Feature release adding API key management for programmatic access and comprehensive mobile responsiveness fixes.
- API Key Management — Generate and manage API keys for programmatic access
- Create, revoke, and list API keys from Settings page
- Scoped permissions and expiration support
- Admin-only feature in Settings tab
- Mobile sidebar scrolling — Admin users can now scroll all 14 nav items on small screens
- Mobile responsiveness — Improved layouts across multiple pages:
- AdminDataTable: CSS breakpoints replace JS-based mobile detection
- AdminDatabase: Stacked toolbar layout with proper touch targets
- AdminHealth: Disk info grid adapts to screen size
- ApiCenterPage: Endpoint headers stack on mobile
- FileManager: Path breadcrumb always visible with tooltip
- MobileDevicesPage: Notification status wraps properly
- PowerManagement: Grid breakpoints adjusted for small screens
- SettingsPage: Tab bar with scroll fade indicator
- CI: Automatic GitHub Release creation on tag push
Major feature release adding intelligent sleep management, file ownership transfer, and universal two-factor authentication.
- Sleep Mode — Full soft-sleep and true-suspend (S3) support
- Auto-idle detection with configurable CPU, disk I/O, and HTTP thresholds
- Scheduled sleep/wake windows with rtcwake integration
- Wake-on-LAN configuration per interface
- Disk spindown via hdparm for data disks during sleep
- Auto-escalation from soft sleep to true suspend
- Auto-wake middleware: incoming HTTP requests wake the system from soft sleep
- Service registration for admin dashboard monitoring
- Collapsible setup help for missing capabilities (hdparm, rtcwake, WoL, suspend)
- Sleep history table with state transitions
- File Ownership Transfer — Transfer file/folder ownership between users
- Backend service with residency enforcement migration
- API endpoints with admin and owner authorization
- Frontend modal with user selector and residency panel
- 2FA for all users — Two-factor authentication no longer limited to admins
- E2E test suite — Comprehensive Playwright end-to-end tests
- Performance:
calculate_used_bytes()cached with 30s TTL
- Frontend
goBacknavigation simplified to avoid edge cases
- Repaired and expanded existing backend test suite
- Production Readiness: Stable
- Version: 1.7.0
This release focuses on improved documentation organization and significant client-side refactoring.
- Structured documentation directory with logical subdirectories:
docs/api/- API documentationdocs/deployment/- Deployment, SSL, reverse proxy, production guidesdocs/features/- Feature documentationdocs/getting-started/- User guide and dev checklistdocs/monitoring/- Monitoring and telemetrydocs/network/- VPN, WebDAV, mDNS setupdocs/security/- Security, audit logging, rate limitingdocs/storage/- RAID and backup documentation
- Updated navigation in docs/README.md with table-based quick links
- Time-based fan schedules (scheduled mode) for fan control
- Collapsible LiveActivities section on dashboard below panels
- Decomposed FileManager and RaidManagement into smaller, focused components
- Consolidated API layer from raw fetch calls to unified
apiClient - Added barrel exports for all component directories
- Activated AuthContext with proper error handling
- Stabilized idle-timeout hook to prevent unnecessary re-renders
- SharesPage and modals aligned with SystemMonitor design language
- PluginsPage aligned with SystemMonitor design language
- UpdatePage aligned with SystemMonitor design language
- Admin Database page redesigned with sidebar and browse/analytics split
- Improved analytics tabs with skeletons and shared UI components
- Simplified 2FA step in login page
- RAID 1 disk capacity display corrected on dashboard
- Auth idle-timeout re-render issues resolved
- Production Readiness: ✅ Stable
- Version: 1.6.1
This release introduces a comprehensive scheduler management system for all background jobs.
- Unified Scheduler Dashboard with 5 tabs for complete scheduler management
- Timeline view for visual execution history across all schedulers
- Retry mechanism for failed executions with one-click re-run
- Execution history tracking with status, duration, and error details
- Real-time status monitoring for all 6 system schedulers
- RAID Scrub - Data integrity checks (configurable interval, default: weekly)
- SMART Scan - Disk health monitoring (default: hourly)
- Auto Backup - Automated system backups (default: daily)
- Sync Check - Sync schedule trigger checks (every 5 minutes)
- Notification Check - Device expiration warnings (hourly)
- Upload Cleanup - Chunked upload cleanup (daily at 3 AM)
GET /api/schedulers- List all schedulers with statusGET /api/schedulers/{name}- Get specific scheduler detailsPOST /api/schedulers/{name}/run-now- Trigger immediate executionGET /api/schedulers/{name}/history- Get execution historyGET /api/schedulers/history/all- Get combined execution timelinePOST /api/schedulers/{name}/toggle- Enable/disable scheduler
SchedulerExecution- Tracks individual execution runs with timing, status, and error infoSchedulerConfig- Stores per-scheduler configuration and enabled state
- Integrated RAID scrub and SMART scan schedulers with service status monitoring
- Enhanced SyncSettings UI with device dropdown and day pickers
- Added execution logging to all scheduler services
- Production Readiness: 100% (DEPLOYED)
- Version: 1.4.2
This release marks the production deployment of BaluHost on January 25, 2026.
- Live production deployment on Debian 13 server (Ryzen 5 5600GT, 16GB RAM)
- PostgreSQL 17.7 migration complete and verified
- Nginx reverse proxy with rate limiting (100 req/s API, 10 req/s auth)
- Systemd services for backend (4 Uvicorn workers)
- Auto-start on reboot configured
- Task Manager-style display showing individual thread usage
- CPU thread breakdown in monitoring dashboard
- Historical per-thread data with retention policies
- Stats tab with database statistics and table counts
- Storage tab with storage breakdown visualization
- History tab for query history tracking
- Maintenance tab for database maintenance tools
- Fan curve chart editor with drag-to-edit functionality
- Visual temperature-to-PWM mapping
- Real-time RPM and PWM display
- Mode switching (auto/manual/emergency)
- mDNS/Bonjour integration for local network discovery
- Zero-configuration networking support
- Service announcement for web interface and API
- Device discovery for other BaluHost instances
- Health check dashboard for all services
- Service registry with real-time status
- Admin controls for service restart/stop/start
- Updated documentation to reflect production deployment status
- Unified version numbers across all components to 1.4.0
- Enhanced monitoring orchestrator with per-thread CPU support
- Improved fan control service with better curve interpolation
- Email validation regex pattern in user registration
- Frontend routing issues with nested routes
- Memory leak in disk I/O monitoring long-running sessions
- Updated
TODO.mdwith completed features and production status - Updated
README.mdwith production deployment information - Updated
PRODUCTION_READINESS.mdwith deployment confirmation - Updated
TECHNICAL_DOCUMENTATION.mdwith new features (Power Management, Fan Control, etc.) - Updated
ARCHITECTURE.mdwith production deployment architecture - Documented known issues (integer overflow in monitoring tables)
- Production Readiness: 100% (DEPLOYED)
- Server: Debian 13, Ryzen 5 5600GT, 16GB RAM
- Database: PostgreSQL 17.7
- Version: 1.4.1
This release makes BaluHost fully production-ready with automated backup system, structured logging, and comprehensive deployment documentation.
- Automated backup scheduler using APScheduler for periodic backups
- PostgreSQL pg_dump support for production database backups
- Configurable backup intervals (hourly, daily, weekly, custom)
- Multiple backup types: full, incremental, database_only, files_only
- Retention policies: max count and age-based cleanup
- Manual backup script (
deploy/scripts/backup.sh) for on-demand backups - Backup configuration via environment variables (
BACKUP_AUTO_ENABLED,BACKUP_AUTO_INTERVAL_HOURS,BACKUP_AUTO_TYPE)
- Structured JSON logging using python-json-logger for log aggregation
- Environment-based log format: JSON for production, human-readable for development
- Configurable log levels via
LOG_LEVELenvironment variable (DEBUG, INFO, WARNING, ERROR, CRITICAL) - Log format configuration via
LOG_FORMATenvironment variable (json, text) - Logging initialization in application startup for consistent configuration
- Comprehensive deployment guide (
docs/DEPLOYMENT.md) with:- 5-minute quick start guide
- Detailed Docker Compose deployment steps
- SSL/TLS configuration with Let's Encrypt
- Monitoring setup instructions
- Backup configuration guide
- Troubleshooting section
- Maintenance procedures
- Updated
.env.production.examplewith backup and logging configuration - Production readiness status updated to ~98% complete
backend/app/core/config.py:- Added backup automation settings (
backup_auto_enabled,backup_auto_interval_hours,backup_auto_type) - Added logging configuration settings (
log_level,log_format)
- Added backup automation settings (
backend/app/services/backup.py:- Enhanced with PostgreSQL pg_dump/psql support
- Added
_backup_postgres_database()method for PostgreSQL backups - Added
_restore_postgres_database()method for PostgreSQL restores - Modified
_get_database_info()to detect database type (SQLite/PostgreSQL)
backend/app/main.py:- Integrated backup scheduler startup/shutdown
- Added structured logging initialization on app startup
backend/pyproject.toml:- Added
python-json-logger>=2.0.0,<3.0.0dependency
- Added
PRODUCTION_READINESS.md:- Updated executive summary to ~98% production-ready
- Marked backup automation as ✅ COMPLETED
- Marked error handling & logging as ✅ COMPLETED
- Marked deployment documentation as ✅ COMPLETED
- Updated production checklist
- Changed status to "READY FOR PRODUCTION DEPLOYMENT"
- Added:
python-json-logger(^2.0.0) for structured JSON logging
# Logging
LOG_LEVEL=INFO # DEBUG|INFO|WARNING|ERROR|CRITICAL
LOG_FORMAT=json # json|text
# Backup Automation
BACKUP_AUTO_ENABLED=true # Enable automated backups
BACKUP_AUTO_INTERVAL_HOURS=24 # Backup interval (hours)
BACKUP_AUTO_TYPE=full # full|incremental|database_only|files_only# Full backup (default)
./deploy/scripts/backup.sh
# Database-only backup
./deploy/scripts/backup.sh --type database_only
# Files-only backup
./deploy/scripts/backup.sh --type files_only
# Without Docker
./deploy/scripts/backup.sh --no-docker- No security changes in this release
- Existing security hardening from v1.3.0 remains active (8/8 critical vulnerabilities fixed)
- Production Readiness: ~98% (up from ~95%)
- Critical Blockers: None
- Optional Enhancements: Print statement cleanup, load testing, PWA
This release focuses on operational excellence and production deployment readiness. BaluHost is now suitable for production deployment with:
- Automated backup system
- Production-grade logging
- Comprehensive deployment documentation
- Full PostgreSQL support
Major features implemented: Monitoring, Security Hardening, Testing Infrastructure.
- Prometheus metrics endpoint (
/api/metrics) with 40+ custom metrics - Grafana dashboards: System Overview, RAID Health
- 20+ alert rules across 6 groups (Critical, Warning, Info severity)
- Docker Compose monitoring profile for easy deployment
- System metrics: CPU, memory, disk, network monitoring
- RAID metrics: array status, disk count, sync progress
- SMART metrics: disk health, temperature, power-on hours
- Application metrics: HTTP requests, file operations, database connections
- Refresh token revocation with JTI tracking
- Password policy enforcement (8+ chars, uppercase, lowercase, number)
- Consolidated auth system (single secret key)
- Security headers middleware activated
- Rate limiting on all critical endpoints (login, register, password change)
- Secret key validation in production mode
- Deprecated code removal (datetime.utcnow)
- 40 test files with 364 test functions
- Security tests (critical vulnerabilities, headers, JWT, input validation)
- Integration tests (files API, sync, mobile, remote server)
- RAID tests (9 files: parsing, dry-run, scrubbing, scheduling)
- Feature tests (audit logging, database, upload progress)
- 3 GitHub Actions workflows (RAID tests, Playwright E2E, mdadm tests)
- Docker Compose with multi-stage Dockerfiles (backend + frontend + PostgreSQL)
- Nginx reverse proxy with SSL/TLS (Let's Encrypt automation)
- Security headers configuration (OWASP best practices)
- Rate limiting zones (API, auth, file uploads)
.env.production.exampletemplate
- PostgreSQL fully supported with docker-compose.postgres.yml
- Database session management improved
- File metadata service migrated to database
- Alembic migrations configured
- Audit logs moved from JSON files to database
- Added:
prometheus-clientfor metrics collection - Added:
slowapifor rate limiting
- Docker:
docker-compose up -d - Monitoring:
docker-compose --profile monitoring up -d - SSL:
./deploy/ssl/setup-letsencrypt.sh domain.com email@example.com
(Add details from previous releases as they become available)
- ✨ Added: New features
- 🔧 Changed: Changes to existing functionality
- 🗑️ Deprecated: Soon-to-be removed features
- 🔒 Security: Security improvements
- 🐛 Fixed: Bug fixes
- 📦 Dependencies: Dependency updates
- 🚀 Deployment: Deployment-related changes
- 📝 Notes: Additional information
Maintained by: Xveyn License: MIT Repository: https://github.com/your-org/baluhost