Observability
Runtime telemetry surface — service health, system logs, error reports, feedback, and audit trail. Instance admins only.
The Observability surface lives at /observability in the QuoxCORE
dashboard. It is a peer top-level area to Settings, dedicated to
runtime telemetry: logs, errors, service health, user feedback, and
the audit trail.
It is gated to instance administrators. Members and org admins who do not also hold an instance-admin role do not see the Observability entry in the sidebar, and direct URL access is blocked by a route guard.
Why a separate surface
Configuring a system and watching it run are different jobs. Mature products consistently split them — Stripe Workbench, Vercel Observability, Supabase Logs Explorer, GitLab Admin → Monitoring. QuoxCORE follows the same pattern: Settings is for changing behaviour, Observability is for inspecting what happened.
Before the SET-IA settings refactor, these surfaces lived under
/admin/* mixed with instance configuration. They were extracted
to /observability so each surface has a single concern.
Tabs
| Tab | URL | What it shows |
|---|---|---|
| Overview | /observability | Instance dashboard: user count, org count, active sessions, login activity (24h), error rate (24h), API key totals |
| Service Health | /observability/health | Status of every registered backend service (auth, collector, n8n, qdrant, dashboard) with last-checked timestamps and a manual recheck button |
| System Logs | /observability/logs | Recent log lines from auth, API, worker, and collector services. Filter by service, level (error/warn/info/debug), and limit |
| Error Reports | /observability/errors | Captured frontend and backend errors: unhandled promise rejections, React error-boundary catches, 5xx API responses, manually filed reports. Triage / mark-resolved |
| User Feedback | /observability/feedback | Product feedback submissions from the in-app feedback form. Subject, body, contact, status (new / triaged / closed) |
| Audit Trail | /observability/audit (deep-link only) | Placeholder for the unified audit view. Org-scoped audit events live on the org dashboard's Activity tab today |
Access control
| Role | Can see Observability sidebar entry? | Can hit direct URL? |
|---|---|---|
| Logged-in user, no admin role | No | No (403 from route guard) |
| Org admin (no instance role) | No | No |
| Instance readonly admin | Yes | Yes (read-only) |
| Instance admin | Yes | Yes (can trigger health rechecks, mark feedback resolved) |
| Instance superadmin | Yes | Yes |
The role-gating is enforced at three levels:
- Sidebar visibility —
navRegistryonly renders the Observability entry when the user has the appropriate role. - Route guard —
<ProtectedRoute minRole="admin">wraps the layout inApp.jsx. - Backend — every endpoint behind
/api/admin/*(which Observability reads) goes throughrequireInstanceAdmin('readonly')middleware.
A non-admin attempting /observability/logs directly hits an "Access Denied" panel rendered by the layout's auth check, never any data.
Common triage flows
"A user reports the chat is broken"
- Open Service Health — confirm
collector,auth, andqdrantare green - Open System Logs — filter
service=collector level=error, look for stack traces around the user's report time - Open Error Reports — scan for unhandled errors with the user's
org_idor recent timestamp - If the issue traces to credentials, open Settings → Provider Keys to verify the resolved key is healthy
"Audit needs evidence of a config change"
- Open the org dashboard at
/orgs/<org-id>→ Activity tab — every settings change is hash-chained through VOLT and surfaces here - The instance-level audit (admin grants, encryption rotations, instance config patches) is recorded server-side via
logAdminAccess()— surfaced in a future unified Audit Trail tab on this page - For compliance bundles, use
/evidence(Evidence Explorer) which builds a per-control PDF
"Feedback queue is unread"
- Open User Feedback — sorted by created_at desc, unread items have a badge
- Click an item to read the full body, change status, leave an internal note
- Resolved items remain queryable indefinitely (subject to the
retention.system_logs_daysconfig in Settings → Instance → Retention Defaults)
Where things were before
If you used QuoxCORE before the SET-IA refactor, the URLs you remember have all been preserved as redirects:
| Legacy URL | New home |
|---|---|
/admin | /settings (instance scope visible to admins) |
/admin/services | /observability/health |
/admin/logs | /observability/logs |
/admin/errors | /observability/errors |
/admin/feedback | /observability/feedback |
/admin/config | /settings#instance/auth |
/admin/keys | /settings#instance/provider-keys |
/admin/admins | /settings#instance/admins |
Bookmarks survive forever — the redirects ship with the dashboard.