import type { AdminLogLine, AdminLogQuery, AdminNotification, AdminNotificationQuery, AdminObservabilityMetrics, AdminStorageStatus, AdminTraceSpan, AuditRecord, BackthinkItem, SystemBackupResp, SystemRestoreResp, SystemRevokeKeysResp, SystemRotateJwtResp, } from "../types"; import { limitQuery, request } from "./core"; /** GET /api/v1/admin/observability/metrics — gateway request metrics. */ export function adminObservabilityMetrics(): Promise { return request("/admin/observability/metrics"); } /** GET /api/v1/admin/observability/trace?limit=N — most recent traced spans. */ export function adminObservabilityTrace(limit?: number): Promise { return request(`/admin/observability/trace${limitQuery(limit)}`); } /** GET /api/v1/admin/observability/audit?limit=N — most recent audit entries. */ export function adminObservabilityAudit(limit?: number): Promise { return request(`/admin/observability/audit${limitQuery(limit)}`); } /** GET /api/v1/admin/observability/logs?level=&limit= — the gateway's structured * log tail, newest first (owner/admin only). An omitted `level` means “all”; the * backend defaults `limit` to 200 and caps it at 1000. */ export function adminObservabilityLogs( params: AdminLogQuery = {} ): Promise { const qs = new URLSearchParams(); if (params.level) qs.set("level", params.level); if (params.limit !== undefined) qs.set("limit", String(params.limit)); const q = qs.toString(); return request(`/admin/observability/logs${q ? `?${q}` : ""}`); } /** GET /api/v1/admin/backthink — persisted background-think records (newest first). */ export function adminBackthink(limit?: number): Promise { return request(`/admin/backthink${limitQuery(limit)}`); } /** GET /api/v1/admin/notifications?type=&before=&limit= — the unified notification * feed (design/10 §3 #16: audit + channel + backthink + system aggregated). * `type` omitted = all types, `before` = createdAt(ms) cursor for older pages, * `limit` defaults to 50 (backend caps at 200). Returned newest first. */ export function adminListNotifications( params: AdminNotificationQuery = {} ): Promise { const qs = new URLSearchParams(); if (params.type) qs.set("type", params.type); if (params.before !== undefined) qs.set("before", String(params.before)); if (params.limit !== undefined) qs.set("limit", String(params.limit)); const q = qs.toString(); return request(`/admin/notifications${q ? `?${q}` : ""}`); } /* ---------------------------------------------------------------------------- * System management admin writes (owner-only, audited). Reference: * internal/services/gateway/admin_system.go + Docs/api-client.md §系统设置契约. * All four are implemented (not 501) — they return real data. * -------------------------------------------------------------------------- */ /** GET /api/v1/admin/system/storage — the **read-only** storage snapshot behind the * dashboard's 存储 card (v0.60): SQLite file/WAL/page stats, the documents table's * count+bytes, and whether the optional pgvector enhancement is configured and * actually live. The `vector` block never carries credentials (no DSN, no password). * owner-only; the backend answers `500 storage_unavailable` rather than a fake * all-zero snapshot when the live DB handle is not wired. */ export function adminSystemStorage(): Promise { return request("/admin/system/storage"); } /** POST /api/v1/admin/system/revoke-keys — revokes every registered API key. */ export function adminSystemRevokeKeys(): Promise { return request("/admin/system/revoke-keys", { method: "POST" }); } /** POST /api/v1/admin/system/rotate-jwt — swaps the JWT signing secret (≥32 chars). * The secret is provided by the owner and never echoed back; all existing tokens * become invalid, so the client must re-login afterward. */ export function adminSystemRotateJWT(newSecret: string): Promise { return request("/admin/system/rotate-jwt", { method: "POST", body: JSON.stringify({ newSecret }), }); } /** POST /api/v1/admin/system/backup — snapshots the SQLite DB (VACUUM INTO, incl. WAL). */ export function adminSystemBackup(): Promise { return request("/admin/system/backup", { method: "POST" }); } /** POST /api/v1/admin/system/restore — restores a data-dir backup; path must live * inside the data directory (path-traversal guard). The backend pre-backups the * current DB and reports that the swap needs a restart. */ export function adminSystemRestore(path: string): Promise { return request("/admin/system/restore", { method: "POST", body: JSON.stringify({ path }), }); }