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
|
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?
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
|
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