Files
ai-kefu-admin/admin/src/api/siteImport.ts
T
浅念 323588c54d feat(admin): site-import API 与模型纯函数
Task 8(TDD):草稿包→表单/保存序列/warnings 分级纯函数 + POST/GET
API 薄封装。事实源 app/platform/routes/site_import_routes.py(GET 五键
无 failed_phase——retry 对 failed 一律展示后端 409 兜底)与 generator.py
build() 的 spec §4 草稿包形状。保存序列沉淀 spec §5 顺序语义(brand 的
GET 在头像上传之后)与 deflections_contact 池形态分派注记,Task 9 装配
消费。前端 vitest 188 → 201。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-20 21:56:05 +08:00

78 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* site-import API(POST 启动 / GET 轮询)——Task 8;消费方
* site-import 视图(Task 9)。
*
* 端点事实源:app/platform/routes/site_import_routes.py
* (/api/platform/tenants/{slug}/site-import[/{task_id}],
* _tenant_guard 守租户——超管与租户管理员两角色可用)。
*
* 契约要点(Task 7 评审备忘):
* - POST 200(非 201)→ {task_id};body 单形态发送——新建 {url} /
* 复活 {retry: 'generate', task_id}(retry 形态后端忽略 url 字段);
* - 429(每租户 15 分钟 3 次频控)/ 409(并发上限·非 generate-failed
* 态复活)的 detail 已是白话文案——调用方原样展示,不二次翻译;
* - GET 五键 status/phase/pages/draft/error——**无 failed_phase**:前端
* retry 按钮对 failed 一律展示,能否复活由后端 409 兜底判定;
* - GET 404 = 任务不存在/已过期(终态语义——视图层 isTerminal404 消费)。
*
* 草稿包类型 SiteImportDraft 是 spec §4 的单一 TS 镜像,定义在视图
* model(type-only 反向引用,无运行时耦合——api 层不 import 视图代码)。
*/
import { http, type RequestOptions } from './client'
import type { SiteImportDraft } from '@/views/site-import/model'
/** 任务状态(app/platform/site_import/task.py TaskState 镜像) */
export type SiteImportStatus = 'pending' | 'crawling' | 'generating' | 'done' | 'failed'
/** GET 轮询响应五键(spec §4;后端恒返五键——非 done 时 draft 为 null) */
export interface SiteImportTaskResponse {
status: SiteImportStatus
/** 运行中阶段('crawling' | 'generating';非运行态 null) */
phase: string | null
/** 已抓页数(运行中递增;BFS 总数不可知——展示「第 N 页」不展示 M) */
pages: number
/** 草稿包(仅 status=done 非 null) */
draft: SiteImportDraft | null
/** 白话失败原因(仅 status=failed 非 null) */
error: string | null
}
/** POST body 单形态:新建 {url} / 复活 {retry, task_id}(后端对 retry
* 形态忽略 url——前端按用途二选一发送,不带冗余键) */
export type StartSiteImportBody = { url: string } | { retry: 'generate'; task_id: string }
/** POST 启动响应 */
export interface StartSiteImportResponse {
task_id: string
}
/** 启动/复活导入任务(POST /api/platform/tenants/{slug}/site-import)。
* 新建传 {url}(http(s) 公网地址——内网/非法地址 400);复活传
* {retry: 'generate', task_id}(同 task_id 只重跑生成步,复用已抓文本)。
* 429/409/404 经既有 ApiError 抛(detail 为白话文案)。 */
export function startSiteImport(
slug: string,
body: StartSiteImportBody,
config?: RequestOptions
): Promise<StartSiteImportResponse> {
return http.post<StartSiteImportResponse>(
`/api/platform/tenants/${slug}/site-import`,
body,
config
)
}
/** 轮询任务状态(GET /api/platform/tenants/{slug}/site-import/{task_id})。
* 3s 间隔;7.5 分钟窗口外自动停(> 服务端 7 分钟总超时)。404 = 过期
* 终态(isTerminal404)——跨租户持他人 task_id 同为 404。 */
export function getSiteImportTask(
slug: string,
taskId: string,
config?: RequestOptions
): Promise<SiteImportTaskResponse> {
return http.get<SiteImportTaskResponse>(
`/api/platform/tenants/${slug}/site-import/${taskId}`,
config
)
}