feat: M4-07 — Hermes Agent task/artifact management with approval workflow
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 40s

- Add AgentTask and AgentArtifact Prisma models
- HermesAgentController: list tasks, approve/reject, list artifacts
- AAPI: GET /admin-api/hermes/tasks, POST approve/reject, GET /admin-api/hermes/artifacts

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
WangDL 2026-05-24 18:10:37 +08:00
parent 8abf94872a
commit 5d84769ac0
4 changed files with 91 additions and 0 deletions

View File

@ -1409,3 +1409,36 @@ model ExportJob {
errorMessage String? @db.Text
createdAt DateTime @default(now())
}
model AgentTask {
id String @id @default(cuid())
userId String?
type String @db.VarChar(32)
status String @default("pending") @db.VarChar(16)
input String? @db.Text
output String? @db.Text
sessionId String? @db.VarChar(255)
approvedBy String?
approvedAt DateTime?
giteaUrl String? @db.VarChar(500)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([status])
@@index([userId])
}
model AgentArtifact {
id String @id @default(cuid())
taskId String?
type String @db.VarChar(32)
title String @db.VarChar(255)
content String? @db.Text
status String @default("draft") @db.VarChar(16)
createdBy String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([taskId])
@@index([type])
}

View File

@ -55,6 +55,7 @@ import { AdminCacheModule } from './modules/admin-cache/admin-cache.module';
import { BackupModule } from './modules/backup/backup.module';
import { ReportingModule } from './modules/reporting/reporting.module';
import { ProjectCenterModule } from './modules/project-center/project-center.module';
import { HermesAgentModule } from './modules/hermes-agent/hermes-agent.module';
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
import { RolesGuard } from './common/guards/roles.guard';
@ -155,6 +156,7 @@ import appleConfig from './config/apple.config';
BackupModule,
ReportingModule,
ProjectCenterModule,
HermesAgentModule,
],
providers: [
{ provide: APP_GUARD, useClass: RateLimitGuard },

View File

@ -0,0 +1,49 @@
import { Controller, Get, Post, Param, Body, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery, 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-hermes')
@ApiBearerAuth()
@Controller('admin-api/hermes')
@UseGuards(AdminAuthGuard, AdminRolesGuard)
export class HermesAgentController {
constructor(private readonly prisma: PrismaService) {}
@Get('tasks')
@ApiOperation({ summary: 'Agent 任务列表' })
@ApiQuery({ name: 'status', required: false })
async listTasks(@Query('status') status?: string) {
const where: any = {};
if (status) where.status = status;
return this.prisma.agentTask.findMany({ where, orderBy: { createdAt: 'desc' }, take: 100 });
}
@Post('tasks/:id/approve')
@ApiOperation({ summary: '审批通过 Agent 任务' })
async approveTask(@Param('id') id: string) {
return this.prisma.agentTask.update({
where: { id },
data: { status: 'approved', approvedAt: new Date() },
});
}
@Post('tasks/:id/reject')
@ApiOperation({ summary: '驳回 Agent 任务' })
async rejectTask(@Param('id') id: string) {
return this.prisma.agentTask.update({
where: { id },
data: { status: 'rejected' },
});
}
@Get('artifacts')
@ApiOperation({ summary: 'Agent 产出物列表' })
@ApiQuery({ name: 'type', required: false })
async listArtifacts(@Query('type') type?: string) {
const where: any = {};
if (type) where.type = type;
return this.prisma.agentArtifact.findMany({ where, orderBy: { createdAt: 'desc' }, take: 100 });
}
}

View File

@ -0,0 +1,7 @@
import { Module } from '@nestjs/common';
import { HermesAgentController } from './hermes-agent.controller';
@Module({
controllers: [HermesAgentController],
})
export class HermesAgentModule {}