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:
1 parent
c9e8120fc6
commit
8bec4bad5d
26 files changed
+5906
-5696
No files matched your search
@@ -0,0 +1,152 @@
|
||||
// 端点定义共用的 helper 与跨分组 schema(由 api.ts 汇总导出公开部分)
|
||||
import { z } from "zod";
|
||||
import * as agent from "../agent.ts";
|
||||
import { type ApiScope, CursorQuery, cursorPage, Id, IdParam } from "../common.ts";
|
||||
import * as content from "../content.ts";
|
||||
import * as identity from "../identity.ts";
|
||||
import * as instances from "../instances.ts";
|
||||
// 所有 REST 端点的路径常量与请求/响应 schema 汇总。
|
||||
// path 相对 API_PREFIX,参数用 OpenAPI 风格 `{id}`(server 的 createRoute 直接使用);
|
||||
// web 用 buildPath() 填参数。响应体统一套 apiResponse() 信封,这里的 response 是 data 部分。
|
||||
|
||||
export const API_PREFIX = "/api/v1";
|
||||
|
||||
export type HttpMethod = "get" | "post" | "patch" | "put" | "delete";
|
||||
|
||||
/**
|
||||
* 鉴权方式(不写即按 scope 校验,cookie 会话与 API Key 同样适用):
|
||||
* - public:免鉴权(必须与服务端 http/auth.ts 的 PUBLIC_AUTH_PATHS 一致,测试断言);
|
||||
* - session:只接受控制台管理员 cookie 会话,API Key(含 admin scope)一律 403。
|
||||
*/
|
||||
export type EndpointAuth = "public" | "session";
|
||||
|
||||
export interface EndpointDef {
|
||||
method: HttpMethod;
|
||||
path: string;
|
||||
scope: ApiScope;
|
||||
auth?: EndpointAuth;
|
||||
summary: string;
|
||||
params?: z.ZodObject;
|
||||
query?: z.ZodType;
|
||||
body?: z.ZodType;
|
||||
response: z.ZodType;
|
||||
}
|
||||
|
||||
export const ep = <E extends EndpointDef>(e: E): E => e;
|
||||
|
||||
/** 列表查询:游标分页 + 资源自有过滤 */
|
||||
export const listQuery = <S extends z.ZodRawShape>(filters: S) => CursorQuery.extend(filters);
|
||||
|
||||
/** 删除/无内容动作的响应 */
|
||||
export const OkResult = z.object({ ok: z.literal(true) });
|
||||
|
||||
export interface CrudSchemas {
|
||||
row: z.ZodType;
|
||||
create?: z.ZodType;
|
||||
update?: z.ZodType;
|
||||
filters?: z.ZodRawShape;
|
||||
}
|
||||
|
||||
/** 标准资源端点:list / get / create / update / remove(按给出的 schema 决定是否生成) */
|
||||
export function crud<const B extends string>(
|
||||
base: B,
|
||||
name: string,
|
||||
s: CrudSchemas,
|
||||
scopes: { read: ApiScope; write: ApiScope },
|
||||
) {
|
||||
const item = `${base}/{id}` as const;
|
||||
return {
|
||||
list: ep({
|
||||
method: "get",
|
||||
path: base,
|
||||
scope: scopes.read,
|
||||
summary: `${name}列表`,
|
||||
query: listQuery(s.filters ?? {}),
|
||||
response: cursorPage(s.row),
|
||||
}),
|
||||
get: ep({
|
||||
method: "get",
|
||||
path: item,
|
||||
scope: scopes.read,
|
||||
summary: `${name}详情`,
|
||||
params: IdParam,
|
||||
response: s.row,
|
||||
}),
|
||||
...(s.create
|
||||
? {
|
||||
create: ep({
|
||||
method: "post",
|
||||
path: base,
|
||||
scope: scopes.write,
|
||||
summary: `新建${name}`,
|
||||
body: s.create,
|
||||
response: s.row,
|
||||
}),
|
||||
}
|
||||
: {}),
|
||||
...(s.update
|
||||
? {
|
||||
update: ep({
|
||||
method: "patch",
|
||||
path: item,
|
||||
scope: scopes.write,
|
||||
summary: `修改${name}`,
|
||||
params: IdParam,
|
||||
body: s.update,
|
||||
response: s.row,
|
||||
}),
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
|
||||
export const R = { read: "read", write: "admin" } as const;
|
||||
|
||||
export const del = (path: string, summary: string) =>
|
||||
ep({ method: "delete", path, scope: "admin", summary, params: IdParam, response: OkResult });
|
||||
|
||||
/** 实例连通性测试 */
|
||||
export const instanceTest = (path: string, summary: string) =>
|
||||
ep({ method: "post", path, scope: "admin", summary, params: IdParam, response: instances.InstanceTestResult });
|
||||
|
||||
/** 入队后台任务的受理结果(taskId = 引擎 run id) */
|
||||
export const TaskAccepted = z.object({ taskId: Id });
|
||||
export type TaskAccepted = z.infer<typeof TaskAccepted>;
|
||||
|
||||
/** 人工指定来源资源身份的结果(待识别池 assign / source-releases identity) */
|
||||
export const ReleaseIdentityResult = z.object({ mediaEntityId: Id, contentUnitIds: z.array(Id) });
|
||||
export type ReleaseIdentityResult = z.infer<typeof ReleaseIdentityResult>;
|
||||
|
||||
/** 身份修订历史 */
|
||||
export const IdentityRevisionList = z.object({ items: z.array(identity.IdentityRevision) });
|
||||
export type IdentityRevisionList = z.infer<typeof IdentityRevisionList>;
|
||||
|
||||
/** 字段覆盖/取消覆盖的结果 */
|
||||
export const FieldOverrideResult = z.object({
|
||||
mediaEntityId: Id,
|
||||
changedFields: z.array(z.string()),
|
||||
lockedFields: z.array(z.string()),
|
||||
});
|
||||
export const FieldParam = z.object({ id: Id, field: content.EntityMetadataField });
|
||||
export const UnitFieldParam = z.object({ id: Id, field: content.UnitMetadataField });
|
||||
export const UnitFieldOverrideResult = z.object({
|
||||
contentUnitId: Id,
|
||||
changedFields: z.array(z.string()),
|
||||
lockedFields: z.array(z.string()),
|
||||
});
|
||||
|
||||
/** 引擎 run id 不是 uuid(openworkflow 自有 id) */
|
||||
export const EngineRunIdParam = z.object({ id: z.string().min(1).max(200) });
|
||||
|
||||
/** 待处理事项聚合分组 */
|
||||
export const DecisionSummaryGroup = z.object({
|
||||
kind: agent.DecisionKind,
|
||||
mediaEntityId: Id.nullable(),
|
||||
mediaEntityTitle: z.string().nullable(),
|
||||
count: z.number().int(),
|
||||
maxSeverity: z.enum(["info", "warning", "critical"]),
|
||||
latestAt: z.string(),
|
||||
});
|
||||
export type DecisionSummaryGroup = z.infer<typeof DecisionSummaryGroup>;
|
||||
export const DecisionSummary = z.object({ total: z.number().int(), groups: z.array(DecisionSummaryGroup) });
|
||||
export type DecisionSummary = z.infer<typeof DecisionSummary>;
|
||||
Reference in new issue
Block a user