Files
cloudflare-domain-manager/apps/api/src/routes/domains.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

106 lines
3.4 KiB
TypeScript

import type { FastifyInstance } from "fastify";
import { bulkUpdateDomainsSchema, updateDomainSchema } from "@cfdm/shared";
import { z } from "zod";
import * as domainService from "../services/domain-service.js";
import { recordAudit } from "../lib/audit.js";
export async function domainRoutes(app: FastifyInstance) {
const createSchema = z.object({
zone_name: z.string(),
group_id: z.number().nullable().optional(),
});
app.get("/domains", async (request) => {
const query = request.query as { group_id?: string };
const groupId = query.group_id ? Number(query.group_id) : undefined;
return domainService.listDomains(request.server.db, groupId);
});
app.post("/domains", async (request) => {
const body = createSchema.parse(request.body);
const domain = await domainService.createDomain(
request.server.db,
request.server.cf,
body.group_id ?? null,
body.zone_name,
);
recordAudit(request.server, request, {
action: "domain.create",
targetType: "app_resource",
targetId: String(domain.id),
summary: `Добавлен домен ${domain.zone_name}`,
details: { zone_name: domain.zone_name, group_id: domain.group_id },
});
return domain;
});
app.post("/domains/bulk", async (request) => {
const body = bulkUpdateDomainsSchema.parse(request.body);
const updated = domainService.bulkUpdateDomains(
request.server.db,
body.ids,
{
group_id: body.group_id,
environment: body.environment,
tags_add: body.tags_add,
},
);
return { updated };
});
app.get("/domains/:id", async (request) => {
const { id } = request.params as { id: string };
return domainService.getDomain(request.server.db, Number(id));
});
app.patch("/domains/:id", async (request) => {
const { id } = request.params as { id: string };
const body = updateDomainSchema.parse(request.body);
const domain = domainService.updateDomain(request.server.db, Number(id), body);
recordAudit(request.server, request, {
action: "domain.update",
targetType: "app_resource",
targetId: String(domain.id),
summary: `Обновлён домен ${domain.zone_name}`,
details: body,
});
return domain;
});
app.delete("/domains/:id", async (request) => {
const { id } = request.params as { id: string };
const domain = domainService.getDomain(request.server.db, Number(id));
domainService.deleteDomain(request.server.db, Number(id));
recordAudit(request.server, request, {
action: "domain.delete",
severity: "warning",
targetType: "app_resource",
targetId: String(id),
summary: `Удалён домен ${domain.zone_name}`,
details: { zone_name: domain.zone_name },
});
return { deleted: true };
});
app.post("/domains/:id/import", async (request) => {
const { id } = request.params as { id: string };
const imported = await domainService.importZoneRecords(
request.server.db,
request.server.cf,
Number(id),
);
return { imported };
});
app.put("/domains/:id/services", async (request) => {
const { id } = request.params as { id: string };
const body = z.object({ service_ids: z.array(z.number()) }).parse(request.body);
const serviceIds = await domainService.setDomainServices(
request.server.db,
Number(id),
body.service_ids,
);
return { service_ids: serviceIds };
});
}