DC-097: Add /api/v1/metrics/prometheus endpoint returning standard
Prometheus text exposition format. Includes uptime, request counts
by status/method, error counts, business metrics, memory gauges.
Public (no auth) for Prometheus scraping.
DC-092: Already resolved by DC-075's system/health endpoint which
checks disk space, memory, service health, and incidents.
All 1540 tests pass.
Backend:
- src/monitoring/disk-space-monitor.js: monitors Docker disk usage against
user-configured budget, auto-cleans at thresholds, breaks down by category
- routes/disk-space.js: GET /disk, GET /disk/breakdown, POST /disk/config,
POST /disk/cleanup endpoints
- src/app.js: wire DiskSpaceMonitor into startup, 10-min check interval
- All 1539 tests pass
Product Vision (PRODUCT-VISION.md):
- DashCaddy is a self-hosting platform, not just a dashboard
- Core value: 'Self-host anything in 30 seconds'
- Three pillars: One-click deploy, zero-config networking, self-healing infra
- vs Portainer/CasaOS/Yunohost positioning
New backlog tasks (P5 tier, DC-101–108):
- Disk budget, one-click deploy with auto Caddyfile+DNS, container
auto-discovery, app catalog, smart wizard, visual Caddy builder,
disaster recovery, multi-host fleet management
47 total backlog tasks, ~110 hr of work, cron running every 2h.
Three coordinated changes to stop every gated *.sami service flipping
red after ~20 probes:
1. health-checker.js _doRequest() now sends X-DashCaddy-HealthCheck: 1
on every outgoing probe. Caddy uses this header (combined with a
trusted source IP via the new @healthcheckProbe matcher in the
dashcaddy_auth snippet) to bypass forward_auth for local container
probes. Without the bypass, forward_auth 401's every probe, and the
authLimiter (20 req / 15 min, DC-027) caps us out within minutes.
2. evaluateHealth() default expectedStatusCodes now includes 401, 403,
and 429. Defense in depth — if a future Caddy reload drops the
bypass, 429 from the rate-limited gate no longer marks the service
as down (it just means the gate answered, which proves the service
is reachable through Caddy).
3. (start.sh — already shipped on the running container, will land
with the next release build) ca.sami now maps to 100.121.150.22
(DNS2) instead of 127.0.0.1, which is the container's own loopback
where nothing serves :443. The CA web UI lives on DNS2's Caddy.
Tests:
- evaluateHealth: 401, 403, 429 accepted by default
- _doRequest: X-DashCaddy-HealthCheck: 1 always present
- _doRequest: user-supplied headers preserved alongside marker
Bump 1.14.7 → 1.14.8.
After DC-005 refactor moved health-checker.js into src/monitoring/, the
require path was never updated. Tests in __tests__/health-checker.test.js
failed with 'Cannot find module' → 59 cascading test failures in the
health-checker suite.
Path: src/monitoring/health-checker.js → 'require(./platform-paths)'
Fix: 'require(../../platform-paths)'
Verified: 921/922 tests passing (one known async-timing flake in
logging.test.js 'writes entry to ERROR_LOG_FILE with context').
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)