Backend (dashcaddy-api/routes/errorlogs.js):
- GET /error-logs: server-side filter chain (level, context substring,
free-text search across error/context/detail/IP, ISO since/until),
real pagination via limit/offset with hasMore reporting, MAX_LIMIT=500
clamp, newest-first sort.
- New endpoint GET /error-logs/contexts returns distinct contexts with
occurrence counts for the frontend dropdown.
- Robust entry parser handles malformed blocks as raw entries so nothing
silently disappears from the operator's view.
- DELETE /error-logs requires { confirm: 'CLEAR' } body and audits the
wipe itself (mirrors DC-050 hardening).
- DC-052 fix: removed legacy /audit-logs GET/DELETE handlers that lived
here before DC-050. errorLogsRoutes is mounted in src/app.js (L733)
BEFORE auditLogRoutes (L789), so Express router.use() semantics meant
the legacy proxies shadowed DC-050's hardened versions — DELETE
without confirm=CLEAR would silently wipe the audit log, and
/audit-logs/actions was unreachable. The hardened routes/audit-log.js
is now the single source of truth.
Frontend (status/js/error-logs.js):
- Level / Context / Search / Since / Until filter row mirroring the
audit-log UI (DC-050).
- Load More pagination with abort-on-filter-change.
- Click-to-expand stack frames in <pre> with scroll-cap.
- Contexts dropdown populated from /error-logs/contexts (refreshes on
every modal open and after a clear).
- confirm=CLEAR clear with success/error notification.
Tests (__tests__/routes/errorlogs.routes.test.js — 20 cases, all pass):
- Endpoint shape, newest-first, level/context/search/since/until filters,
invalid-since + unknown-level 400s, pagination + hasMore, MAX_LIMIT
clamp, /contexts distinct list, confirm=CLEAR gating + audit emission,
missing-file empty results, malformed entry fallback, /contexts
missing-file empty, search-by-IP, huge since/until, combined filters.
Full suite: 86 suites / 1910 tests, all green.
GLM judge round 1 (372s, 50 tool calls): grade D — HIGH audit-log
shadowing + MEDIUM coverage gaps + LOW tofu glyph.
GLM judge round 2 (114s, 25 tool calls): grade A — all findings fixed,
no new regressions, ship recommendation: ship.
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.
Full codebase including API server (32 modules + routes), dashboard frontend,
DashCA certificate distribution, installer script, and deployment skills.