VigilanzaTurni/server/seed.ts
marco370 a5355ed881 Add system to manage different types of security services and their details
Introduce new "serviceTypes" table and CRUD operations in the backend. Update frontend to fetch and display service types dynamically. Modify vehicle assignment logic to handle null guards.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: e5565357-90e1-419f-b9a8-6ee8394636df
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e5565357-90e1-419f-b9a8-6ee8394636df/IgrJ2ut
2025-10-17 09:12:29 +00:00

303 lines
9.5 KiB
TypeScript

import { db } from "./db";
import { users, guards, sites, vehicles, contractParameters, serviceTypes } from "@shared/schema";
import { eq } from "drizzle-orm";
import bcrypt from "bcrypt";
async function seed() {
console.log("🌱 Avvio seed database multi-sede...");
// Create Service Types
console.log("📝 Creazione tipologie di servizi...");
const defaultServiceTypes = [
{
code: "fixed_post",
label: "Presidio Fisso",
description: "Guardia fissa presso una struttura",
icon: "Building2",
color: "blue",
isActive: true
},
{
code: "patrol",
label: "Pattugliamento",
description: "Ronde e controlli su area",
icon: "Eye",
color: "green",
isActive: true
},
{
code: "night_inspection",
label: "Ispettorato Notturno",
description: "Controlli notturni programmati",
icon: "Shield",
color: "purple",
isActive: true
},
{
code: "quick_response",
label: "Pronto Intervento",
description: "Intervento rapido su chiamata",
icon: "Zap",
color: "orange",
isActive: true
}
];
for (const serviceType of defaultServiceTypes) {
const existing = await db.select().from(serviceTypes).where(eq(serviceTypes.code, serviceType.code)).limit(1);
if (existing.length === 0) {
await db.insert(serviceTypes).values(serviceType);
console.log(` + Creata tipologia: ${serviceType.label}`);
} else {
console.log(` ✓ Tipologia esistente: ${serviceType.label}`);
}
}
// Create CCNL contract parameters
console.log("📋 Creazione parametri contrattuali CCNL...");
const existingParams = await db.select().from(contractParameters).limit(1);
if (existingParams.length === 0) {
await db.insert(contractParameters).values({
contractType: "CCNL Vigilanza Privata",
maxHoursPerDay: 9,
maxOvertimePerDay: 2,
maxHoursPerWeek: 48,
maxOvertimePerWeek: 8,
minDailyRestHours: 11,
minDailyRestHoursReduced: 9,
maxDailyRestReductionsPerMonth: 3,
maxDailyRestReductionsPerYear: 20,
minWeeklyRestHours: 24,
maxNightHoursPerWeek: 40,
pauseMinutesIfOver6Hours: 30,
holidayPayIncrease: 30,
nightPayIncrease: 15,
overtimePayIncrease: 20,
mealVoucherEnabled: true,
mealVoucherAfterHours: 6,
mealVoucherAmount: 8
});
console.log(" ✓ Parametri CCNL creati");
} else {
console.log(" ✓ Parametri CCNL già esistenti");
}
// Locations
const locations = ["roccapiemonte", "milano", "roma"] as const;
const locationNames = {
roccapiemonte: "Roccapiemonte",
milano: "Milano",
roma: "Roma"
};
// Cleanup existing data (optional - comment out to preserve existing data)
// await db.delete(guards);
// await db.delete(sites);
// await db.delete(vehicles);
console.log("👥 Creazione guardie per ogni sede...");
// Create 10 guards per location
const guardNames = [
"Marco Rossi", "Luca Bianchi", "Giuseppe Verdi", "Francesco Romano",
"Alessandro Russo", "Andrea Marino", "Matteo Ferrari", "Lorenzo Conti",
"Davide Ricci", "Simone Moretti"
];
for (const location of locations) {
for (let i = 0; i < 10; i++) {
const fullName = guardNames[i];
const [firstName, ...lastNameParts] = fullName.split(" ");
const lastName = lastNameParts.join(" ");
const email = `${fullName.toLowerCase().replace(" ", ".")}@${location}.vt.alfacom.it`;
const badgeNumber = `${location.substring(0, 3).toUpperCase()}${String(i + 1).padStart(3, "0")}`;
// Check if user exists
const existingUser = await db
.select()
.from(users)
.where(eq(users.email, email))
.limit(1);
let userId: string;
if (existingUser.length > 0) {
userId = existingUser[0].id;
console.log(` ✓ Utente esistente: ${email}`);
} else {
// Create user
const hashedPassword = await bcrypt.hash("guard123", 10);
const [newUser] = await db
.insert(users)
.values({
email,
firstName,
lastName,
passwordHash: hashedPassword,
role: "guard"
})
.returning();
userId = newUser.id;
console.log(` + Creato utente: ${email}`);
}
// Check if guard exists
const existingGuard = await db
.select()
.from(guards)
.where(eq(guards.badgeNumber, badgeNumber))
.limit(1);
if (existingGuard.length === 0) {
await db.insert(guards).values({
userId,
badgeNumber,
phoneNumber: `+39 ${330 + i} ${Math.floor(Math.random() * 1000000)}`,
location,
isArmed: i % 3 === 0, // 1 su 3 è armato
hasFireSafety: i % 2 === 0, // 1 su 2 ha antincendio
hasFirstAid: i % 4 === 0, // 1 su 4 ha primo soccorso
hasDriverLicense: i % 2 === 1, // 1 su 2 ha patente
languages: i === 0 ? ["italiano", "inglese"] : ["italiano"]
});
console.log(` + Creata guardia: ${badgeNumber} - ${name} (${locationNames[location]})`);
} else {
console.log(` ✓ Guardia esistente: ${badgeNumber}`);
}
}
}
console.log("\n🏢 Creazione clienti per ogni sede...");
// Create 10 clients per location
const companyNames = [
"Banca Centrale", "Ospedale San Marco", "Centro Commerciale Europa",
"Uffici Postali", "Museo Arte Moderna", "Palazzo Comunale",
"Stazione Ferroviaria", "Aeroporto Internazionale", "Università Statale",
"Tribunale Civile"
];
for (const location of locations) {
for (let i = 0; i < 10; i++) {
const companyName = companyNames[i];
const email = `${companyName.toLowerCase().replace(/ /g, ".")}@${location}.clienti.vt.it`;
// Check if client user exists
const existingClient = await db
.select()
.from(users)
.where(eq(users.email, email))
.limit(1);
let clientId: string;
if (existingClient.length > 0) {
clientId = existingClient[0].id;
console.log(` ✓ Cliente esistente: ${email}`);
} else {
const hashedPassword = await bcrypt.hash("client123", 10);
const [newClient] = await db
.insert(users)
.values({
email,
firstName: companyName,
lastName: locationNames[location],
passwordHash: hashedPassword,
role: "client"
})
.returning();
clientId = newClient.id;
console.log(` + Creato cliente: ${email}`);
}
// Check if site exists
const siteName = `${companyName} - ${locationNames[location]}`;
const existingSite = await db
.select()
.from(sites)
.where(eq(sites.name, siteName))
.limit(1);
if (existingSite.length === 0) {
const shiftTypes = ["fixed_post", "patrol", "night_inspection", "quick_response"] as const;
await db.insert(sites).values({
name: siteName,
address: `Via ${companyName} ${i + 1}, ${locationNames[location]}`,
clientId,
location,
shiftType: shiftTypes[i % 4],
minGuards: Math.floor(Math.random() * 3) + 1,
requiresArmed: i % 3 === 0,
requiresDriverLicense: i % 4 === 0,
isActive: true
});
console.log(` + Creato sito: ${siteName}`);
} else {
console.log(` ✓ Sito esistente: ${siteName}`);
}
}
}
console.log("\n🚗 Creazione automezzi per ogni sede...");
// Create vehicles per location
const vehicleBrands = [
{ brand: "Fiat", model: "Punto", type: "car" },
{ brand: "Volkswagen", model: "Polo", type: "car" },
{ brand: "Ford", model: "Transit", type: "van" },
{ brand: "Mercedes", model: "Sprinter", type: "van" },
{ brand: "BMW", model: "GS 750", type: "motorcycle" },
] as const;
for (const location of locations) {
for (let i = 0; i < 5; i++) {
const vehicle = vehicleBrands[i];
const licensePlate = `${location.substring(0, 2).toUpperCase()}${String(Math.floor(Math.random() * 1000)).padStart(3, "0")}${String.fromCharCode(65 + Math.floor(Math.random() * 26))}${String.fromCharCode(65 + Math.floor(Math.random() * 26))}`;
// Check if vehicle exists
const existingVehicle = await db
.select()
.from(vehicles)
.where(eq(vehicles.licensePlate, licensePlate))
.limit(1);
if (existingVehicle.length === 0) {
await db.insert(vehicles).values({
licensePlate,
brand: vehicle.brand,
model: vehicle.model,
vehicleType: vehicle.type,
year: 2018 + Math.floor(Math.random() * 6),
location,
status: i === 0 ? "in_use" : "available",
mileage: Math.floor(Math.random() * 100000) + 10000
});
console.log(` + Creato automezzo: ${licensePlate} - ${vehicle.brand} ${vehicle.model} (${locationNames[location]})`);
} else {
console.log(` ✓ Automezzo esistente: ${licensePlate}`);
}
}
}
console.log("\n✅ Seed completato!");
console.log(`
📊 Riepilogo:
- 30 guardie totali (10 per sede)
- 30 siti/clienti totali (10 per sede)
- 15 automezzi totali (5 per sede)
🔐 Credenziali:
- Guardie: *.guardia@[sede].vt.alfacom.it / guard123
- Clienti: *@[sede].clienti.vt.it / client123
- Admin: admin@vt.alfacom.it / admin123
`);
process.exit(0);
}
seed().catch((error) => {
console.error("❌ Errore seed:", error);
process.exit(1);
});