import { apiFetch, apiFetchBlob, downloadBlob } from "@/lib/api"; /** * NL2SQL 查询(/nl2sql/*)与管理(/nl2sql/admin/*)适配层。 * 按本次约定:页面以只读展示为主,运维类接口(jobs / refresh / kill / cache-invalidate) * 提供触发按钮,权限类接口只做列表展示,不建增删改表单。 */ export interface Nl2SqlQueryResult { query_id?: string; question?: string; generated_sql?: string | null; columns?: string[]; rows?: Record[]; row_count?: number; truncated?: boolean; summary?: string; answer?: string; elapsed_ms?: number | null; trace_id?: string; [key: string]: unknown; } export interface QueryHistoryItem { query_id: string; user_id?: number; session_id?: string | null; caller_agent?: string | null; question?: string; generated_sql?: string | null; access_tables?: string[]; status?: string; error_code?: string | null; error_message?: string | null; row_count?: number; truncated?: boolean; elapsed_ms?: number | null; trace_id?: string | null; create_time?: string | null; } export interface Nl2SqlHealth { [component: string]: unknown; } export interface QueryRole { id?: number; employee_role?: string; max_rows?: number; active?: boolean; [key: string]: unknown; } export interface TablePermission { id?: number; table_name?: string; active?: boolean; [key: string]: unknown; } export interface ColumnPermission { id?: number; table_name?: string; column_name?: string; active?: boolean; [key: string]: unknown; } export interface SensitiveField { id?: number; table_name?: string; column_name?: string; mask_type?: string; active?: boolean; [key: string]: unknown; } export interface MaintenanceJobResult { name?: string; status?: string; attempts?: number; detail?: unknown; error_type?: string | null; } export type MaintenanceTask = | "metadata_sync" | "vector_cleanup" | "consistency_check" | "history_cleanup"; function qs(params: Record) { const search = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null && value !== "") search.set(key, String(value)); } const text = search.toString(); return text ? `?${text}` : ""; } export const nl2sqlApi = { /* ---------------------------------------------------------- 查询域(11) */ query: (body: { question: string; session_id?: string; caller_agent?: string; max_rows?: number; include_sql?: boolean; page?: number; page_size?: number; sort_by?: string; sort_order?: "asc" | "desc"; }) => apiFetch("/nl2sql/query", { method: "POST", body: JSON.stringify(body) }), health: () => apiFetch("/nl2sql/health"), explain: (sql: string) => apiFetch[]>("/nl2sql/query/explain", { method: "POST", body: JSON.stringify({ sql }), }), history: (params: { page?: number; page_size?: number; status?: string; start_time?: string; end_time?: string; } = {}) => apiFetch<{ page?: number; page_size?: number; items?: QueryHistoryItem[] }>( `/nl2sql/query-history${qs(params)}` ), historyDetail: (queryId: string) => apiFetch(`/nl2sql/query-history/${encodeURIComponent(queryId)}`), exportHistory: async (queryId: string) => { const blob = await apiFetchBlob(`/nl2sql/query-history/${encodeURIComponent(queryId)}/export`); downloadBlob(blob, `nl2sql-${queryId}.csv`); }, running: () => apiFetch[]>("/nl2sql/query/running"), kill: (queryId: string) => apiFetch<{ query_id?: string; verified?: boolean }>("/nl2sql/query/kill", { method: "POST", body: JSON.stringify({ query_id: queryId }), }), diagnostics: () => apiFetch<{ health?: Nl2SqlHealth; running?: Record[]; metrics?: Record; recent?: unknown[]; }>("/nl2sql/query/diagnostics"), invalidateCache: (tableNames: string[]) => apiFetch>("/nl2sql/cache/invalidate", { method: "POST", body: JSON.stringify({ table_names: tableNames }), }), /* ------------------------------------------------------ 管理域(20) */ roles: () => apiFetch("/nl2sql/admin/roles"), roleTables: (roleId: number) => apiFetch(`/nl2sql/admin/roles/${roleId}/tables`), roleColumns: (roleId: number) => apiFetch(`/nl2sql/admin/roles/${roleId}/columns`), sensitiveFields: () => apiFetch("/nl2sql/admin/sensitive-fields"), metrics: () => apiFetch>("/nl2sql/admin/metrics"), metricsPrometheus: () => apiFetch("/nl2sql/admin/metrics/prometheus"), runtimeConfig: () => apiFetch>("/nl2sql/admin/runtime-config"), runJob: (task: MaintenanceTask, beforeDays = 180) => apiFetch("/nl2sql/admin/jobs", { method: "POST", body: JSON.stringify({ task, before_days: beforeDays }), }), jobHistory: (params: { page?: number; page_size?: number; status?: string } = {}) => apiFetch<{ items?: Record[]; page?: number; page_size?: number }>( `/nl2sql/admin/jobs/history${qs(params)}` ), semantics: () => apiFetch>("/nl2sql/admin/semantics"), refreshSemantics: () => apiFetch>("/nl2sql/admin/semantics/refresh", { method: "POST" }), };