- Monorepo: NestJS API (Fastify) + React web (antd/ProComponents) + shared packages - PostgreSQL/Prisma (unified resources, relations graph, audit, events, jobs) - Auth/RBAC/workspace isolation, credential vault (AES-256-GCM) - Servers/SSH, Docker discovery & lifecycle, Job Center - Websites & deployments (git provider credential clone, env, health verification) - Domains/DNS (Cloudflare adapter), certificates (TLS probe), monitoring - Automation (cron/event/webhook HMAC + notifications), AI Gateway, MCP (29 tools) - AI chat window (LLM function-calling + rules fallback, SSE streaming, approvals) - Notes: Vditor WYSIWYG markdown editor, non-blocking autosave - Tests: 35 unit/security tests; UI audit clean (desktop+mobile, deep links)
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
/**
|
|
* # 事件查询控制器
|
|
*/
|
|
import { Controller, Get, Query } from "@nestjs/common";
|
|
import { z } from "zod";
|
|
import { ZodValidationPipe } from "../../common/pipes/zod-validation.pipe";
|
|
import { CurrentWorkspace } from "../../common/decorators";
|
|
import { PrismaService } from "../../prisma/prisma.service";
|
|
import type { RequestWorkspace } from "../../common/decorators";
|
|
|
|
const ListQuerySchema = z.object({
|
|
page: z.coerce.number().int().min(1).default(1),
|
|
pageSize: z.coerce.number().int().min(1).max(100).default(20),
|
|
eventType: z.string().optional(),
|
|
});
|
|
|
|
@Controller("events")
|
|
export class EventController {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
/** # 分页查询当前工作区领域事件 */
|
|
@Get()
|
|
async list(
|
|
@CurrentWorkspace() workspace: RequestWorkspace,
|
|
@Query(new ZodValidationPipe(ListQuerySchema)) query: z.infer<typeof ListQuerySchema>,
|
|
) {
|
|
const where = {
|
|
workspaceId: workspace.id,
|
|
...(query.eventType ? { eventType: query.eventType } : {}),
|
|
};
|
|
const [total, items] = await this.prisma.$transaction([
|
|
this.prisma.eventRecord.count({ where }),
|
|
this.prisma.eventRecord.findMany({
|
|
where,
|
|
orderBy: { createdAt: "desc" },
|
|
skip: (query.page - 1) * query.pageSize,
|
|
take: query.pageSize,
|
|
}),
|
|
]);
|
|
return { items, total, page: query.page, pageSize: query.pageSize };
|
|
}
|
|
}
|