Optimised imoprt earthquakes

This commit is contained in:
Tim Howitz 2025-05-26 14:40:06 +01:00
parent 8a48857ac0
commit a8fe047019

View File

@ -42,63 +42,61 @@ export async function POST() {
const failedImports: { row: CsvRow; reason: string }[] = []; const failedImports: { row: CsvRow; reason: string }[] = [];
// Fetch all observatories once to avoid repeated queries // Fetch all observatories and users once
const observatories = await prisma.observatory.findMany({ const observatories = await prisma.observatory.findMany({
select: { id: true, latitude: true, longitude: true }, select: { id: true, latitude: true, longitude: true },
}); });
const creators = await prisma.user.findMany({
where: { role: { in: ["SCIENTIST", "ADMIN"] } },
});
const earthquakes = await Promise.all( const earthquakes = records.map((row) => {
records.map(async (row) => { const randomCreator = creators.length > 0 ? creators[getRandomNumber(0, creators.length - 1)] : null;
const creators = await prisma.user.findMany({
where: { role: { in: ["SCIENTIST", "ADMIN"] } },
});
const randomCreator = creators.length > 0 ? creators[getRandomNumber(0, creators.length - 1)] : null;
if (!randomCreator) { if (!randomCreator) {
failedImports.push({ row, reason: `RandomCreator: ${randomCreator}` }); failedImports.push({ row, reason: `No creator found` });
return null; return null;
}
const eqLat = parseFloat(row.Latitude);
const eqLon = parseFloat(row.Longitude);
// Find observatories within distance threshold
let nearbyObservatories = observatories
.map((obs) => ({
id: obs.id,
distance: getDistance(eqLat, eqLon, obs.latitude, obs.longitude),
}))
.filter((obs) => obs.distance <= DISTANCE_THRESHOLD_KM)
.map((obs) => ({ id: obs.id }));
// If no observatories within range, find the nearest one
if (nearbyObservatories.length === 0) {
const nearest = observatories.reduce(
(min, obs) => {
const distance = getDistance(eqLat, eqLon, obs.latitude, obs.longitude);
return distance < min.distance ? { id: obs.id, distance } : min;
},
{ id: -1, distance: Infinity }
);
if (nearest.id !== -1) {
nearbyObservatories = [{ id: nearest.id }];
} }
}
const eqLat = parseFloat(row.Latitude); return {
const eqLon = parseFloat(row.Longitude); date: new Date(row.Date),
code: row.Code,
// Find observatories within distance threshold magnitude: parseFloat(row.Magnitude),
let nearbyObservatories = observatories type: row.Type,
.map((obs) => ({ latitude: eqLat,
id: obs.id, longitude: eqLon,
distance: getDistance(eqLat, eqLon, obs.latitude, obs.longitude), location: row.Location,
})) depth: row.Depth,
.filter((obs) => obs.distance <= DISTANCE_THRESHOLD_KM) creatorId: randomCreator.id,
.map((obs) => ({ id: obs.id })); observatories: { connect: nearbyObservatories },
};
// If no observatories within range, find the nearest one });
if (nearbyObservatories.length === 0) {
const nearest = observatories.reduce(
(min, obs) => {
const distance = getDistance(eqLat, eqLon, obs.latitude, obs.longitude);
return distance < min.distance ? { id: obs.id, distance } : min;
},
{ id: -1, distance: Infinity }
);
if (nearest.id !== -1) {
nearbyObservatories = [{ id: nearest.id }];
}
}
return {
date: new Date(row.Date),
code: row.Code,
magnitude: parseFloat(row.Magnitude),
type: row.Type,
latitude: eqLat,
longitude: eqLon,
location: row.Location,
depth: row.Depth,
creatorId: randomCreator.id,
observatories: { connect: nearbyObservatories },
};
})
);
const validEarthquakes = earthquakes.filter( const validEarthquakes = earthquakes.filter(
(earthquake): earthquake is NonNullable<typeof earthquake> => earthquake !== null (earthquake): earthquake is NonNullable<typeof earthquake> => earthquake !== null