Files
cloudflare-domain-manager/apps/api/src/routes/groups.ts
T
DenozordecandCursor 859ad23006
Build and Push CFDM Docker Image / build-and-push (push) Successful in 2m9s
Build and Push CFDM Docker Image / create-release (push) Skipped
Build and Push CFDM Docker Image / update-wiki (push) Successful in 5s
feat(audit): локальный журнал и push в auth-portal
Таблица audit_log, recordAudit на CRUD, GET /api/v1/audit и dual-write source_app=cfdm.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 13:24:32 +07:00

69 lines
2.2 KiB
TypeScript

import type { FastifyInstance } from "fastify";
import { z } from "zod";
import { repos } from "@cfdm/db";
import * as groupService from "../services/group-service.js";
import { recordAudit } from "../lib/audit.js";
export async function groupRoutes(app: FastifyInstance) {
const bodySchema = z.object({
name: z.string(),
slug: z.string(),
});
app.get("/groups", async (request) => {
return groupService.listGroups(request.server.db);
});
app.post("/groups", async (request) => {
const body = bodySchema.parse(request.body);
const group = groupService.createGroup(request.server.db, body.name, body.slug);
recordAudit(request.server, request, {
action: "group.create",
targetType: "app_resource",
targetId: String(group.id),
summary: `Создана группа «${group.name}»`,
details: { name: group.name, slug: group.slug },
});
return group;
});
app.get("/groups/:id", async (request) => {
const { id } = request.params as { id: string };
return groupService.getGroupWithStats(request.server.db, Number(id));
});
app.patch("/groups/:id", async (request) => {
const { id } = request.params as { id: string };
const body = bodySchema.parse(request.body);
const group = groupService.updateGroup(
request.server.db,
Number(id),
body.name,
body.slug,
);
recordAudit(request.server, request, {
action: "group.update",
targetType: "app_resource",
targetId: String(group.id),
summary: `Обновлена группа «${group.name}»`,
details: { name: group.name, slug: group.slug },
});
return group;
});
app.delete("/groups/:id", async (request) => {
const { id } = request.params as { id: string };
const group = repos.getGroup(request.server.db, Number(id));
groupService.deleteGroup(request.server.db, Number(id));
recordAudit(request.server, request, {
action: "group.delete",
severity: "warning",
targetType: "app_resource",
targetId: String(id),
summary: `Удалена группа «${group.name}»`,
details: { name: group.name, slug: group.slug },
});
return { deleted: true };
});
}