Implement API endpoints and UI components for managing shift assignments, including guard certifications and a new assignment removal mutation. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 99f0fce6-9386-489a-9632-1d81223cab44 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/99f0fce6-9386-489a-9632-1d81223cab44/9lvKVew
242 lines
7.0 KiB
TypeScript
242 lines
7.0 KiB
TypeScript
// Integration: javascript_database and javascript_log_in_with_replit blueprints
|
|
import {
|
|
users,
|
|
guards,
|
|
certifications,
|
|
sites,
|
|
shifts,
|
|
shiftAssignments,
|
|
notifications,
|
|
type User,
|
|
type UpsertUser,
|
|
type Guard,
|
|
type InsertGuard,
|
|
type Certification,
|
|
type InsertCertification,
|
|
type Site,
|
|
type InsertSite,
|
|
type Shift,
|
|
type InsertShift,
|
|
type ShiftAssignment,
|
|
type InsertShiftAssignment,
|
|
type Notification,
|
|
type InsertNotification,
|
|
} 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<User | undefined>;
|
|
upsertUser(user: UpsertUser): Promise<User>;
|
|
|
|
// Guard operations
|
|
getAllGuards(): Promise<Guard[]>;
|
|
getGuard(id: string): Promise<Guard | undefined>;
|
|
createGuard(guard: InsertGuard): Promise<Guard>;
|
|
updateGuard(id: string, guard: Partial<InsertGuard>): Promise<Guard | undefined>;
|
|
|
|
// Certification operations
|
|
getCertificationsByGuard(guardId: string): Promise<Certification[]>;
|
|
createCertification(cert: InsertCertification): Promise<Certification>;
|
|
updateCertificationStatus(id: string, status: "valid" | "expiring_soon" | "expired"): Promise<void>;
|
|
|
|
// Site operations
|
|
getAllSites(): Promise<Site[]>;
|
|
getSite(id: string): Promise<Site | undefined>;
|
|
createSite(site: InsertSite): Promise<Site>;
|
|
updateSite(id: string, site: Partial<InsertSite>): Promise<Site | undefined>;
|
|
|
|
// Shift operations
|
|
getAllShifts(): Promise<Shift[]>;
|
|
getShift(id: string): Promise<Shift | undefined>;
|
|
getActiveShifts(): Promise<Shift[]>;
|
|
createShift(shift: InsertShift): Promise<Shift>;
|
|
updateShiftStatus(id: string, status: "planned" | "active" | "completed" | "cancelled"): Promise<void>;
|
|
|
|
// Shift Assignment operations
|
|
getShiftAssignments(shiftId: string): Promise<ShiftAssignment[]>;
|
|
createShiftAssignment(assignment: InsertShiftAssignment): Promise<ShiftAssignment>;
|
|
|
|
// Notification operations
|
|
getNotificationsByUser(userId: string): Promise<Notification[]>;
|
|
createNotification(notification: InsertNotification): Promise<Notification>;
|
|
markNotificationAsRead(id: string): Promise<void>;
|
|
}
|
|
|
|
export class DatabaseStorage implements IStorage {
|
|
// User operations (Replit Auth required)
|
|
async getUser(id: string): Promise<User | undefined> {
|
|
const [user] = await db.select().from(users).where(eq(users.id, id));
|
|
return user;
|
|
}
|
|
|
|
async upsertUser(userData: UpsertUser): Promise<User> {
|
|
const [user] = await db
|
|
.insert(users)
|
|
.values(userData)
|
|
.onConflictDoUpdate({
|
|
target: users.id,
|
|
set: {
|
|
...userData,
|
|
updatedAt: new Date(),
|
|
},
|
|
})
|
|
.returning();
|
|
return user;
|
|
}
|
|
|
|
// Guard operations
|
|
async getAllGuards(): Promise<Guard[]> {
|
|
return await db.select().from(guards);
|
|
}
|
|
|
|
async getGuard(id: string): Promise<Guard | undefined> {
|
|
const [guard] = await db.select().from(guards).where(eq(guards.id, id));
|
|
return guard;
|
|
}
|
|
|
|
async createGuard(guard: InsertGuard): Promise<Guard> {
|
|
const [newGuard] = await db.insert(guards).values(guard).returning();
|
|
return newGuard;
|
|
}
|
|
|
|
async updateGuard(id: string, guardData: Partial<InsertGuard>): Promise<Guard | undefined> {
|
|
const [updated] = await db
|
|
.update(guards)
|
|
.set({ ...guardData, updatedAt: new Date() })
|
|
.where(eq(guards.id, id))
|
|
.returning();
|
|
return updated;
|
|
}
|
|
|
|
// Certification operations
|
|
async getCertificationsByGuard(guardId: string): Promise<Certification[]> {
|
|
return await db
|
|
.select()
|
|
.from(certifications)
|
|
.where(eq(certifications.guardId, guardId))
|
|
.orderBy(desc(certifications.expiryDate));
|
|
}
|
|
|
|
async createCertification(cert: InsertCertification): Promise<Certification> {
|
|
const [newCert] = await db.insert(certifications).values(cert).returning();
|
|
return newCert;
|
|
}
|
|
|
|
async updateCertificationStatus(
|
|
id: string,
|
|
status: "valid" | "expiring_soon" | "expired"
|
|
): Promise<void> {
|
|
await db
|
|
.update(certifications)
|
|
.set({ status })
|
|
.where(eq(certifications.id, id));
|
|
}
|
|
|
|
// Site operations
|
|
async getAllSites(): Promise<Site[]> {
|
|
return await db.select().from(sites);
|
|
}
|
|
|
|
async getSite(id: string): Promise<Site | undefined> {
|
|
const [site] = await db.select().from(sites).where(eq(sites.id, id));
|
|
return site;
|
|
}
|
|
|
|
async createSite(site: InsertSite): Promise<Site> {
|
|
const [newSite] = await db.insert(sites).values(site).returning();
|
|
return newSite;
|
|
}
|
|
|
|
async updateSite(id: string, siteData: Partial<InsertSite>): Promise<Site | undefined> {
|
|
const [updated] = await db
|
|
.update(sites)
|
|
.set({ ...siteData, updatedAt: new Date() })
|
|
.where(eq(sites.id, id))
|
|
.returning();
|
|
return updated;
|
|
}
|
|
|
|
// Shift operations
|
|
async getAllShifts(): Promise<Shift[]> {
|
|
return await db.select().from(shifts).orderBy(desc(shifts.startTime));
|
|
}
|
|
|
|
async getShift(id: string): Promise<Shift | undefined> {
|
|
const [shift] = await db.select().from(shifts).where(eq(shifts.id, id));
|
|
return shift;
|
|
}
|
|
|
|
async getActiveShifts(): Promise<Shift[]> {
|
|
return await db
|
|
.select()
|
|
.from(shifts)
|
|
.where(eq(shifts.status, "active"))
|
|
.orderBy(desc(shifts.startTime));
|
|
}
|
|
|
|
async createShift(shift: InsertShift): Promise<Shift> {
|
|
const [newShift] = await db.insert(shifts).values(shift).returning();
|
|
return newShift;
|
|
}
|
|
|
|
async updateShiftStatus(
|
|
id: string,
|
|
status: "planned" | "active" | "completed" | "cancelled"
|
|
): Promise<void> {
|
|
await db
|
|
.update(shifts)
|
|
.set({ status, updatedAt: new Date() })
|
|
.where(eq(shifts.id, id));
|
|
}
|
|
|
|
// Shift Assignment operations
|
|
async getShiftAssignments(shiftId: string): Promise<ShiftAssignment[]> {
|
|
return await db
|
|
.select()
|
|
.from(shiftAssignments)
|
|
.where(eq(shiftAssignments.shiftId, shiftId));
|
|
}
|
|
|
|
async createShiftAssignment(assignment: InsertShiftAssignment): Promise<ShiftAssignment> {
|
|
const [newAssignment] = await db
|
|
.insert(shiftAssignments)
|
|
.values(assignment)
|
|
.returning();
|
|
return newAssignment;
|
|
}
|
|
|
|
async deleteShiftAssignment(id: string): Promise<void> {
|
|
await db
|
|
.delete(shiftAssignments)
|
|
.where(eq(shiftAssignments.id, id));
|
|
}
|
|
|
|
// Notification operations
|
|
async getNotificationsByUser(userId: string): Promise<Notification[]> {
|
|
return await db
|
|
.select()
|
|
.from(notifications)
|
|
.where(eq(notifications.userId, userId))
|
|
.orderBy(desc(notifications.createdAt));
|
|
}
|
|
|
|
async createNotification(notification: InsertNotification): Promise<Notification> {
|
|
const [newNotification] = await db
|
|
.insert(notifications)
|
|
.values(notification)
|
|
.returning();
|
|
return newNotification;
|
|
}
|
|
|
|
async markNotificationAsRead(id: string): Promise<void> {
|
|
await db
|
|
.update(notifications)
|
|
.set({ isRead: true })
|
|
.where(eq(notifications.id, id));
|
|
}
|
|
}
|
|
|
|
export const storage = new DatabaseStorage();
|