fix #29 Corrected User ID
This commit is contained in:
@@ -62,17 +62,17 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
||||
// 🆕 POST /staff/time/edit (Bearbeiten durch Invalidieren + Neu erstellen)
|
||||
server.post("/staff/time/edit", async (req, reply) => {
|
||||
try {
|
||||
const userId = req.user.user_id;
|
||||
// 1. Der "Actor" ist der, der gerade eingeloggt ist (z.B. Manager)
|
||||
const actorId = req.user.user_id;
|
||||
const tenantId = req.user.tenant_id;
|
||||
|
||||
// Wir erwarten das komplette Paket für die Änderung
|
||||
const {
|
||||
originalEventIds, // Array der IDs, die "gelöscht" werden sollen (Start ID, End ID)
|
||||
newStart, // ISO String
|
||||
newEnd, // ISO String
|
||||
newType, // z.B. 'work', 'vacation'
|
||||
originalEventIds,
|
||||
newStart,
|
||||
newEnd,
|
||||
newType,
|
||||
description,
|
||||
reason // Warum wurde geändert? (Audit)
|
||||
reason
|
||||
} = req.body as {
|
||||
originalEventIds: string[],
|
||||
newStart: string,
|
||||
@@ -86,41 +86,66 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
||||
return reply.code(400).send({ error: "Keine Events zum Bearbeiten angegeben." });
|
||||
}
|
||||
|
||||
// 1. Transaction starten (damit alles oder nichts passiert)
|
||||
// -----------------------------------------------------------
|
||||
// SCHRITT A: Den eigentlichen Besitzer (Mitarbeiter) ermitteln
|
||||
// -----------------------------------------------------------
|
||||
// Wir holen uns das erste Event aus der Liste, um zu sehen, wem es gehört.
|
||||
const existingEvents = await server.db
|
||||
.select({
|
||||
user_id: stafftimeevents.user_id,
|
||||
tenant_id: stafftimeevents.tenant_id
|
||||
})
|
||||
.from(stafftimeevents)
|
||||
.where(and(
|
||||
eq(stafftimeevents.id, originalEventIds[0]),
|
||||
eq(stafftimeevents.tenant_id, tenantId) // Sicherheitscheck: Nur im eigenen Tenant
|
||||
))
|
||||
.limit(1);
|
||||
|
||||
if (existingEvents.length === 0) {
|
||||
return reply.code(404).send({ error: "Ursprüngliches Event nicht gefunden oder Zugriff verweigert." });
|
||||
}
|
||||
|
||||
// Das ist der Mitarbeiter, dem die Zeit gehört
|
||||
const targetUserId = existingEvents[0].user_id;
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// SCHRITT B: Transaktion durchführen
|
||||
// -----------------------------------------------------------
|
||||
await server.db.transaction(async (tx) => {
|
||||
|
||||
// A. INVALIDIEREN (Die alten Events "löschen")
|
||||
// Wir erstellen für jedes alte Event ein 'invalidated' Event
|
||||
// 1. INVALIDIEREN
|
||||
// Wir nutzen 'targetUserId' als Besitzer des Events, aber 'actorId' als Auslöser
|
||||
const invalidations = originalEventIds.map(id => ({
|
||||
tenant_id: tenantId,
|
||||
user_id: userId, // Gehört dem Mitarbeiter
|
||||
user_id: targetUserId, // <--- WICHTIG: Gehört dem Mitarbeiter
|
||||
actortype: "user",
|
||||
actoruser_id: userId, // Wer hat geändert?
|
||||
actoruser_id: actorId, // <--- WICHTIG: Geändert durch Manager/Self
|
||||
eventtime: new Date(),
|
||||
eventtype: "invalidated", // <--- NEUER TYP: Muss in loadValidEvents gefiltert werden!
|
||||
eventtype: "invalidated",
|
||||
source: "WEB",
|
||||
related_event_id: id, // Zeigt auf das alte Event
|
||||
related_event_id: id,
|
||||
metadata: {
|
||||
reason: reason || "Bearbeitung",
|
||||
replaced_by_edit: true
|
||||
}
|
||||
}));
|
||||
|
||||
// Batch Insert
|
||||
// @ts-ignore
|
||||
await tx.insert(stafftimeevents).values(invalidations);
|
||||
|
||||
// B. NEU ERSTELLEN (Die korrigierten Events anlegen)
|
||||
// 2. NEU ERSTELLEN
|
||||
|
||||
// Start Event
|
||||
// @ts-ignore
|
||||
await tx.insert(stafftimeevents).values({
|
||||
tenant_id: tenantId,
|
||||
user_id: userId,
|
||||
user_id: targetUserId, // <--- Gehört dem Mitarbeiter
|
||||
actortype: "user",
|
||||
actoruser_id: userId,
|
||||
actoruser_id: actorId, // <--- Erstellt durch Manager/Self
|
||||
eventtime: new Date(newStart),
|
||||
eventtype: `${newType}_start`, // z.B. work_start
|
||||
eventtype: `${newType}_start`,
|
||||
source: "WEB",
|
||||
payload: { description: description || "" }
|
||||
});
|
||||
@@ -130,11 +155,11 @@ export default async function staffTimeRoutes(server: FastifyInstance) {
|
||||
// @ts-ignore
|
||||
await tx.insert(stafftimeevents).values({
|
||||
tenant_id: tenantId,
|
||||
user_id: userId,
|
||||
user_id: targetUserId, // <--- Gehört dem Mitarbeiter
|
||||
actortype: "user",
|
||||
actoruser_id: userId,
|
||||
actoruser_id: actorId, // <--- Erstellt durch Manager/Self
|
||||
eventtime: new Date(newEnd),
|
||||
eventtype: `${newType}_end`, // z.B. work_end
|
||||
eventtype: `${newType}_end`,
|
||||
source: "WEB"
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user