80 lines
2.6 KiB
TypeScript
80 lines
2.6 KiB
TypeScript
import { Router } from "express";
|
|
import { ok } from "../../lib/api-response.js";
|
|
import { getSingleParam } from "../../lib/http.js";
|
|
import { requireTableAccess } from "../../middleware/permission.js";
|
|
import { validateBody } from "../../middleware/validate.js";
|
|
import { createAuditEvent } from "../audit/audit.service.js";
|
|
import { addColumn, dropColumn, ensureSchemaMutationsEnabled, updateColumn } from "./schema.service.js";
|
|
import { createColumnSchema, updateColumnSchema } from "./schema.schemas.js";
|
|
|
|
export const schemaRouter = Router({ mergeParams: true });
|
|
|
|
schemaRouter.post("/", requireTableAccess("schema_change"), validateBody(createColumnSchema), async (req, res, next) => {
|
|
try {
|
|
const tableName = getSingleParam(req.params.table);
|
|
await ensureSchemaMutationsEnabled();
|
|
await addColumn(tableName, req.body);
|
|
await createAuditEvent({
|
|
actorUserId: req.user?.id ?? null,
|
|
action: "schema.column.create",
|
|
resourceType: "table",
|
|
resourceName: tableName,
|
|
payloadAfter: req.body,
|
|
ip: req.ip,
|
|
userAgent: req.headers["user-agent"] ?? null,
|
|
status: "success"
|
|
});
|
|
res.status(201).json(ok({ created: true }));
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
schemaRouter.put(
|
|
"/:column",
|
|
requireTableAccess("schema_change"),
|
|
validateBody(updateColumnSchema),
|
|
async (req, res, next) => {
|
|
try {
|
|
const tableName = getSingleParam(req.params.table);
|
|
const columnName = getSingleParam(req.params.column);
|
|
await ensureSchemaMutationsEnabled();
|
|
await updateColumn(tableName, columnName, req.body);
|
|
await createAuditEvent({
|
|
actorUserId: req.user?.id ?? null,
|
|
action: "schema.column.update",
|
|
resourceType: "table",
|
|
resourceName: `${tableName}.${columnName}`,
|
|
payloadAfter: req.body,
|
|
ip: req.ip,
|
|
userAgent: req.headers["user-agent"] ?? null,
|
|
status: "success"
|
|
});
|
|
res.json(ok({ updated: true }));
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
);
|
|
|
|
schemaRouter.delete("/:column", requireTableAccess("schema_change"), async (req, res, next) => {
|
|
try {
|
|
const tableName = getSingleParam(req.params.table);
|
|
const columnName = getSingleParam(req.params.column);
|
|
await ensureSchemaMutationsEnabled();
|
|
await dropColumn(tableName, columnName);
|
|
await createAuditEvent({
|
|
actorUserId: req.user?.id ?? null,
|
|
action: "schema.column.delete",
|
|
resourceType: "table",
|
|
resourceName: `${tableName}.${columnName}`,
|
|
ip: req.ip,
|
|
userAgent: req.headers["user-agent"] ?? null,
|
|
status: "success"
|
|
});
|
|
res.json(ok({ deleted: true }));
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|