import type { AdminNotification, AdminNotificationQuery, AdminObservabilityMetrics, 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/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. * -------------------------------------------------------------------------- */ /** 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 }), }); }