Three coordinated fixes for the System Overview widget:
1. routes/monitoring.js — flatten getAllStats() shape from
{current:{cpu:{percent},memory:{percent}}} to {cpu,memory,memoryUsage}
so the widget's Number() coercion actually produces numbers, not NaN.
Skill reference: references/totp-and-system-overview-pitfalls.md §3.
2. routes/health.js — add summary block to /health-checks/status response.
Widget looks for {healthy, unhealthy, total} but only per-service objects
existed. Permissive on healthy side (up|healthy|online), strict on
unhealthy (down|unhealthy|offline|error); anything else counted as
unknown. Same skill §3 reference.
3. middleware.js — add /api/v1/monitoring/stats to PUBLIC_ROUTES and the
rate-limit skip list. The widget polls it every 5s from the dashboard;
cookie-auth works but listing it explicitly makes it future-proof
against auth-cookie expiry and prevents per-second 429s.
End-to-end test (unauthenticated):
GET /api/v1/monitoring/stats -> {cpu: 8.71, memory: 0.37, ...}
GET /api/v1/health-checks/status -> {summary: {healthy:11, unhealthy:4, total:15}}
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:
1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths
Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.
Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)
Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
Two cleanups in one pass for the v1.14.0 'works on any platform' theme:
1. Response helpers — merged src/utils/responses.js and the root-level
response-helpers.js into a single module at src/utils/responses.js.
The old module had a richer set (created, noContent, validationError,
unauthorized, forbidden, notFound, conflict) and is now re-exported
from the new location. Updated 15 routes to import from
src/utils/responses and deleted the root response-helpers.js.
2. Error logger — error-handler.js now uses the unified
src/utils/logging.js#logError (same one src/app.js uses), so all errors
go to one log file with one rotation policy. Removed the dead
asyncHandler export (the real one is in src/utils/async-handler.js
and is used everywhere). Deleted the legacy error-logger.js.
Both are invisible to users — same HTTP response shapes, same log file
path, same error format. Internal-only refactor.
- Add /api/v1/monitoring/stats and /api/v1/health-checks/status to PUBLIC_ROUTES
so the frontend widget can fetch without auth
- Transform monitoring stats response from nested {cpu:{percent}} to flat
{cpu: number, memory: number, memoryUsage: number} for the widget
- Add summary {healthy, unhealthy, total} to health-checks/status response
Cloud backups (Dropbox / WebDAV / SFTP):
- backup-manager.js: save + load handlers per provider, credential
resolution via credentialManager, destination probe.
- routes/backups.js: /credentials/{provider} (masked GET, POST, DELETE),
/test-destination, scheduling endpoints.
- status/js/backup-restore.js: destination picker, provider-specific
credential forms, test button wired to backend probe.
- npm deps already present (dropbox 10.34.0, webdav 5.7.1,
ssh2-sftp-client 11.0.0).
Resource history:
- resource-monitor.js: three-tier rollup storage — raw 10s samples
(7-day retention), hourly rollups (30-day), daily rollups
(365-day). getHistoryByRange() auto-selects the appropriate tier.
- routes/monitoring.js: /monitoring/history/:containerId now supports
startTime/endTime range mode (legacy ?hours=N still works).
- status/js/resource-monitor.js + dashboard.css: "History" tab with
range buttons (1h/24h/7d/30d/1y), SVG sparklines for
CPU / memory / network. Renderer handles raw and rolled-up shapes.
status/dist/features.js rebuilt from source via build.js.
Lifted out of wip/cloud-backups-and-history; the half-finished
app-deps feature from that branch (frontend calls /api/v1/apps/
check-dependencies but the endpoint doesn't exist) is preserved
separately on wip/app-deps for later.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- monitoring.js: Added log dependency, replaced console.log with log.warn
- themes.js: Added log dependency, replaced console.error with log.error
- src/app.js: Pass log to monitoringRoutes and themesRoutes
This fixes error messages being lost to stdout instead of proper log files.
Full codebase including API server (32 modules + routes), dashboard frontend,
DashCA certificate distribution, installer script, and deployment skills.