feat(plan): add plan category CRUD routes with audit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,16 @@ import {
|
||||
listEntries,
|
||||
listOverrides,
|
||||
} from "../../services/plan.service";
|
||||
import {
|
||||
CreatePlanCategorySchema,
|
||||
UpdatePlanCategorySchema,
|
||||
} from "../../schemas/planCategory.schema";
|
||||
import {
|
||||
listPlanCategories,
|
||||
createPlanCategory,
|
||||
updatePlanCategory,
|
||||
deactivatePlanCategory,
|
||||
} from "../../services/planCategory.service";
|
||||
|
||||
const MAX_RANGE_DAYS = 92;
|
||||
|
||||
@@ -135,6 +145,88 @@ export default async function planRoutes(app: FastifyInstance) {
|
||||
},
|
||||
);
|
||||
|
||||
// --- GET /plan/categories (any planner can read; needed for display) ---
|
||||
app.get(
|
||||
"/categories",
|
||||
{
|
||||
preHandler: requireAnyPermission(
|
||||
"attendance.manage",
|
||||
"attendance.record",
|
||||
),
|
||||
},
|
||||
async (_request: FastifyRequest, reply: FastifyReply) => {
|
||||
const cats = await listPlanCategories(true);
|
||||
return success(reply, cats);
|
||||
},
|
||||
);
|
||||
|
||||
// --- POST /plan/categories ---
|
||||
app.post(
|
||||
"/categories",
|
||||
{ preHandler: requirePermission("attendance.manage") },
|
||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
const body = parseBody(CreatePlanCategorySchema, request.body);
|
||||
if ("error" in body) return error(reply, body.error, 400);
|
||||
const result = await createPlanCategory(body.data!);
|
||||
if ("error" in result) return error(reply, result.error, result.status);
|
||||
await logAudit({
|
||||
request,
|
||||
authData: request.authData,
|
||||
action: "create",
|
||||
entityType: "plan_category",
|
||||
entityId: result.data.id,
|
||||
newValues: result.data,
|
||||
description: `Kategorie: ${result.data.label}`,
|
||||
});
|
||||
return success(reply, result.data, 201, "Kategorie vytvořena");
|
||||
},
|
||||
);
|
||||
|
||||
// --- PATCH /plan/categories/:id ---
|
||||
app.patch(
|
||||
"/categories/:id",
|
||||
{ preHandler: requirePermission("attendance.manage") },
|
||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
const id = parseId((request.params as any).id, reply);
|
||||
if (id === null) return;
|
||||
const body = parseBody(UpdatePlanCategorySchema, request.body);
|
||||
if ("error" in body) return error(reply, body.error, 400);
|
||||
const result = await updatePlanCategory(id, body.data!);
|
||||
if ("error" in result) return error(reply, result.error, result.status);
|
||||
await logAudit({
|
||||
request,
|
||||
authData: request.authData,
|
||||
action: "update",
|
||||
entityType: "plan_category",
|
||||
entityId: id,
|
||||
newValues: result.data,
|
||||
description: `Kategorie: ${result.data.label}`,
|
||||
});
|
||||
return success(reply, result.data, 200, "Kategorie aktualizována");
|
||||
},
|
||||
);
|
||||
|
||||
// --- DELETE /plan/categories/:id (deactivate) ---
|
||||
app.delete(
|
||||
"/categories/:id",
|
||||
{ preHandler: requirePermission("attendance.manage") },
|
||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
const id = parseId((request.params as any).id, reply);
|
||||
if (id === null) return;
|
||||
const result = await deactivatePlanCategory(id);
|
||||
if ("error" in result) return error(reply, result.error, result.status);
|
||||
await logAudit({
|
||||
request,
|
||||
authData: request.authData,
|
||||
action: "delete",
|
||||
entityType: "plan_category",
|
||||
entityId: id,
|
||||
description: "Kategorie deaktivována",
|
||||
});
|
||||
return success(reply, { ok: true }, 200, "Kategorie deaktivována");
|
||||
},
|
||||
);
|
||||
|
||||
// --- POST /plan/entries ---
|
||||
app.post(
|
||||
"/entries",
|
||||
|
||||
@@ -145,4 +145,5 @@ export type EntityType =
|
||||
| "warehouse_location"
|
||||
| "warehouse_receipt_attachment"
|
||||
| "work_plan_entry"
|
||||
| "work_plan_override";
|
||||
| "work_plan_override"
|
||||
| "plan_category";
|
||||
|
||||
Reference in New Issue
Block a user