diff --git a/importersFixed.md b/importersFixed.md index 050c3d0..acdbd89 100644 --- a/importersFixed.md +++ b/importersFixed.md @@ -1,6 +1,6 @@ - [x] Import users - [x] Import artefacts -- [ ] Import earthquakes +- [x] Import earthquakes - [ ] Import observatoies - [ ] Import requests - [ ] Import scientists diff --git a/src/app/api/import-earthquakes/route.ts b/src/app/api/import-earthquakes/route.ts index 7712819..a42c6fb 100644 --- a/src/app/api/import-earthquakes/route.ts +++ b/src/app/api/import-earthquakes/route.ts @@ -1,10 +1,10 @@ import { parse } from "csv-parse/sync"; import fs from "fs/promises"; import { NextResponse } from "next/server"; -import { prisma } from "@utils/prisma"; import path from "path"; +import { prisma } from "@utils/prisma"; +import { getRandomNumber } from "@utils/maths"; -// Path to your earthquakes.csv const csvFilePath = path.resolve(process.cwd(), "public/earthquakes.csv"); type CsvRow = { @@ -20,31 +20,60 @@ type CsvRow = { export async function POST() { try { - // 1. Read the CSV file const fileContent = await fs.readFile(csvFilePath, "utf8"); - // 2. Parse the CSV const records: CsvRow[] = parse(fileContent, { columns: true, skip_empty_lines: true, }); - // 3. Transform to fit Earthquake model - const earthquakes = records.map((row) => ({ - date: new Date(row.Date), - code: row.Code, - magnitude: parseFloat(row.Magnitude), - type: row.Type, - latitude: parseFloat(row.Latitude), - longitude: parseFloat(row.Longitude), - location: row.Location, - depth: row.Depth, // store as received - // todo add random selection for creatorId - creatorId: null, - })); - // 4. Bulk create earthquakes in database: + + const failedImports: { row: CsvRow; reason: string }[] = []; + + const earthquakes = await Promise.all( + records.map(async (row) => { + 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) { + failedImports.push({ row, reason: `RandomCreator: ${randomCreator}` }); + return null; + } + + return { + date: new Date(row.Date), + code: row.Code, + magnitude: parseFloat(row.Magnitude), + type: row.Type, + latitude: parseFloat(row.Latitude), + longitude: parseFloat(row.Longitude), + location: row.Location, + depth: row.Depth, + creatorId: randomCreator.id, + }; + }) + ); + + const validEarthquakes = earthquakes.filter( + (earthquake): earthquake is NonNullable => earthquake !== null + ); + await prisma.earthquake.createMany({ - data: earthquakes, + data: validEarthquakes, + }); + + if (failedImports.length > 0) { + console.warn("Failed imports:", failedImports); + await fs.writeFile(path.resolve(process.cwd(), "failed_imports_earthquakes.json"), JSON.stringify(failedImports, null, 2)); + } + + return NextResponse.json({ + success: true, + count: validEarthquakes.length, + failedCount: failedImports.length, }); - return NextResponse.json({ success: true, count: earthquakes.length }); } catch (error: any) { console.error(error); return NextResponse.json({ success: false, error: error.message }, { status: 500 });