feat: M4-10 — admin notification deepening (cost alerts, import failures, key expirations)
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 41s
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 41s
- Add scope field to Notification model (user/admin) - AdminNotificationsController: list, send, mark read - Generate endpoints: cost-alert, import-failure, key-expiring Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c4089129c0
commit
b3176b8ead
@ -586,6 +586,7 @@ model Notification {
|
|||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
content String? @db.Text
|
content String? @db.Text
|
||||||
data Json?
|
data Json?
|
||||||
|
scope String @default("user") @db.VarChar(16)
|
||||||
readAt DateTime?
|
readAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import { ProjectCenterModule } from './modules/project-center/project-center.mod
|
|||||||
import { HermesAgentModule } from './modules/hermes-agent/hermes-agent.module';
|
import { HermesAgentModule } from './modules/hermes-agent/hermes-agent.module';
|
||||||
import { ReleaseModule } from './modules/release/release.module';
|
import { ReleaseModule } from './modules/release/release.module';
|
||||||
import { ComplianceModule } from './modules/compliance/compliance.module';
|
import { ComplianceModule } from './modules/compliance/compliance.module';
|
||||||
|
import { AdminNotificationsModule } from './modules/admin-notifications/admin-notifications.module';
|
||||||
|
|
||||||
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
|
||||||
import { RolesGuard } from './common/guards/roles.guard';
|
import { RolesGuard } from './common/guards/roles.guard';
|
||||||
@ -161,6 +162,7 @@ import appleConfig from './config/apple.config';
|
|||||||
HermesAgentModule,
|
HermesAgentModule,
|
||||||
ReleaseModule,
|
ReleaseModule,
|
||||||
ComplianceModule,
|
ComplianceModule,
|
||||||
|
AdminNotificationsModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: APP_GUARD, useClass: RateLimitGuard },
|
{ provide: APP_GUARD, useClass: RateLimitGuard },
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
import { Controller, Get, Post, Patch, Param, Body, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiTags, ApiBearerAuth, ApiOperation, ApiBody } from '@nestjs/swagger';
|
||||||
|
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
||||||
|
import { AdminAuthGuard } from '../../common/guards/admin-auth.guard';
|
||||||
|
import { AdminRolesGuard } from '../../common/guards/admin-roles.guard';
|
||||||
|
|
||||||
|
@ApiTags('admin-notifications-v2')
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@Controller('admin-api/admin-notifications')
|
||||||
|
@UseGuards(AdminAuthGuard, AdminRolesGuard)
|
||||||
|
export class AdminNotificationsController {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: 'Admin 通知列表' })
|
||||||
|
async list() {
|
||||||
|
return this.prisma.notification.findMany({
|
||||||
|
where: { scope: 'admin' },
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
take: 100,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('send')
|
||||||
|
@ApiOperation({ summary: '发送 Admin 通知' })
|
||||||
|
@ApiBody({ schema: { type: 'object', required: ['title', 'type'], properties: {
|
||||||
|
title: { type: 'string' }, type: { type: 'string' }, content: { type: 'string' }, data: { type: 'object' },
|
||||||
|
} } })
|
||||||
|
async send(@Body() dto: { title: string; type: string; content?: string; data?: any }) {
|
||||||
|
return this.prisma.notification.create({
|
||||||
|
data: {
|
||||||
|
userId: 'admin',
|
||||||
|
type: dto.type,
|
||||||
|
title: dto.title,
|
||||||
|
content: dto.content || '',
|
||||||
|
data: dto.data || null,
|
||||||
|
scope: 'admin',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post(':id/read')
|
||||||
|
@ApiOperation({ summary: '标记 Admin 通知已读' })
|
||||||
|
async markRead(@Param('id') id: string) {
|
||||||
|
return this.prisma.notification.update({ where: { id }, data: { readAt: new Date() } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// ═══ Predefined admin notification generators ═══
|
||||||
|
|
||||||
|
@Post('generate/cost-alert')
|
||||||
|
@ApiOperation({ summary: '生成成本预警通知' })
|
||||||
|
async generateCostAlert(@Body() dto: { cost: number; threshold: number; period: string }) {
|
||||||
|
return this.prisma.notification.create({
|
||||||
|
data: {
|
||||||
|
userId: 'admin', type: 'cost_alert', scope: 'admin',
|
||||||
|
title: `成本预警:${dto.period}成本 ¥${dto.cost} 超过阈值 ¥${dto.threshold}`,
|
||||||
|
content: `${dto.period} AI 调用成本已达到 ¥${dto.cost},超过预设阈值 ¥${dto.threshold}。`,
|
||||||
|
data: dto,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('generate/import-failure')
|
||||||
|
@ApiOperation({ summary: '生成导入失败通知' })
|
||||||
|
async generateImportFailure(@Body() dto: { importId: string; failedCount: number; totalCount: number }) {
|
||||||
|
return this.prisma.notification.create({
|
||||||
|
data: {
|
||||||
|
userId: 'admin', type: 'import_failure', scope: 'admin',
|
||||||
|
title: `导入任务大量失败:${dto.failedCount}/${dto.totalCount}`,
|
||||||
|
content: `导入任务 ${dto.importId} 中 ${dto.failedCount}/${dto.totalCount} 项失败。`,
|
||||||
|
data: dto,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('generate/key-expiring')
|
||||||
|
@ApiOperation({ summary: '生成 API Key 到期通知' })
|
||||||
|
async generateKeyExpiring(@Body() dto: { keyName: string; expiresInDays: number }) {
|
||||||
|
return this.prisma.notification.create({
|
||||||
|
data: {
|
||||||
|
userId: 'admin', type: 'key_expiring', scope: 'admin',
|
||||||
|
title: `API Key「${dto.keyName}」即将在 ${dto.expiresInDays} 天后到期`,
|
||||||
|
content: `请尽快续期或更换密钥。`,
|
||||||
|
data: dto,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { AdminNotificationsController } from './admin-notifications.controller';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [AdminNotificationsController],
|
||||||
|
})
|
||||||
|
export class AdminNotificationsModule {}
|
||||||
Loading…
x
Reference in New Issue
Block a user