VigilanzaTurni/server/routes.ts
marco370 abe4041cd1 Add basic UI components and structure for the application
Initial commit adds core UI components, including layout elements, form controls, and navigation elements, along with the main application structure and routing.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 99f0fce6-9386-489a-9632-1d81223cab44
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/99f0fce6-9386-489a-9632-1d81223cab44/nGJAldO
2025-10-11 09:36:55 +00:00

254 lines
8.6 KiB
TypeScript

import type { Express } from "express";
import { createServer, type Server } from "http";
import { storage } from "./storage";
import { setupAuth, isAuthenticated } from "./replitAuth";
import { db } from "./db";
import { guards, certifications, sites, shifts, shiftAssignments, users } from "@shared/schema";
import { eq } from "drizzle-orm";
import { differenceInDays } from "date-fns";
export async function registerRoutes(app: Express): Promise<Server> {
// Auth middleware
await setupAuth(app);
// ============= AUTH ROUTES =============
app.get("/api/auth/user", isAuthenticated, async (req: any, res) => {
try {
const userId = req.user.claims.sub;
const user = await storage.getUser(userId);
res.json(user);
} catch (error) {
console.error("Error fetching user:", error);
res.status(500).json({ message: "Failed to fetch user" });
}
});
// ============= GUARD ROUTES =============
app.get("/api/guards", isAuthenticated, async (req, res) => {
try {
const allGuards = await storage.getAllGuards();
// Fetch related data for each guard
const guardsWithDetails = await Promise.all(
allGuards.map(async (guard) => {
const certs = await storage.getCertificationsByGuard(guard.id);
const user = guard.userId ? await storage.getUser(guard.userId) : undefined;
// Update certification status based on expiry date
for (const cert of certs) {
const daysUntilExpiry = differenceInDays(new Date(cert.expiryDate), new Date());
let newStatus: "valid" | "expiring_soon" | "expired" = "valid";
if (daysUntilExpiry < 0) {
newStatus = "expired";
} else if (daysUntilExpiry <= 30) {
newStatus = "expiring_soon";
}
if (cert.status !== newStatus) {
await storage.updateCertificationStatus(cert.id, newStatus);
cert.status = newStatus;
}
}
return {
...guard,
certifications: certs,
user,
};
})
);
res.json(guardsWithDetails);
} catch (error) {
console.error("Error fetching guards:", error);
res.status(500).json({ message: "Failed to fetch guards" });
}
});
app.post("/api/guards", isAuthenticated, async (req, res) => {
try {
const guard = await storage.createGuard(req.body);
res.json(guard);
} catch (error) {
console.error("Error creating guard:", error);
res.status(500).json({ message: "Failed to create guard" });
}
});
// ============= CERTIFICATION ROUTES =============
app.post("/api/certifications", isAuthenticated, async (req, res) => {
try {
const cert = await storage.createCertification(req.body);
res.json(cert);
} catch (error) {
console.error("Error creating certification:", error);
res.status(500).json({ message: "Failed to create certification" });
}
});
// ============= SITE ROUTES =============
app.get("/api/sites", isAuthenticated, async (req, res) => {
try {
const allSites = await storage.getAllSites();
res.json(allSites);
} catch (error) {
console.error("Error fetching sites:", error);
res.status(500).json({ message: "Failed to fetch sites" });
}
});
app.post("/api/sites", isAuthenticated, async (req, res) => {
try {
const site = await storage.createSite(req.body);
res.json(site);
} catch (error) {
console.error("Error creating site:", error);
res.status(500).json({ message: "Failed to create site" });
}
});
// ============= SHIFT ROUTES =============
app.get("/api/shifts", isAuthenticated, async (req, res) => {
try {
const allShifts = await storage.getAllShifts();
// Fetch related data for each shift
const shiftsWithDetails = await Promise.all(
allShifts.map(async (shift) => {
const site = await storage.getSite(shift.siteId);
const assignments = await storage.getShiftAssignments(shift.id);
// Fetch guard details for each assignment
const assignmentsWithGuards = await Promise.all(
assignments.map(async (assignment) => {
const guard = await storage.getGuard(assignment.guardId);
const certs = guard ? await storage.getCertificationsByGuard(guard.id) : [];
const user = guard?.userId ? await storage.getUser(guard.userId) : undefined;
return {
...assignment,
guard: guard ? {
...guard,
certifications: certs,
user,
} : null,
};
})
);
return {
...shift,
site: site!,
assignments: assignmentsWithGuards.filter(a => a.guard !== null),
};
})
);
res.json(shiftsWithDetails);
} catch (error) {
console.error("Error fetching shifts:", error);
res.status(500).json({ message: "Failed to fetch shifts" });
}
});
app.get("/api/shifts/active", isAuthenticated, async (req, res) => {
try {
const activeShifts = await storage.getActiveShifts();
// Fetch related data for each shift
const shiftsWithDetails = await Promise.all(
activeShifts.map(async (shift) => {
const site = await storage.getSite(shift.siteId);
const assignments = await storage.getShiftAssignments(shift.id);
// Fetch guard details for each assignment
const assignmentsWithGuards = await Promise.all(
assignments.map(async (assignment) => {
const guard = await storage.getGuard(assignment.guardId);
const certs = guard ? await storage.getCertificationsByGuard(guard.id) : [];
const user = guard?.userId ? await storage.getUser(guard.userId) : undefined;
return {
...assignment,
guard: guard ? {
...guard,
certifications: certs,
user,
} : null,
};
})
);
return {
...shift,
site: site!,
assignments: assignmentsWithGuards.filter(a => a.guard !== null),
};
})
);
res.json(shiftsWithDetails);
} catch (error) {
console.error("Error fetching active shifts:", error);
res.status(500).json({ message: "Failed to fetch active shifts" });
}
});
app.post("/api/shifts", isAuthenticated, async (req, res) => {
try {
const shift = await storage.createShift(req.body);
res.json(shift);
} catch (error) {
console.error("Error creating shift:", error);
res.status(500).json({ message: "Failed to create shift" });
}
});
app.patch("/api/shifts/:id/status", isAuthenticated, async (req, res) => {
try {
await storage.updateShiftStatus(req.params.id, req.body.status);
res.json({ success: true });
} catch (error) {
console.error("Error updating shift status:", error);
res.status(500).json({ message: "Failed to update shift status" });
}
});
// ============= SHIFT ASSIGNMENT ROUTES =============
app.post("/api/shift-assignments", isAuthenticated, async (req, res) => {
try {
const assignment = await storage.createShiftAssignment(req.body);
res.json(assignment);
} catch (error) {
console.error("Error creating shift assignment:", error);
res.status(500).json({ message: "Failed to create shift assignment" });
}
});
// ============= NOTIFICATION ROUTES =============
app.get("/api/notifications", isAuthenticated, async (req: any, res) => {
try {
const userId = req.user.claims.sub;
const userNotifications = await storage.getNotificationsByUser(userId);
res.json(userNotifications);
} catch (error) {
console.error("Error fetching notifications:", error);
res.status(500).json({ message: "Failed to fetch notifications" });
}
});
app.patch("/api/notifications/:id/read", isAuthenticated, async (req, res) => {
try {
await storage.markNotificationAsRead(req.params.id);
res.json({ success: true });
} catch (error) {
console.error("Error marking notification as read:", error);
res.status(500).json({ message: "Failed to mark notification as read" });
}
});
const httpServer = createServer(app);
return httpServer;
}