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:
Stev_Wang committed 2026-11-04 11:49:05 +08:00
1 parent cc6e84cdbc
commit e4330a43e4
25 files changed
+4189 -30

No files matched your search

+12 -5
View File
@@ -28,6 +28,7 @@ import { AppException } from '../../common/errors/app-exception';
import { RequestContextService } from '../../common/security/request-context';
import type { PrismaService } from '../../infra/prisma/prisma.service';
import { PRISMA } from '../../infra/tokens';
import { SystemConfigService } from '../platform/system-config/system-config.service';
import { iso, maskPhone } from './user.mapper';
const ROLE_LIST_INCLUDE = {
@@ -238,6 +239,7 @@ export class RolesService {
constructor(
@Inject(PRISMA) private readonly prisma: PrismaService,
@Inject(RequestContextService) private readonly requestContext: RequestContextService,
@Inject(SystemConfigService) private readonly systemConfig: SystemConfigService,
) {}
async list(query: RoleListQuery): Promise<ListResponse<RoleListItem>> {
@@ -694,22 +696,27 @@ export class RolesService {
}
}
/** 软提示(不阻断):角色数量 / 超管人数超过 PRD 建议值;A4 迁 system_configs */
/** 软提示(不阻断):角色 / 超管人数超过建议值;阈值读 system_configs(R-26),常量仅作读失败兜底 */
private async buildWarnings(roleCode: string): Promise<string[]> {
const warnings: string[] = [];
const roleSoftLimit = await this.systemConfig.getNumber('limit.role.max', ROLE_SOFT_LIMIT);
const activeRoleCount = await this.prisma.role.count({ where: { status: 'ACTIVE' } });
if (activeRoleCount > ROLE_SOFT_LIMIT) {
if (activeRoleCount > roleSoftLimit) {
warnings.push(
`启用角色数 ${String(activeRoleCount)} 已超过建议上限 ${String(ROLE_SOFT_LIMIT)},建议合并角色`,
`启用角色数 ${String(activeRoleCount)} 已超过建议上限 ${String(roleSoftLimit)},建议合并角色`,
);
}
if (roleCode === 'super_admin') {
const superAdminSoftLimit = await this.systemConfig.getNumber(
'limit.super_admin.max',
SUPER_ADMIN_SOFT_LIMIT,
);
const superAdminCount = await this.prisma.user.count({
where: { status: 'ACTIVE', roles: { some: { role: { code: 'super_admin' } } } },
});
if (superAdminCount > SUPER_ADMIN_SOFT_LIMIT) {
if (superAdminCount > superAdminSoftLimit) {
warnings.push(
`超级管理员 ${String(superAdminCount)} 人已超过建议上限 ${String(SUPER_ADMIN_SOFT_LIMIT)} 人`,
`超级管理员 ${String(superAdminCount)} 人已超过建议上限 ${String(superAdminSoftLimit)} 人`,
);
}
}