// Integration: javascript_database and javascript_log_in_with_replit blueprints import { users, guards, certifications, vehicles, sites, shifts, shiftAssignments, notifications, guardConstraints, sitePreferences, trainingCourses, holidays, holidayAssignments, absences, absenceAffectedShifts, contractParameters, type User, type UpsertUser, type Guard, type InsertGuard, type Certification, type InsertCertification, type Vehicle, type InsertVehicle, type Site, type InsertSite, type Shift, type InsertShift, type ShiftAssignment, type InsertShiftAssignment, type Notification, type InsertNotification, type GuardConstraints, type InsertGuardConstraints, type SitePreference, type InsertSitePreference, type TrainingCourse, type InsertTrainingCourse, type Holiday, type InsertHoliday, type HolidayAssignment, type InsertHolidayAssignment, type Absence, type InsertAbsence, type AbsenceAffectedShift, type InsertAbsenceAffectedShift, type ContractParameters, type InsertContractParameters, } from "@shared/schema"; import { db } from "./db"; import { eq, and, gte, lte, desc } from "drizzle-orm"; export interface IStorage { // User operations (Replit Auth required) getUser(id: string): Promise; upsertUser(user: UpsertUser): Promise; getAllUsers(): Promise; updateUserRole(id: string, role: "admin" | "coordinator" | "guard" | "client"): Promise; // Guard operations getAllGuards(): Promise; getGuard(id: string): Promise; createGuard(guard: InsertGuard): Promise; updateGuard(id: string, guard: Partial): Promise; // Certification operations getCertificationsByGuard(guardId: string): Promise; createCertification(cert: InsertCertification): Promise; updateCertificationStatus(id: string, status: "valid" | "expiring_soon" | "expired"): Promise; // Site operations getAllSites(): Promise; getSite(id: string): Promise; createSite(site: InsertSite): Promise; updateSite(id: string, site: Partial): Promise; // Shift operations getAllShifts(): Promise; getShift(id: string): Promise; getActiveShifts(): Promise; createShift(shift: InsertShift): Promise; updateShiftStatus(id: string, status: "planned" | "active" | "completed" | "cancelled"): Promise; // Shift Assignment operations getShiftAssignments(shiftId: string): Promise; createShiftAssignment(assignment: InsertShiftAssignment): Promise; // Notification operations getNotificationsByUser(userId: string): Promise; createNotification(notification: InsertNotification): Promise; markNotificationAsRead(id: string): Promise; // Guard Constraints operations getGuardConstraints(guardId: string): Promise; upsertGuardConstraints(constraints: InsertGuardConstraints): Promise; // Site Preferences operations getSitePreferences(siteId: string): Promise; createSitePreference(pref: InsertSitePreference): Promise; deleteSitePreference(id: string): Promise; // Training Courses operations getTrainingCoursesByGuard(guardId: string): Promise; getAllTrainingCourses(): Promise; createTrainingCourse(course: InsertTrainingCourse): Promise; updateTrainingCourse(id: string, course: Partial): Promise; deleteTrainingCourse(id: string): Promise; // Holidays operations getAllHolidays(year?: number): Promise; createHoliday(holiday: InsertHoliday): Promise; deleteHoliday(id: string): Promise; // Holiday Assignments operations getHolidayAssignments(holidayId: string): Promise; createHolidayAssignment(assignment: InsertHolidayAssignment): Promise; deleteHolidayAssignment(id: string): Promise; // Absences operations getAllAbsences(): Promise; getAbsencesByGuard(guardId: string): Promise; createAbsence(absence: InsertAbsence): Promise; updateAbsence(id: string, absence: Partial): Promise; deleteAbsence(id: string): Promise; // Absence Affected Shifts operations getAffectedShiftsByAbsence(absenceId: string): Promise; createAbsenceAffectedShift(affected: InsertAbsenceAffectedShift): Promise; deleteAbsenceAffectedShift(id: string): Promise; // Contract Parameters operations getContractParameters(): Promise; createContractParameters(params: InsertContractParameters): Promise; updateContractParameters(id: string, params: Partial): Promise; } export class DatabaseStorage implements IStorage { // User operations (Replit Auth required) async getUser(id: string): Promise { const [user] = await db.select().from(users).where(eq(users.id, id)); return user; } async upsertUser(userData: UpsertUser): Promise { // Check if user already exists by email (unique constraint) const existingUser = await db .select() .from(users) .where(eq(users.email, userData.email || '')) .limit(1); if (existingUser.length > 0) { // Update existing user const [updated] = await db .update(users) .set({ ...userData, updatedAt: new Date(), }) .where(eq(users.email, userData.email || '')) .returning(); return updated; } else { // Insert new user const [user] = await db .insert(users) .values(userData) .returning(); return user; } } async getAllUsers(): Promise { return await db.select().from(users).orderBy(desc(users.createdAt)); } async updateUserRole(id: string, role: "admin" | "coordinator" | "guard" | "client"): Promise { const [updated] = await db .update(users) .set({ role, updatedAt: new Date() }) .where(eq(users.id, id)) .returning(); return updated; } async deleteUser(id: string): Promise { const [deleted] = await db.delete(users).where(eq(users.id, id)).returning(); return deleted; } // Guard operations async getAllGuards(): Promise { return await db.select().from(guards); } async getGuard(id: string): Promise { const [guard] = await db.select().from(guards).where(eq(guards.id, id)); return guard; } async createGuard(guard: InsertGuard): Promise { const [newGuard] = await db.insert(guards).values(guard).returning(); return newGuard; } async updateGuard(id: string, guardData: Partial): Promise { const [updated] = await db .update(guards) .set({ ...guardData, updatedAt: new Date() }) .where(eq(guards.id, id)) .returning(); return updated; } async deleteGuard(id: string): Promise { const [deleted] = await db.delete(guards).where(eq(guards.id, id)).returning(); return deleted; } // Vehicle operations async getAllVehicles(): Promise { return await db.select().from(vehicles).orderBy(desc(vehicles.createdAt)); } async getVehicle(id: string): Promise { const [vehicle] = await db.select().from(vehicles).where(eq(vehicles.id, id)); return vehicle; } async createVehicle(vehicle: InsertVehicle): Promise { const [newVehicle] = await db.insert(vehicles).values(vehicle).returning(); return newVehicle; } async updateVehicle(id: string, vehicleData: Partial): Promise { const [updated] = await db .update(vehicles) .set({ ...vehicleData, updatedAt: new Date() }) .where(eq(vehicles.id, id)) .returning(); return updated; } async deleteVehicle(id: string): Promise { const [deleted] = await db.delete(vehicles).where(eq(vehicles.id, id)).returning(); return deleted; } // Certification operations async getCertificationsByGuard(guardId: string): Promise { return await db .select() .from(certifications) .where(eq(certifications.guardId, guardId)) .orderBy(desc(certifications.expiryDate)); } async createCertification(cert: InsertCertification): Promise { const [newCert] = await db.insert(certifications).values(cert).returning(); return newCert; } async updateCertificationStatus( id: string, status: "valid" | "expiring_soon" | "expired" ): Promise { await db .update(certifications) .set({ status }) .where(eq(certifications.id, id)); } // Site operations async getAllSites(): Promise { return await db.select().from(sites); } async getSite(id: string): Promise { const [site] = await db.select().from(sites).where(eq(sites.id, id)); return site; } async createSite(site: InsertSite): Promise { const [newSite] = await db.insert(sites).values(site).returning(); return newSite; } async updateSite(id: string, siteData: Partial): Promise { const [updated] = await db .update(sites) .set({ ...siteData, updatedAt: new Date() }) .where(eq(sites.id, id)) .returning(); return updated; } async deleteSite(id: string): Promise { const [deleted] = await db.delete(sites).where(eq(sites.id, id)).returning(); return deleted; } // Shift operations async getAllShifts(): Promise { return await db.select().from(shifts).orderBy(desc(shifts.startTime)); } async getShift(id: string): Promise { const [shift] = await db.select().from(shifts).where(eq(shifts.id, id)); return shift; } async getActiveShifts(): Promise { return await db .select() .from(shifts) .where(eq(shifts.status, "active")) .orderBy(desc(shifts.startTime)); } async createShift(shift: InsertShift): Promise { const [newShift] = await db.insert(shifts).values(shift).returning(); return newShift; } async updateShiftStatus( id: string, status: "planned" | "active" | "completed" | "cancelled" ): Promise { await db .update(shifts) .set({ status, updatedAt: new Date() }) .where(eq(shifts.id, id)); } async updateShift(id: string, shiftData: Partial): Promise { const [updated] = await db .update(shifts) .set({ ...shiftData, updatedAt: new Date() }) .where(eq(shifts.id, id)) .returning(); return updated; } async deleteShift(id: string): Promise { const [deleted] = await db.delete(shifts).where(eq(shifts.id, id)).returning(); return deleted; } // Shift Assignment operations async getShiftAssignments(shiftId: string): Promise { return await db .select() .from(shiftAssignments) .where(eq(shiftAssignments.shiftId, shiftId)); } async createShiftAssignment(assignment: InsertShiftAssignment): Promise { const [newAssignment] = await db .insert(shiftAssignments) .values(assignment) .returning(); return newAssignment; } async deleteShiftAssignment(id: string): Promise { await db .delete(shiftAssignments) .where(eq(shiftAssignments.id, id)); } // Notification operations async getNotificationsByUser(userId: string): Promise { return await db .select() .from(notifications) .where(eq(notifications.userId, userId)) .orderBy(desc(notifications.createdAt)); } async createNotification(notification: InsertNotification): Promise { const [newNotification] = await db .insert(notifications) .values(notification) .returning(); return newNotification; } async markNotificationAsRead(id: string): Promise { await db .update(notifications) .set({ isRead: true }) .where(eq(notifications.id, id)); } // Guard Constraints operations async getGuardConstraints(guardId: string): Promise { const [constraints] = await db .select() .from(guardConstraints) .where(eq(guardConstraints.guardId, guardId)); return constraints; } async upsertGuardConstraints(constraintsData: InsertGuardConstraints): Promise { const existing = await this.getGuardConstraints(constraintsData.guardId); if (existing) { const [updated] = await db .update(guardConstraints) .set({ ...constraintsData, updatedAt: new Date() }) .where(eq(guardConstraints.guardId, constraintsData.guardId)) .returning(); return updated; } else { const [created] = await db .insert(guardConstraints) .values(constraintsData) .returning(); return created; } } // Site Preferences operations async getSitePreferences(siteId: string): Promise { return await db .select() .from(sitePreferences) .where(eq(sitePreferences.siteId, siteId)); } async createSitePreference(pref: InsertSitePreference): Promise { const [newPref] = await db.insert(sitePreferences).values(pref).returning(); return newPref; } async deleteSitePreference(id: string): Promise { await db.delete(sitePreferences).where(eq(sitePreferences.id, id)); } // Training Courses operations async getTrainingCoursesByGuard(guardId: string): Promise { return await db .select() .from(trainingCourses) .where(eq(trainingCourses.guardId, guardId)) .orderBy(desc(trainingCourses.scheduledDate)); } async getAllTrainingCourses(): Promise { return await db.select().from(trainingCourses).orderBy(desc(trainingCourses.scheduledDate)); } async createTrainingCourse(course: InsertTrainingCourse): Promise { const [newCourse] = await db.insert(trainingCourses).values(course).returning(); return newCourse; } async updateTrainingCourse(id: string, courseData: Partial): Promise { const [updated] = await db .update(trainingCourses) .set(courseData) .where(eq(trainingCourses.id, id)) .returning(); return updated; } async deleteTrainingCourse(id: string): Promise { await db.delete(trainingCourses).where(eq(trainingCourses.id, id)); } // Holidays operations async getAllHolidays(year?: number): Promise { if (year) { return await db .select() .from(holidays) .where(eq(holidays.year, year)) .orderBy(holidays.date); } return await db.select().from(holidays).orderBy(holidays.date); } async createHoliday(holiday: InsertHoliday): Promise { const [newHoliday] = await db.insert(holidays).values(holiday).returning(); return newHoliday; } async deleteHoliday(id: string): Promise { await db.delete(holidays).where(eq(holidays.id, id)); } // Holiday Assignments operations async getHolidayAssignments(holidayId: string): Promise { return await db .select() .from(holidayAssignments) .where(eq(holidayAssignments.holidayId, holidayId)); } async createHolidayAssignment(assignment: InsertHolidayAssignment): Promise { const [newAssignment] = await db.insert(holidayAssignments).values(assignment).returning(); return newAssignment; } async deleteHolidayAssignment(id: string): Promise { await db.delete(holidayAssignments).where(eq(holidayAssignments.id, id)); } // Absences operations async getAllAbsences(): Promise { return await db.select().from(absences).orderBy(desc(absences.startDate)); } async getAbsencesByGuard(guardId: string): Promise { return await db .select() .from(absences) .where(eq(absences.guardId, guardId)) .orderBy(desc(absences.startDate)); } async createAbsence(absence: InsertAbsence): Promise { const [newAbsence] = await db.insert(absences).values(absence).returning(); return newAbsence; } async updateAbsence(id: string, absenceData: Partial): Promise { const [updated] = await db .update(absences) .set(absenceData) .where(eq(absences.id, id)) .returning(); return updated; } async deleteAbsence(id: string): Promise { await db.delete(absences).where(eq(absences.id, id)); } // Absence Affected Shifts operations async getAffectedShiftsByAbsence(absenceId: string): Promise { return await db .select() .from(absenceAffectedShifts) .where(eq(absenceAffectedShifts.absenceId, absenceId)); } async createAbsenceAffectedShift(affected: InsertAbsenceAffectedShift): Promise { const [newAffected] = await db.insert(absenceAffectedShifts).values(affected).returning(); return newAffected; } async deleteAbsenceAffectedShift(id: string): Promise { await db.delete(absenceAffectedShifts).where(eq(absenceAffectedShifts.id, id)); } // Contract Parameters operations async getContractParameters(): Promise { const params = await db.select().from(contractParameters).limit(1); return params[0]; } async createContractParameters(params: InsertContractParameters): Promise { const [newParams] = await db.insert(contractParameters).values(params).returning(); return newParams; } async updateContractParameters(id: string, params: Partial): Promise { const [updated] = await db .update(contractParameters) .set(params) .where(eq(contractParameters.id, id)) .returning(); return updated; } } export const storage = new DatabaseStorage();