Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 35s
CI / tests-unit (push) Successful in 1m59s
CI / tests-integration (push) Successful in 1m58s
CI / tests-ui (push) Successful in 2m43s
CI / preflight (push) Skipped
CI / deploy (push) Failing after 19s
Dependency updates are handled manually, so the scheduled Renovate job only cost a daily privileged Docker run on the deploy host. The empty cache directory it maintained is gone too, and the operations note now records that updates are manual instead of describing bot behaviour.
86 lines
5.8 KiB
Markdown
86 lines
5.8 KiB
Markdown
# CMS error center and dependency maintenance
|
|
|
|
Open **HK > DevOps > CMS error center** (`/admin/devops/cms-errors`).
|
|
The previous `/admin/devops/errors` page still displays emulator errors.
|
|
|
|
## Access and workflow
|
|
|
|
- Read: existing `admin.devops.view` permission, checked on the server.
|
|
- Mark resolved: `admin.devops.edit`, checked again in the server action; recorded in the staff audit log.
|
|
- Search by event reference, Next.js digest, route, message or deployment version.
|
|
- Expand a group for its latest stack, sanitized context and occurrence references.
|
|
- Marking a group resolved does not delete evidence. A later occurrence reopens it.
|
|
- Refresh is manual so inspecting an expanded error is not interrupted by polling.
|
|
|
|
## What is collected
|
|
|
|
Pino `logger.error`, `logServerError`, unexpected action errors, Next.js request
|
|
failures, React error boundaries, uncaught browser errors and unhandled browser
|
|
promise rejections. API wrapper failures return an `errorId`; Next.js boundary
|
|
errors can be correlated by their digest. Release identifiers come from the build.
|
|
Browser reports retain their own client release separately from the receiving server.
|
|
|
|
Reports are stored in `storage/cms-errors`, using the existing persistent storage
|
|
mount. No third-party service, token or new database table is required.
|
|
Storage does not depend on database availability; viewing the HK and its permission
|
|
checks still require authentication/database availability. Server console logs
|
|
remain the fallback when the CMS itself cannot serve requests.
|
|
|
|
Retention: seven days; approximately 10 MB/day, 100 queued server writes, and the
|
|
latest 1,000 events in the viewer. Limits are per CMS process/storage volume;
|
|
this is intended for the existing single-instance deployment. Daily expiry runs
|
|
on the next write. The browser endpoint is same-origin, body-size bounded and
|
|
rate-limited. Browser reports are untrusted observations and cannot grant access.
|
|
Known credential patterns and URL parameters are redacted; arbitrary object
|
|
metadata and request bodies are excluded. Avoid putting personal data in error
|
|
messages: this is pattern-based redaction, not a universal data-loss filter.
|
|
|
|
This does not collect historical console logs, process crashes before framework
|
|
startup, nginx failures, all `console.error` calls, or every handled business
|
|
validation error. A browser stack may point at minified chunks; private source-map
|
|
symbolication and distributed traces are not part of this local viewer. A recorded
|
|
stack is diagnostic evidence, not an automatic root-cause determination.
|
|
|
|
## Dependencies
|
|
|
|
`pnpm install --frozen-lockfile`, `pnpm deps:audit`, `pnpm typecheck`, `pnpm test`,
|
|
`pnpm biome:lint`, and `pnpm build` are the verification sequence.
|
|
`pnpm analyze --output` writes a Next.js bundle analysis (not an application build).
|
|
|
|
TinyMCE 8.9 is pinned in pnpm. `pnpm assets:editor` copies its runtime files and
|
|
license notices to ignored `public/vendor/tinymce`; dev/build run this first.
|
|
The Docker build includes the generated assets. The editor retains its existing
|
|
HTML fields and toolbar; validate saved content and preview when upgrading it.
|
|
|
|
Lenis has been removed; the public site now uses native scrolling. Other used
|
|
runtime libraries remain. Vitest and its coverage provider are upgraded together;
|
|
`clearMocks: false` preserves initialization-time permission contract assertions.
|
|
|
|
Dependency updates are manual: Renovate has been removed, so there is no bot
|
|
opening upgrade pull requests. Node/pnpm upgrades remain coordinated with
|
|
Docker and the runner toolchain.
|
|
Obsolete global overrides were removed; a scoped esbuild override remains because
|
|
Drizzle Kit's loader still resolves a vulnerable legacy development-server build.
|
|
The two deprecated esbuild-kit packages remain upstream dependencies of Drizzle
|
|
Kit; replacing the ORM is not warranted for this tooling issue.
|
|
|
|
## HK request performance
|
|
|
|
Open **DevOps → Request performance** (`/admin/devops/performance`). Access requires `DEVOPS_VIEW`; collection only retains requests that passed authentication and permission checks through `withAdmin`.
|
|
|
|
The view shows recent requests, their server duration, completed database query count/time/errors, monitored curl download count/time/errors, HTTP status and the existing operation ID. Search by route or operation ID, sort by duration or recency, and filter requests taking at least one second.
|
|
|
|
### Measurement boundaries
|
|
|
|
- Duration ends when the handler returns its response. Streaming completion, background jobs, browser rendering and public pages are not measured.
|
|
- Database spans wrap the shared mysql2 promise pool and transaction connection query/execute calls. Query parameters and SQL are never collected. Explicit transaction connection acquisition and transaction control methods are not separate spans.
|
|
- External spans currently cover `curlFetchText` and `curlDownload`; ordinary fetch calls and other integrations are not covered.
|
|
- Concurrent dependency durations can exceed wall-clock request duration. Do not subtract the sums to infer application CPU time.
|
|
- Dynamic route values and query strings are removed. No request bodies, headers, usernames, download URLs or SQL text are stored.
|
|
|
|
### Storage and operation
|
|
|
|
No new environment variables or packages are required. Redis stores at most 200 recent samples under `cms:performance:v1`, with one-hour retention. Writes are best effort, restricted to an already-ready connection and at most four pending batches; the request never waits for persistence. The view reads at most 200 entries and falls back after one second if shared storage is unavailable.
|
|
|
|
An in-process buffer preserves up to 200 samples during outages. The page explicitly labels this local mode; it is per instance and disappears on restart. Filtering applies to the retained samples, not complete traffic history. Under load or during storage outages, some shared samples may be omitted.
|