Add development tools to reset and seed the application data
Introduces API endpoints `/api/dev/reset-data` (DELETE) and `/api/dev/seed-data` (POST) for clearing and populating the database with sample sites and guards, intended for development and testing purposes. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e5565357-90e1-419f-b9a8-6ee8394636df Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e5565357-90e1-419f-b9a8-6ee8394636df/Jxn533V
This commit is contained in:
parent
24a1c81d6e
commit
52f3aee8e4
4
.replit
4
.replit
@ -19,6 +19,10 @@ externalPort = 80
|
||||
localPort = 33035
|
||||
externalPort = 3001
|
||||
|
||||
[[ports]]
|
||||
localPort = 33123
|
||||
externalPort = 5173
|
||||
|
||||
[[ports]]
|
||||
localPort = 41343
|
||||
externalPort = 3000
|
||||
|
||||
269
server/routes.ts
269
server/routes.ts
@ -2153,6 +2153,275 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// ============= DEV UTILITIES (Reset & Seed Data) =============
|
||||
|
||||
// DELETE all sites and guards (for testing)
|
||||
app.delete("/api/dev/reset-data", isAuthenticated, async (req, res) => {
|
||||
try {
|
||||
// Delete all shift assignments first (foreign key constraints)
|
||||
await db.delete(shiftAssignments);
|
||||
|
||||
// Delete all shifts
|
||||
await db.delete(shifts);
|
||||
|
||||
// Delete all sites
|
||||
await db.delete(sites);
|
||||
|
||||
// Delete all certifications
|
||||
await db.delete(certifications);
|
||||
|
||||
// Delete all guards
|
||||
await db.delete(guards);
|
||||
|
||||
// Delete all vehicles
|
||||
await db.delete(vehicles);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: "Tutti i dati (siti, guardie, turni, veicoli) sono stati eliminati"
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error resetting data:", error);
|
||||
res.status(500).json({ message: "Errore durante reset dati" });
|
||||
}
|
||||
});
|
||||
|
||||
// Create sample data (3 sites Milano + 3 Roccapiemonte, 10 guards each)
|
||||
app.post("/api/dev/seed-data", isAuthenticated, async (req, res) => {
|
||||
try {
|
||||
// Create service types first
|
||||
const [serviceTypePresidioFisso] = await db.insert(serviceTypes).values({
|
||||
name: "Presidio Fisso",
|
||||
description: "Servizio di presidio fisso con guardia armata",
|
||||
shiftType: "fixed_post",
|
||||
fixedPostHours: 24,
|
||||
}).returning();
|
||||
|
||||
const [serviceTypePattuglia] = await db.insert(serviceTypes).values({
|
||||
name: "Pattuglia Mobile",
|
||||
description: "Servizio di pattuglia mobile con passaggi programmati",
|
||||
shiftType: "patrol",
|
||||
patrolPassages: 4,
|
||||
}).returning();
|
||||
|
||||
// Create 3 sites for Milano
|
||||
const [siteMilano1] = await db.insert(sites).values({
|
||||
name: "Banca Centrale Milano",
|
||||
address: "Via Dante 45, Milano",
|
||||
city: "Milano",
|
||||
location: "milano",
|
||||
serviceTypeId: serviceTypePresidioFisso.id,
|
||||
shiftType: "fixed_post",
|
||||
requiresArmed: true,
|
||||
requiresDriverLicense: false,
|
||||
minGuardsRequired: 1,
|
||||
serviceStartTime: "00:00",
|
||||
serviceEndTime: "24:00",
|
||||
contractReference: "CTR-MI-001-2025",
|
||||
contractStartDate: "2025-01-01",
|
||||
contractEndDate: "2025-12-31",
|
||||
}).returning();
|
||||
|
||||
const [siteMilano2] = await db.insert(sites).values({
|
||||
name: "Museo Arte Moderna Milano",
|
||||
address: "Corso Magenta 12, Milano",
|
||||
city: "Milano",
|
||||
location: "milano",
|
||||
serviceTypeId: serviceTypePattuglia.id,
|
||||
shiftType: "patrol",
|
||||
requiresArmed: false,
|
||||
requiresDriverLicense: true,
|
||||
minGuardsRequired: 1,
|
||||
serviceStartTime: "08:00",
|
||||
serviceEndTime: "20:00",
|
||||
contractReference: "CTR-MI-002-2025",
|
||||
contractStartDate: "2025-01-01",
|
||||
contractEndDate: "2025-06-30",
|
||||
}).returning();
|
||||
|
||||
const [siteMilano3] = await db.insert(sites).values({
|
||||
name: "Centro Commerciale Porta Nuova",
|
||||
address: "Piazza Gae Aulenti 1, Milano",
|
||||
city: "Milano",
|
||||
location: "milano",
|
||||
serviceTypeId: serviceTypePresidioFisso.id,
|
||||
shiftType: "fixed_post",
|
||||
requiresArmed: true,
|
||||
requiresDriverLicense: false,
|
||||
minGuardsRequired: 2,
|
||||
serviceStartTime: "06:00",
|
||||
serviceEndTime: "22:00",
|
||||
contractReference: "CTR-MI-003-2025",
|
||||
contractStartDate: "2025-01-01",
|
||||
contractEndDate: "2025-12-31",
|
||||
}).returning();
|
||||
|
||||
// Create 3 sites for Roccapiemonte
|
||||
const [siteRocca1] = await db.insert(sites).values({
|
||||
name: "Deposito Logistica Roccapiemonte",
|
||||
address: "Via Industriale 23, Roccapiemonte",
|
||||
city: "Roccapiemonte",
|
||||
location: "roccapiemonte",
|
||||
serviceTypeId: serviceTypePresidioFisso.id,
|
||||
shiftType: "fixed_post",
|
||||
requiresArmed: true,
|
||||
requiresDriverLicense: false,
|
||||
minGuardsRequired: 1,
|
||||
serviceStartTime: "00:00",
|
||||
serviceEndTime: "24:00",
|
||||
contractReference: "CTR-RC-001-2025",
|
||||
contractStartDate: "2025-01-01",
|
||||
contractEndDate: "2025-12-31",
|
||||
}).returning();
|
||||
|
||||
const [siteRocca2] = await db.insert(sites).values({
|
||||
name: "Cantiere Edile Salerno Nord",
|
||||
address: "SS 18 km 45, Roccapiemonte",
|
||||
city: "Roccapiemonte",
|
||||
location: "roccapiemonte",
|
||||
serviceTypeId: serviceTypePattuglia.id,
|
||||
shiftType: "patrol",
|
||||
requiresArmed: false,
|
||||
requiresDriverLicense: true,
|
||||
minGuardsRequired: 1,
|
||||
serviceStartTime: "18:00",
|
||||
serviceEndTime: "06:00",
|
||||
contractReference: "CTR-RC-002-2025",
|
||||
contractStartDate: "2025-01-15",
|
||||
contractEndDate: "2025-07-15",
|
||||
}).returning();
|
||||
|
||||
const [siteRocca3] = await db.insert(sites).values({
|
||||
name: "Stabilimento Farmaceutico",
|
||||
address: "Via delle Industrie 89, Roccapiemonte",
|
||||
city: "Roccapiemonte",
|
||||
location: "roccapiemonte",
|
||||
serviceTypeId: serviceTypePresidioFisso.id,
|
||||
shiftType: "fixed_post",
|
||||
requiresArmed: true,
|
||||
requiresDriverLicense: false,
|
||||
minGuardsRequired: 2,
|
||||
serviceStartTime: "00:00",
|
||||
serviceEndTime: "24:00",
|
||||
contractReference: "CTR-RC-003-2025",
|
||||
contractStartDate: "2025-01-01",
|
||||
contractEndDate: "2025-12-31",
|
||||
}).returning();
|
||||
|
||||
// Create 10 guards for Milano
|
||||
const milanNames = [
|
||||
{ firstName: "Marco", lastName: "Rossi", badgeNumber: "MI-001" },
|
||||
{ firstName: "Giulia", lastName: "Bianchi", badgeNumber: "MI-002" },
|
||||
{ firstName: "Luca", lastName: "Ferrari", badgeNumber: "MI-003" },
|
||||
{ firstName: "Sara", lastName: "Romano", badgeNumber: "MI-004" },
|
||||
{ firstName: "Andrea", lastName: "Colombo", badgeNumber: "MI-005" },
|
||||
{ firstName: "Elena", lastName: "Ricci", badgeNumber: "MI-006" },
|
||||
{ firstName: "Francesco", lastName: "Marino", badgeNumber: "MI-007" },
|
||||
{ firstName: "Chiara", lastName: "Greco", badgeNumber: "MI-008" },
|
||||
{ firstName: "Matteo", lastName: "Bruno", badgeNumber: "MI-009" },
|
||||
{ firstName: "Alessia", lastName: "Gallo", badgeNumber: "MI-010" },
|
||||
];
|
||||
|
||||
for (let i = 0; i < milanNames.length; i++) {
|
||||
await db.insert(guards).values({
|
||||
...milanNames[i],
|
||||
location: "milano",
|
||||
isArmed: i % 2 === 0, // Alternare armati/non armati
|
||||
hasDriverLicense: i % 3 === 0, // 1 su 3 con patente
|
||||
hasFireSafety: true,
|
||||
hasFirstAid: i % 2 === 1,
|
||||
phone: `+39 333 ${String(i).padStart(3, '0')}${String(i).padStart(4, '0')}`,
|
||||
email: `${milanNames[i].firstName.toLowerCase()}.${milanNames[i].lastName.toLowerCase()}@vigilanza.it`,
|
||||
});
|
||||
}
|
||||
|
||||
// Create 10 guards for Roccapiemonte
|
||||
const roccaNames = [
|
||||
{ firstName: "Antonio", lastName: "Esposito", badgeNumber: "RC-001" },
|
||||
{ firstName: "Maria", lastName: "De Luca", badgeNumber: "RC-002" },
|
||||
{ firstName: "Giuseppe", lastName: "Russo", badgeNumber: "RC-003" },
|
||||
{ firstName: "Anna", lastName: "Costa", badgeNumber: "RC-004" },
|
||||
{ firstName: "Vincenzo", lastName: "Ferrara", badgeNumber: "RC-005" },
|
||||
{ firstName: "Rosa", lastName: "Gatti", badgeNumber: "RC-006" },
|
||||
{ firstName: "Salvatore", lastName: "Leone", badgeNumber: "RC-007" },
|
||||
{ firstName: "Lucia", lastName: "Longo", badgeNumber: "RC-008" },
|
||||
{ firstName: "Michele", lastName: "Martino", badgeNumber: "RC-009" },
|
||||
{ firstName: "Carmela", lastName: "Moretti", badgeNumber: "RC-010" },
|
||||
];
|
||||
|
||||
for (let i = 0; i < roccaNames.length; i++) {
|
||||
await db.insert(guards).values({
|
||||
...roccaNames[i],
|
||||
location: "roccapiemonte",
|
||||
isArmed: i % 2 === 0,
|
||||
hasDriverLicense: i % 3 === 0,
|
||||
hasFireSafety: true,
|
||||
hasFirstAid: i % 2 === 1,
|
||||
phone: `+39 333 ${String(i + 10).padStart(3, '0')}${String(i + 10).padStart(4, '0')}`,
|
||||
email: `${roccaNames[i].firstName.toLowerCase()}.${roccaNames[i].lastName.toLowerCase()}@vigilanza.it`,
|
||||
});
|
||||
}
|
||||
|
||||
// Create 5 vehicles for Milano
|
||||
const vehiclesMilano = [
|
||||
{ licensePlate: "MI123AB", brand: "Fiat", model: "Ducato", vehicleType: "van" as const },
|
||||
{ licensePlate: "MI456CD", brand: "Volkswagen", model: "Transporter", vehicleType: "van" as const },
|
||||
{ licensePlate: "MI789EF", brand: "Ford", model: "Transit", vehicleType: "van" as const },
|
||||
{ licensePlate: "MI012GH", brand: "Renault", model: "Kangoo", vehicleType: "car" as const },
|
||||
{ licensePlate: "MI345IJ", brand: "Opel", model: "Vivaro", vehicleType: "van" as const },
|
||||
];
|
||||
|
||||
for (const vehicle of vehiclesMilano) {
|
||||
await db.insert(vehicles).values({
|
||||
...vehicle,
|
||||
location: "milano",
|
||||
year: 2022,
|
||||
status: "available",
|
||||
});
|
||||
}
|
||||
|
||||
// Create 5 vehicles for Roccapiemonte
|
||||
const vehiclesRocca = [
|
||||
{ licensePlate: "SA123AB", brand: "Fiat", model: "Ducato", vehicleType: "van" as const },
|
||||
{ licensePlate: "SA456CD", brand: "Volkswagen", model: "Caddy", vehicleType: "car" as const },
|
||||
{ licensePlate: "SA789EF", brand: "Ford", model: "Transit", vehicleType: "van" as const },
|
||||
{ licensePlate: "SA012GH", brand: "Renault", model: "Master", vehicleType: "van" as const },
|
||||
{ licensePlate: "SA345IJ", brand: "Peugeot", model: "Partner", vehicleType: "car" as const },
|
||||
];
|
||||
|
||||
for (const vehicle of vehiclesRocca) {
|
||||
await db.insert(vehicles).values({
|
||||
...vehicle,
|
||||
location: "roccapiemonte",
|
||||
year: 2023,
|
||||
status: "available",
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: "Dati di esempio creati con successo",
|
||||
summary: {
|
||||
sites: {
|
||||
milano: 3,
|
||||
roccapiemonte: 3,
|
||||
},
|
||||
guards: {
|
||||
milano: 10,
|
||||
roccapiemonte: 10,
|
||||
},
|
||||
vehicles: {
|
||||
milano: 5,
|
||||
roccapiemonte: 5,
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error seeding data:", error);
|
||||
res.status(500).json({ message: "Errore durante creazione dati di esempio" });
|
||||
}
|
||||
});
|
||||
|
||||
const httpServer = createServer(app);
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user