feat(api): 搭建 API 与 Worker 骨架及契约基线

NestJS 11 + Fastify 统一错误体与 trace_id,/health 真实探活 DB/Redis,OpenAPI 3.1 契约含 20 个错误码;shared 包提供错误码、权限点、ULID、分页与通用 schema;worker 完成队列进程骨架。
This commit is contained in:
Stev_Wang committed 2026-11-02 17:20:46 +08:00
1 parent 09dbb27b66
commit 23067edb8f
70 files changed
+2445

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
/**
* 权限点常量骨架(A0-SH-01)
* 命名规范:<模块>:<动作>,模块取后端八模块语义(identity / client / catalog / industry /
* script / media / delivery / platform),全小写;动作使用动词或名词短语。
* A1/A2 接入真实角色-权限表后,这里只增不改;删除/改名需评审(AGENTS §10)。
*/
export const Permission = {
// 脚本
SCRIPT_READ: 'script:read',
SCRIPT_WRITE: 'script:write',
SCRIPT_REVIEW: 'script:review',
// 素材
MATERIAL_READ: 'material:read',
MATERIAL_WRITE: 'material:write',
MATERIAL_RENDER: 'material:render',
MATERIAL_REVIEW: 'material:review',
// 资产
ASSET_READ: 'asset:read',
ASSET_WRITE: 'asset:write',
// 导出交付
DELIVERY_READ: 'delivery:read',
DELIVERY_EXPORT: 'delivery:export',
// 客户
CUSTOMER_READ: 'customer:read',
CUSTOMER_MANAGE: 'customer:manage',
CUSTOMER_FIELD_APPROVE: 'customer_field:approve',
// 组织与角色
USER_MANAGE: 'user:manage',
ROLE_MANAGE: 'role:manage',
// 平台配置
INDUSTRY_MANAGE: 'industry:manage',
INDUSTRY_PUBLISH: 'industry:publish',
DICT_MANAGE: 'dict:manage',
FORM_DESIGN: 'form:design',
AI_CONFIGURE: 'ai:configure',
SYSTEM_CONFIGURE: 'system:configure',
// 审计
AUDIT_READ: 'audit:read',
AUDIT_EXPORT: 'audit:export',
} as const;
export type PermissionCode = (typeof Permission)[keyof typeof Permission];
export const PERMISSION_CODES: readonly PermissionCode[] = Object.values(Permission);
/** 需要额外单独校验的特殊权限(技术架构 §6.2「关键特殊权限」) */
export const SPECIAL_PERMISSIONS: readonly PermissionCode[] = [
Permission.DELIVERY_EXPORT,
Permission.AI_CONFIGURE,
Permission.AUDIT_EXPORT,
Permission.INDUSTRY_PUBLISH,
Permission.CUSTOMER_FIELD_APPROVE,
];
const PERMISSION_CODE_SET: ReadonlySet<string> = new Set(PERMISSION_CODES);
export function isPermissionCode(value: string): value is PermissionCode {
return PERMISSION_CODE_SET.has(value);
}
export interface ParsedPermission {
module: string;
action: string;
}
/** 拆分权限点为 { module, action };格式不合法返回 null */
export function parsePermission(code: string): ParsedPermission | null {
const separator = code.indexOf(':');
if (separator <= 0 || separator === code.length - 1) {
return null;
}
const module = code.slice(0, separator);
const action = code.slice(separator + 1);
if (module.includes(':') || action.includes(':')) {
return null;
}
return { module, action };
}