feat(api): A4 数据字典与系统配置后端
背景:A4 需要字典三层合并、配置单一来源与阈值同源。\n改动:新增 catalog 模块(类型/条目/三层合并/编码不可改/快照工具);platform 新增 SystemConfigService/Controller、NamingService 与配置版本历史;roles/users/customers/customer-fields 改为读 system_configs 上限。\n影响面:新增 13 个 REST 端点与 4 个模块注入;system_configs 写入走事务/乐观锁/版本历史;OpenAPI 快照更新。\n回滚:回滚本提交并恢复 shared 契约;新增表可保留。\n验证:api typecheck/build;单测 137;集成 58;OpenAPI diff 无破坏性变更。
This commit is contained in:
1 parent
cc6e84cdbc
commit
e4330a43e4
25 files changed
+4189
-30
No files matched your search
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 系统配置 Prisma 行 -> 共享 DTO 映射(A4-BE-02)。
|
||||
*
|
||||
* 元数据(标签 / 说明 / 影响面 / 类型 / 上下限 / 是否公开)唯一来源是
|
||||
* `SYSTEM_CONFIG_DEFINITIONS`;`system_configs` 只提供当前值与版本。
|
||||
* DB 缺行时用定义默认值 + version 1 兜底,不写库。
|
||||
*/
|
||||
import {
|
||||
type SystemConfig,
|
||||
type SystemConfigChange,
|
||||
type SystemConfigDefinition,
|
||||
type SystemConfigValue,
|
||||
systemConfigValueType,
|
||||
} from '@lingxi/shared';
|
||||
import type { Prisma } from '@prisma/client';
|
||||
import type {
|
||||
SystemConfig as PrismaSystemConfig,
|
||||
SystemConfigVersion as PrismaSystemConfigVersion,
|
||||
} from '@prisma/client';
|
||||
|
||||
/** 从未落库的配置:用 epoch 表示「未更新过」,避免伪造读取时间 */
|
||||
const NEVER_UPDATED_AT = new Date(0).toISOString();
|
||||
|
||||
/** Prisma JsonB 只应存原始值;异常结构回退配置默认值,避免脏数据打穿前端 schema */
|
||||
export function normalizeConfigValue(
|
||||
raw: Prisma.JsonValue | undefined,
|
||||
fallback: SystemConfigValue,
|
||||
): SystemConfigValue {
|
||||
if (typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean') {
|
||||
return raw;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
export function toSystemConfig(
|
||||
definition: SystemConfigDefinition,
|
||||
row: PrismaSystemConfig | undefined,
|
||||
updatedByName?: string | null,
|
||||
): SystemConfig {
|
||||
return {
|
||||
key: definition.key,
|
||||
group: definition.group,
|
||||
label: definition.label,
|
||||
description: definition.description,
|
||||
impact: definition.impact,
|
||||
type: definition.type,
|
||||
value: normalizeConfigValue(row?.configValue, definition.defaultValue),
|
||||
valueType: systemConfigValueType(definition),
|
||||
unit: definition.unit ?? null,
|
||||
version: row?.version ?? 1,
|
||||
updatedAt: row === undefined ? NEVER_UPDATED_AT : row.updatedAt.toISOString(),
|
||||
updatedBy: updatedByName ?? row?.updatedBy ?? null,
|
||||
editable: definition.editable,
|
||||
isPublic: definition.public,
|
||||
min: definition.min ?? null,
|
||||
max: definition.max ?? null,
|
||||
step: definition.step ?? null,
|
||||
maxLength: definition.maxLength ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
export function toSystemConfigChange(
|
||||
row: PrismaSystemConfigVersion,
|
||||
label: string,
|
||||
operator: string | null,
|
||||
): SystemConfigChange {
|
||||
return {
|
||||
key: row.configKey,
|
||||
label,
|
||||
version: row.version,
|
||||
oldValue: row.oldValue,
|
||||
newValue: row.newValue,
|
||||
reason: row.reason,
|
||||
operator,
|
||||
changedAt: row.changedAt.toISOString(),
|
||||
result: '已生效',
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user