88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
|
|
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 });
|
||
|
|
}
|
||
|
|
}
|