Prevent login-page 401 noise by deferring project/chat API calls until auth is confirmed, use public-config for registration policy, and add client-side duty assignment checks before saving workflow plans. Co-authored-by: Cursor <cursoragent@cursor.com>
131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
import {
|
|
Project,
|
|
ProjectWorkflow,
|
|
WorkflowDefinition,
|
|
DocumentLineage,
|
|
CreateProjectInput,
|
|
ActivateWorkflowInput,
|
|
ActivateWorkflowResult,
|
|
} from '../types/projectWorkflow';
|
|
import { getBearerAuthHeaders } from './authHeaders';
|
|
|
|
const API_BASE = '';
|
|
|
|
export async function fetchProjects(): Promise<Project[]> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects`, {
|
|
headers: getBearerAuthHeaders(),
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error(`获取项目列表失败: ${res.status}`);
|
|
}
|
|
const data = await res.json();
|
|
return Array.isArray(data) ? data : [];
|
|
}
|
|
|
|
export async function createProject(data: CreateProjectInput): Promise<Project> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects`, {
|
|
method: 'POST',
|
|
headers: getBearerAuthHeaders('application/json'),
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(text || `创建项目失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function getProject(id: number): Promise<Project> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects/${id}`, {
|
|
headers: getBearerAuthHeaders(),
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error(`获取项目详情失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function fetchProjectWorkflows(projectId: number): Promise<ProjectWorkflow[]> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects/${projectId}/workflows`, {
|
|
headers: getBearerAuthHeaders(),
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error(`获取项目工作流清单失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function activateWorkflow(
|
|
projectId: number,
|
|
input: ActivateWorkflowInput
|
|
): Promise<ActivateWorkflowResult> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects/${projectId}/active-workflow`, {
|
|
method: 'PUT',
|
|
headers: getBearerAuthHeaders('application/json'),
|
|
body: JSON.stringify(input),
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
let msg = text;
|
|
try {
|
|
const parsed = JSON.parse(text);
|
|
if (parsed.message) msg = parsed.message;
|
|
} catch {
|
|
// ignore
|
|
}
|
|
throw new Error(msg || `切换激活工作流失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function fetchWorkflowCatalog(): Promise<WorkflowDefinition[]> {
|
|
const res = await fetch(`${API_BASE}/api/v1/workflows`, {
|
|
headers: getBearerAuthHeaders(),
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error(`获取工作流规范目录失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function fetchProjectLineage(
|
|
projectId: number,
|
|
docId?: string
|
|
): Promise<DocumentLineage[]> {
|
|
const url = docId
|
|
? `${API_BASE}/api/v1/projects/${projectId}/lineage?doc_id=${encodeURIComponent(docId)}`
|
|
: `${API_BASE}/api/v1/projects/${projectId}/lineage`;
|
|
const res = await fetch(url, {
|
|
headers: getBearerAuthHeaders(),
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error(`获取文档血缘失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function runProjectWorkflow(
|
|
projectId: number,
|
|
workflowKey: string,
|
|
payload: Record<string, unknown>
|
|
): Promise<unknown> {
|
|
const res = await fetch(`${API_BASE}/api/v1/projects/${projectId}/workflows/${workflowKey}/run`, {
|
|
method: 'POST',
|
|
headers: getBearerAuthHeaders('application/json'),
|
|
body: JSON.stringify(payload),
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
let msg = text;
|
|
try {
|
|
const parsed = JSON.parse(text);
|
|
if (parsed.message) msg = parsed.message;
|
|
else if (parsed.error_reason) msg = parsed.error_reason;
|
|
} catch {
|
|
// ignore
|
|
}
|
|
throw new Error(msg || `启动工作流运行失败: ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|