Fixed import artefacts and added imageName to artefact

This commit is contained in:
Tim Howitz 2025-05-22 17:59:20 +01:00
parent 885e694ad2
commit cb6dd05071
5 changed files with 95 additions and 71 deletions

6
importersFixed.md Normal file
View File

@ -0,0 +1,6 @@
- [ ] Import users
- [x] Import artefacts
- [ ] Import earthquakes
- [ ] Import observatoies
- [ ] Import requests
- [ ] Import scientists

View File

@ -91,6 +91,7 @@ model Artefact {
type String @db.VarChar(50) // Lava, Tephra, Ash, Soil type String @db.VarChar(50) // Lava, Tephra, Ash, Soil
warehouseArea String warehouseArea String
description String description String
imageName String
earthquakeId Int earthquakeId Int
earthquake Earthquake @relation(fields: [earthquakeId], references: [id]) earthquake Earthquake @relation(fields: [earthquakeId], references: [id])
creatorId Int? creatorId Int?

View File

@ -1,4 +1,4 @@
Name,Type,WarehouseArea,Description,earthquakeID,Price,Required,PickedUp,Picture Name,Type,WarehouseArea,Description,EarthquakeCode,Price,Required,PickedUp,Picture
Echo Bomb,Lava,ShelvingAreaA,A dense glossy black volcanic bomb with minor vesicles.,EV-7.4-Mexico-00035,120,no,no,EchoBomb.PNG Echo Bomb,Lava,ShelvingAreaA,A dense glossy black volcanic bomb with minor vesicles.,EV-7.4-Mexico-00035,120,no,no,EchoBomb.PNG
Silvershade Ash,Ash,ShelvingAreaD,Fine light-grey volcanic ash collected near a village.,EV-6.0-Iceland-00018,40,no,no,SilvershadeAsh.PNG Silvershade Ash,Ash,ShelvingAreaD,Fine light-grey volcanic ash collected near a village.,EV-6.0-Iceland-00018,40,no,no,SilvershadeAsh.PNG
Strata Core,Soil,LoggingArea,Soil core with visible stratification showing evidence of liquefaction.,ET-6.9-Brazil-00046,30,no,no,StrataCore.PNG Strata Core,Soil,LoggingArea,Soil core with visible stratification showing evidence of liquefaction.,ET-6.9-Brazil-00046,30,no,no,StrataCore.PNG

1 Name Type WarehouseArea Description earthquakeID EarthquakeCode Price Required PickedUp Picture
2 Echo Bomb Lava ShelvingAreaA A dense glossy black volcanic bomb with minor vesicles. EV-7.4-Mexico-00035 120 no no EchoBomb.PNG
3 Silvershade Ash Ash ShelvingAreaD Fine light-grey volcanic ash collected near a village. EV-6.0-Iceland-00018 40 no no SilvershadeAsh.PNG
4 Strata Core Soil LoggingArea Soil core with visible stratification showing evidence of liquefaction. ET-6.9-Brazil-00046 30 no no StrataCore.PNG

View File

@ -0,0 +1,87 @@
import { parse } from "csv-parse/sync";
import fs from "fs/promises";
import { NextResponse } from "next/server";
import path from "path";
import { stringToBool } from "@utils/parsingUtils";
import { prisma } from "@utils/prisma";
import { getRandomNumber } from "@utils/maths";
const csvFilePath = path.resolve(process.cwd(), "public/artefacts.csv");
type CsvRow = {
Type: string;
Name: string;
Description: string;
WarehouseArea: string;
EarthquakeCode: string;
Required?: string;
Price: string;
PickedUp?: string;
Picture: string;
};
export async function POST() {
try {
const fileContent = await fs.readFile(csvFilePath, "utf8");
const records: CsvRow[] = parse(fileContent, {
columns: true,
skip_empty_lines: true,
});
const failedImports: { row: CsvRow; reason: string }[] = [];
const artefacts = await Promise.all(
records.map(async (row) => {
const earthquake = await prisma.earthquake.findUnique({
where: { code: row.EarthquakeCode },
});
const creators = await prisma.user.findMany({
where: {
role: { in: ["SCIENTIST", "ADMIN"] },
},
});
const randomCreator = creators.length > 0 ? creators[getRandomNumber(0, creators.length - 1)] : null;
if (!earthquake || !randomCreator) {
failedImports.push({ row, reason: `Earthquake: ${earthquake}, RandomCreator: ${randomCreator}` });
return undefined;
}
return {
name: row.Name,
description: row.Description,
type: row.Type,
warehouseArea: row.WarehouseArea,
earthquakeId: earthquake.id,
required: stringToBool(row.Required, true),
shopPrice: row.Price && row.Price !== "" ? parseFloat(row.Price) : getRandomNumber(20, 500),
pickedUp: stringToBool(row.PickedUp, false),
creatorId: randomCreator.id,
purchasedById: null,
imageName: row.Picture,
};
})
);
const validArtefacts = artefacts.filter((artefact): artefact is NonNullable<typeof artefact> => artefact !== undefined);
await prisma.artefact.createMany({
data: validArtefacts,
});
if (failedImports.length > 0) {
console.warn("Failed imports:", failedImports);
await fs.writeFile(path.resolve(process.cwd(), "failed_imports_artefacts.json"), JSON.stringify(failedImports, null, 2));
}
return NextResponse.json({
success: true,
count: validArtefacts.length,
failedCount: failedImports.length,
});
} catch (error: any) {
console.error(error);
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}

View File

@ -1,70 +0,0 @@
import { parse } from "csv-parse/sync";
import fs from "fs/promises";
import { NextResponse } from "next/server";
import path from "path";
import { PrismaClient } from "@prismaclient";
// CSV location
const csvFilePath = path.resolve(process.cwd(), "public/artefacts.csv");
const prisma = new PrismaClient();
type CsvRow = {
Type: string;
Name: string;
Description: string;
WarehouseArea: string;
EarthquakeId: string;
Required?: string;
ShopPrice?: string;
PickedUp?: string;
};
function stringToBool(val: string | undefined, defaultValue: boolean = false): boolean {
if (!val) return defaultValue;
return /^true$/i.test(val.trim());
}
export async function POST() {
try {
// 1. Read file
const fileContent = await fs.readFile(csvFilePath, "utf8");
// 2. Parse CSV
const records: CsvRow[] = parse(fileContent, {
columns: true,
skip_empty_lines: true,
});
// 3. Map records to artefact input
const artefacts = records.map((row) => ({
name: row.Name,
description: row.Description,
type: row.Type,
warehouseArea: row.WarehouseArea,
// todo get earthquakeId where code === row.EarthquakeCode
earthquakeId: parseInt(row.EarthquakeId, 10),
required: stringToBool(row.Required, true), // default TRUE
shopPrice: row.ShopPrice && row.ShopPrice !== "" ? parseFloat(row.ShopPrice) : null,
pickedUp: stringToBool(row.PickedUp, false), // default FALSE
// todo add random selection for creatorId
creatorId: null,
purchasedById: null,
}));
// 4. Bulk insert
await prisma.artefact.createMany({
data: artefacts,
});
return NextResponse.json({
success: true,
count: artefacts.length,
});
} catch (error: any) {
console.error(error);
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
} finally {
await prisma.$disconnect();
}
}