refactor: 拆分大文件(contracts 端点、整理服务、浏览器纯函数、整理弹窗来源)

- contracts/src/api.ts 2733 行 → api/*.ts 13 个领域文件 + shared.ts;api.ts 按原顺序合并 Api。
  新旧对比:354 个端点内容与顺序一致,分组键与对外导出一致
- acquisition-organize/services/organize.ts 2645 行 → organize-types / -plan / -exec / -finalize / -records,
  organize.ts 保留为汇总入口,外部引用不变
- browser/service.ts 类外的纯函数(视图映射、原因文案、坐标换算、图片尺寸、出口代理)移到 session-view.ts,
  service.ts 照旧转出
- organize-wizard:来源解析 useResolvedSource 移到 source.ts,FormSelect 移到 form-select.tsx

只挪位置不改逻辑;typecheck、lint、test:all、web build、server 编译与编译产物自检通过。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 17:40:43 +08:00
1 parent c9e8120fc6
commit 8bec4bad5d
26 files changed
+5906 -5696

No files matched your search

+233
View File
@@ -0,0 +1,233 @@
import { z } from "zod";
import * as auth from "../auth.ts";
import { cursorPage, HealthStatus, IdParam } from "../common.ts";
import * as events from "../events.ts";
import * as ops from "../ops.ts";
import { EngineRunIdParam, ep, OkResult } from "./shared.ts";
export const systemApi = {
// ── 登录门禁 ──
/** /auth/setup、/auth/login、/auth/session 免鉴权;改密与 TOTP 只接受控制台 cookie 会话 */
auth: {
setup: ep({
method: "post",
path: "/auth/setup",
scope: "read",
auth: "public",
summary: "首次初始化管理员",
body: auth.AdminSetupRequest,
response: auth.SessionInfo,
}),
login: ep({
method: "post",
path: "/auth/login",
scope: "read",
auth: "public",
summary: "管理员登录",
body: auth.LoginRequest,
response: auth.LoginResult,
}),
logout: ep({ method: "post", path: "/auth/logout", scope: "read", summary: "注销当前会话", response: OkResult }),
session: ep({
method: "get",
path: "/auth/session",
scope: "read",
auth: "public",
summary: "当前登录态(免鉴权)",
response: auth.SessionInfo,
}),
password: ep({
method: "post",
path: "/auth/password",
scope: "admin",
auth: "session",
summary: "修改密码(吊销其它会话)",
body: auth.PasswordChangeRequest,
response: auth.PasswordChangeResult,
}),
totpStatus: ep({
method: "get",
path: "/auth/totp",
scope: "admin",
auth: "session",
summary: "TOTP 状态",
response: auth.TotpStatus,
}),
totp: ep({
method: "post",
path: "/auth/totp",
scope: "admin",
auth: "session",
summary: "TOTP 绑定/启用/停用/重新生成恢复码",
body: auth.TotpAction,
response: auth.TotpActionResult,
}),
totpSetup: ep({
method: "get",
path: "/auth/totp/setup",
scope: "admin",
auth: "session",
summary: "待确认的 TOTP 密钥与 otpauth URL(前端渲染二维码)",
response: auth.TotpSetup,
}),
passkeys: ep({
method: "get",
path: "/auth/passkeys",
scope: "admin",
auth: "session",
summary: "已登记的 Passkey",
response: auth.PasskeyList,
}),
passkeyRegisterOptions: ep({
method: "post",
path: "/auth/passkeys/register/options",
scope: "admin",
auth: "session",
summary: "Passkey 注册挑战",
response: auth.PasskeyChallenge,
}),
passkeyRegister: ep({
method: "post",
path: "/auth/passkeys/register/verify",
scope: "admin",
auth: "session",
summary: "校验并登记 Passkey",
body: auth.PasskeyRegisterRequest,
response: auth.PasskeyInfo,
}),
passkeyRename: ep({
method: "patch",
path: "/auth/passkeys/{id}",
scope: "admin",
auth: "session",
summary: "重命名 Passkey",
params: IdParam,
body: auth.PasskeyRenameRequest,
response: auth.PasskeyInfo,
}),
passkeyDelete: ep({
method: "delete",
path: "/auth/passkeys/{id}",
scope: "admin",
auth: "session",
summary: "删除 Passkey",
params: IdParam,
response: OkResult,
}),
passkeyLoginOptions: ep({
method: "post",
path: "/auth/passkeys/login/options",
scope: "read",
auth: "public",
summary: "Passkey 登录挑战(免鉴权)",
response: auth.PasskeyChallenge,
}),
passkeyLogin: ep({
method: "post",
path: "/auth/passkeys/login/verify",
scope: "read",
auth: "public",
summary: "Passkey 登录(免鉴权;成功即下发会话)",
body: auth.PasskeyLoginRequest,
response: auth.LoginResult,
}),
},
// ── 事件 ──
events: {
list: ep({
method: "get",
path: "/events",
scope: "read",
summary:
"事件流:控制台用 SSE(text/event-stream,cookie 会话);API Key 调用者带 limit 取 JSON 补读页(after=上次 nextAfter)",
query: events.EventReplayQuery,
response: events.EventReplayPage,
}),
},
// ── 系统 ──
system: {
health: ep({
method: "get",
path: "/health",
scope: "read",
summary: "服务健康状态(免鉴权)",
response: HealthStatus,
}),
healthDetail: ep({
method: "get",
path: "/system/health",
scope: "admin",
summary: "进程与健康:进程心跳 / 事件循环延迟 / SSE 连接 / DB / 磁盘 / 挂载根 / 引擎 / 定时任务",
response: ops.SystemHealth,
}),
healthHistory: ep({
method: "get",
path: "/system/health/history",
scope: "admin",
summary: "心跳采样时间序列(事件循环延迟、运行中 run、SSE 连接;按桶聚合)",
query: ops.SystemHealthHistoryQuery,
response: ops.SystemHealthHistory,
}),
storage: ep({
method: "get",
path: "/system/storage",
scope: "admin",
summary: "存储:表体积前 15、库总体积、各缓存用量与预算、备份占用、DATA_DIR 分目录用量、清理任务状态",
response: ops.SystemStorage,
}),
storageCleanup: ep({
method: "post",
path: "/system/storage/cleanup/{target}",
scope: "admin",
summary: "立即执行某个存储清理任务(排入对应定时任务,已在排队或运行中则合并)",
params: ops.StorageCleanupParam,
response: ops.StorageCleanupResult,
}),
},
// ── 引擎面板(仅 admin) ──
engine: {
runs: ep({
method: "get",
path: "/engine/runs",
scope: "admin",
summary: "引擎 runs(状态/名称/时间筛选,新→旧)",
query: ops.EngineRunQuery,
response: cursorPage(ops.EngineRun),
}),
run: ep({
method: "get",
path: "/engine/runs/{id}",
scope: "admin",
summary: "run 详情(step attempts + signals)",
params: EngineRunIdParam,
response: ops.EngineRunDetail,
}),
stats: ep({
method: "get",
path: "/engine/stats",
scope: "admin",
summary: "按状态计数 / 最老待处理 / 活跃 worker 快照",
response: ops.EngineStats,
}),
cancel: ep({
method: "post",
path: "/engine/runs/{id}/cancel",
scope: "admin",
summary: "取消 run",
params: EngineRunIdParam,
body: ops.EngineCancelRequest,
response: ops.EngineCancelResult,
}),
retry: ep({
method: "post",
path: "/engine/runs/{id}/retry",
scope: "admin",
summary: "按原任务名与输入重新入队(新幂等键 retry:<id>:<序号>)",
params: EngineRunIdParam,
response: z.object({ runId: z.string(), retryOf: z.string(), attempt: z.number().int().positive() }),
}),
},
} as const;