Fixed import artefacts and added imageName to artefact
This commit is contained in:
parent
885e694ad2
commit
cb6dd05071
6
importersFixed.md
Normal file
6
importersFixed.md
Normal file
@ -0,0 +1,6 @@
|
||||
- [ ] Import users
|
||||
- [x] Import artefacts
|
||||
- [ ] Import earthquakes
|
||||
- [ ] Import observatoies
|
||||
- [ ] Import requests
|
||||
- [ ] Import scientists
|
||||
@ -91,6 +91,7 @@ model Artefact {
|
||||
type String @db.VarChar(50) // Lava, Tephra, Ash, Soil
|
||||
warehouseArea String
|
||||
description String
|
||||
imageName String
|
||||
earthquakeId Int
|
||||
earthquake Earthquake @relation(fields: [earthquakeId], references: [id])
|
||||
creatorId Int?
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
|
87
src/app/api/import-artefacts/route.ts
Normal file
87
src/app/api/import-artefacts/route.ts
Normal 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 });
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user