feat: harden platform workflows and UI governance

This commit is contained in:
hectorzhao
2026-07-22 14:14:55 +08:00
parent ef957f7daa
commit 0f223f7f91
80 changed files with 4958 additions and 764 deletions
@@ -1,3 +1,4 @@
import { ConflictException } from '@nestjs/common';
import { DictionariesService } from './dictionaries.service';
function createPrismaMock() {
@@ -173,6 +174,22 @@ describe('DictionariesService', () => {
expect(prisma.enterpriseBlacklist.update).toHaveBeenCalledWith({ where: { id: 'enterprise-1' }, data: { status: 'deleted' } });
});
it.each([
['global', 'globalBlacklist', 'createGlobalBlacklist', { phoneNumber: '13800000000', reason: '投诉' }],
['enterprise', 'enterpriseBlacklist', 'createEnterpriseBlacklist', {
tenantId: 'tenant-1', applicationId: 'app-1', phoneNumber: '13900000000', reason: '退订',
}],
] as const)('maps a duplicate %s blacklist entry, including a soft-deleted row, to HTTP 409', async (_scope, model, method, input) => {
const prisma = createPrismaMock();
prisma[model].create.mockRejectedValue({ code: 'P2002', meta: { target: ['phoneNumber'] } });
const service = new DictionariesService(prisma as never);
await expect(service[method](input as never)).rejects.toBeInstanceOf(ConflictException);
await expect(service[method](input as never)).rejects.toMatchObject({
response: expect.objectContaining({ code: 'BLACKLIST_DUPLICATE', field: 'phoneNumber' }),
});
});
it('only accepts string, image and file report field types', async () => {
const prisma = createPrismaMock();
const service = new DictionariesService(prisma as never);