fix(saas): P1 审计修复 — 连接池断路器 + Worker重试 + XSS防护 + 状态机SQL解析器

P1 修复内容:
- F7: health handler 连接池容量检查 (80%阈值返回503 degraded)
- F9: SSE spawned task 并发限制 (Semaphore 16 permits)
- F10: Key Pool 单次 JOIN 查询优化 (消除 N+1)
- F12: CORS panic → 配置错误
- F14: 连接池使用率计算修正 (ratio = used*100/total)
- F15: SQL 迁移解析器替换为状态机 (支持 $$, DO $body$, 存储过程)
- Worker 重试机制: 失败任务通过 mpsc channel 重新入队
- DOMPurify XSS 防护 (PipelineResultPreview)
- Admin V2: ErrorBoundary + SWR全局配置 + 请求优化
This commit is contained in:
iven
2026-03-30 14:21:39 +08:00
parent bc8c77e7fe
commit ba2c6a6105
38 changed files with 490 additions and 236 deletions

View File

@@ -1,35 +1,35 @@
import request from './request'
import request, { withSignal } from './request'
import type { PromptTemplate, PromptVersion, PaginatedResponse } from '@/types'
export const promptService = {
list: (params?: Record<string, unknown>) =>
request.get<PaginatedResponse<PromptTemplate>>('/prompts', { params }).then((r) => r.data),
list: (params?: Record<string, unknown>, signal?: AbortSignal) =>
request.get<PaginatedResponse<PromptTemplate>>('/prompts', withSignal({ params }, signal)).then((r) => r.data),
get: (name: string) =>
request.get<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`).then((r) => r.data),
get: (name: string, signal?: AbortSignal) =>
request.get<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`, withSignal({}, signal)).then((r) => r.data),
create: (data: {
name: string; category: string; description?: string; source?: string
system_prompt: string; user_prompt_template?: string
variables?: unknown[]; min_app_version?: string
}) =>
request.post<PromptTemplate>('/prompts', data).then((r) => r.data),
}, signal?: AbortSignal) =>
request.post<PromptTemplate>('/prompts', data, withSignal({}, signal)).then((r) => r.data),
update: (name: string, data: { description?: string; status?: string }) =>
request.put<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`, data).then((r) => r.data),
update: (name: string, data: { description?: string; status?: string }, signal?: AbortSignal) =>
request.put<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`, data, withSignal({}, signal)).then((r) => r.data),
archive: (name: string) =>
request.delete<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`).then((r) => r.data),
archive: (name: string, signal?: AbortSignal) =>
request.delete<PromptTemplate>(`/prompts/${encodeURIComponent(name)}`, withSignal({}, signal)).then((r) => r.data),
listVersions: (name: string) =>
request.get<PromptVersion[]>(`/prompts/${encodeURIComponent(name)}/versions`).then((r) => r.data),
listVersions: (name: string, signal?: AbortSignal) =>
request.get<PromptVersion[]>(`/prompts/${encodeURIComponent(name)}/versions`, withSignal({}, signal)).then((r) => r.data),
createVersion: (name: string, data: {
system_prompt: string; user_prompt_template?: string
variables?: unknown[]; changelog?: string; min_app_version?: string
}) =>
request.post<PromptVersion>(`/prompts/${encodeURIComponent(name)}/versions`, data).then((r) => r.data),
}, signal?: AbortSignal) =>
request.post<PromptVersion>(`/prompts/${encodeURIComponent(name)}/versions`, data, withSignal({}, signal)).then((r) => r.data),
rollback: (name: string, version: number) =>
request.post<PromptTemplate>(`/prompts/${encodeURIComponent(name)}/rollback/${version}`).then((r) => r.data),
rollback: (name: string, version: number, signal?: AbortSignal) =>
request.post<PromptTemplate>(`/prompts/${encodeURIComponent(name)}/rollback/${version}`, undefined, withSignal({}, signal)).then((r) => r.data),
}