// src/routes/resources/history.ts import { FastifyInstance } from "fastify"; const columnMap: Record = { customers: "customer", vendors: "vendor", projects: "project", plants: "plant", contracts: "contract", contacts: "contact", tasks: "task", vehicles: "vehicle", events: "event", files: "file", products: "product", inventoryitems: "inventoryitem", inventoryitemgroups: "inventoryitemgroup", absencerequests: "absencerequest", checks: "check", costcentres: "costcentre", ownaccounts: "ownaccount", documentboxes: "documentbox", hourrates: "hourrate", services: "service", roles: "role", }; export default async function resourceHistoryRoutes(server: FastifyInstance) { server.get<{ Params: { resource: string; id: string } }>("/resource/:resource/:id/history", { schema: { tags: ["History"], summary: "Get history entries for a resource", params: { type: "object", required: ["resource", "id"], properties: { resource: { type: "string" }, id: { type: "string" }, }, }, }, }, async (req, reply) => { const { resource, id } = req.params; const column = columnMap[resource]; if (!column) { return reply.code(400).send({ error: `History not supported for resource '${resource}'` }); } const { data, error } = await server.supabase .from("historyitems") .select("*") .eq(column, id) .order("created_at", { ascending: true }); if (error) { server.log.error(error); return reply.code(500).send({ error: "Failed to fetch history" }); } const {data:users, error:usersError} = await server.supabase .from("auth_users") .select("*, auth_profiles(*), tenants!auth_tenant_users(*)") const filteredUsers = (users ||[]).filter(i => i.tenants.find((t:any) => t.id === req.user?.tenant_id)) const dataCombined = data.map(historyitem => { return { ...historyitem, created_by_profile: filteredUsers.find(i => i.id === historyitem.created_by) ? filteredUsers.find(i => i.id === historyitem.created_by).auth_profiles[0] : null } }) return dataCombined; }); // Neuen HistoryItem anlegen server.post<{ Params: { resource: string; id: string }; Body: { text: string; old_val?: string | null; new_val?: string | null; config?: Record; }; }>("/resource/:resource/:id/history", { schema: { tags: ["History"], summary: "Create new history entry", params: { type: "object", properties: { resource: { type: "string" }, id: { type: "string" } }, required: ["resource", "id"] }, body: { type: "object", properties: { text: { type: "string" }, old_val: { type: "string", nullable: true }, new_val: { type: "string", nullable: true }, config: { type: "object", nullable: true } }, required: ["text"] }, response: { 201: { type: "object", properties: { id: { type: "number" }, text: { type: "string" }, created_at: { type: "string" }, created_by: { type: "string" } } } } } }, async (req, reply) => { const { resource, id } = req.params; const { text, old_val, new_val, config } = req.body; const userId = (req.user as any)?.user_id; const fkField = columnMap[resource]; if (!fkField) { return reply.code(400).send({ error: `Unknown resource: ${resource}` }); } const { data, error } = await server.supabase .from("historyitems") .insert({ text, [fkField]: id, oldVal: old_val || null, newVal: new_val || null, config: config || null, tenant: (req.user as any)?.tenant_id, created_by: userId }) .select() .single(); if (error) { return reply.code(500).send({ error: error.message }); } return reply.code(201).send(data); }); }