diff --git a/shared/schema.ts b/shared/schema.ts index 9b9bbd2..1517edb 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -297,6 +297,50 @@ export const shiftAssignments = pgTable("shift_assignments", { // Actual check-in/out times (recorded when guard clocks in/out) checkInTime: timestamp("check_in_time"), checkOutTime: timestamp("check_out_time"), + + // Dotazioni operative per questo turno specifico + isArmedOnDuty: boolean("is_armed_on_duty").default(false), // Guardia armata per questo turno + assignedVehicleId: varchar("assigned_vehicle_id").references(() => vehicles.id, { onDelete: "set null" }), // Automezzo assegnato +}); + +// ============= PATROL ROUTES (TURNI PATTUGLIA) ============= + +export const patrolRoutes = pgTable("patrol_routes", { + id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), + guardId: varchar("guard_id").notNull().references(() => guards.id, { onDelete: "cascade" }), + + // Data e orari del turno pattuglia + shiftDate: date("shift_date").notNull(), // Data del turno + startTime: varchar("start_time").notNull(), // Orario inizio (HH:MM) + endTime: varchar("end_time").notNull(), // Orario fine (HH:MM) + + status: shiftStatusEnum("status").notNull().default("planned"), + location: locationEnum("location").notNull(), // Sede di riferimento + + // Dotazioni + vehicleId: varchar("vehicle_id").references(() => vehicles.id, { onDelete: "set null" }), + isArmedRoute: boolean("is_armed_route").default(false), // Percorso con guardia armata + + notes: text("notes"), + createdAt: timestamp("created_at").defaultNow(), + updatedAt: timestamp("updated_at").defaultNow(), +}); + +export const patrolRouteStops = pgTable("patrol_route_stops", { + id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), + patrolRouteId: varchar("patrol_route_id").notNull().references(() => patrolRoutes.id, { onDelete: "cascade" }), + siteId: varchar("site_id").notNull().references(() => sites.id, { onDelete: "cascade" }), + + sequenceOrder: integer("sequence_order").notNull(), // Ordine nel percorso (1, 2, 3...) + estimatedArrivalTime: varchar("estimated_arrival_time"), // Orario stimato arrivo (HH:MM) + actualArrivalTime: timestamp("actual_arrival_time"), // Orario effettivo arrivo + + // Check completamento tappa + isCompleted: boolean("is_completed").default(false), + completedAt: timestamp("completed_at"), + + notes: text("notes"), // Note specifiche per questa tappa + createdAt: timestamp("created_at").defaultNow(), }); // ============= CCNL SETTINGS ============= @@ -518,6 +562,7 @@ export const guardsRelations = relations(guards, ({ one, many }) => ({ }), certifications: many(certifications), shiftAssignments: many(shiftAssignments), + patrolRoutes: many(patrolRoutes), constraints: one(guardConstraints), sitePreferences: many(sitePreferences), trainingCourses: many(trainingCourses), @@ -549,6 +594,7 @@ export const sitesRelations = relations(sites, ({ one, many }) => ({ references: [customers.id], }), shifts: many(shifts), + patrolRouteStops: many(patrolRouteStops), preferences: many(sitePreferences), })); @@ -573,6 +619,33 @@ export const shiftAssignmentsRelations = relations(shiftAssignments, ({ one }) = fields: [shiftAssignments.guardId], references: [guards.id], }), + assignedVehicle: one(vehicles, { + fields: [shiftAssignments.assignedVehicleId], + references: [vehicles.id], + }), +})); + +export const patrolRoutesRelations = relations(patrolRoutes, ({ one, many }) => ({ + guard: one(guards, { + fields: [patrolRoutes.guardId], + references: [guards.id], + }), + vehicle: one(vehicles, { + fields: [patrolRoutes.vehicleId], + references: [vehicles.id], + }), + stops: many(patrolRouteStops), +})); + +export const patrolRouteStopsRelations = relations(patrolRouteStops, ({ one }) => ({ + patrolRoute: one(patrolRoutes, { + fields: [patrolRouteStops.patrolRouteId], + references: [patrolRoutes.id], + }), + site: one(sites, { + fields: [patrolRouteStops.siteId], + references: [sites.id], + }), })); export const notificationsRelations = relations(notifications, ({ one }) => ({ @@ -731,6 +804,17 @@ export const insertShiftSchema = createInsertSchema(shifts).omit({ updatedAt: true, }); +export const insertPatrolRouteSchema = createInsertSchema(patrolRoutes).omit({ + id: true, + createdAt: true, + updatedAt: true, +}); + +export const insertPatrolRouteStopSchema = createInsertSchema(patrolRouteStops).omit({ + id: true, + createdAt: true, +}); + // Form schema that accepts datetime strings and transforms to Date export const insertShiftFormSchema = z.object({ siteId: z.string().min(1, "Sito obbligatorio"),