Switched to local prismaclient
This commit is contained in:
parent
de02f94f6a
commit
1bd327ea1a
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -55,6 +55,7 @@
|
|||||||
},
|
},
|
||||||
"importSorter.generalConfiguration.sortOnBeforeSave": true,
|
"importSorter.generalConfiguration.sortOnBeforeSave": true,
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"prismaclient",
|
||||||
"vars"
|
"vars"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
1140
package-lock.json
generated
1140
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
"@types/bcryptjs": "^5.0.2",
|
|
||||||
"@types/express": "^5.0.1",
|
"@types/express": "^5.0.1",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
@ -53,4 +52,4 @@
|
|||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
const usingPrisma = false;
|
const usingPrisma = false;
|
||||||
let prisma: PrismaClient;
|
let prisma: PrismaClient;
|
||||||
|
|||||||
@ -1,69 +1,65 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
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
|
// CSV location
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/artefacts.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/artefacts.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
Type: string;
|
Type: string;
|
||||||
WarehouseArea: string;
|
WarehouseArea: string;
|
||||||
EarthquakeId: string;
|
EarthquakeId: string;
|
||||||
Required?: string;
|
Required?: string;
|
||||||
ShopPrice?: string;
|
ShopPrice?: string;
|
||||||
PickedUp?: string;
|
PickedUp?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function stringToBool(val: string | undefined, defaultValue: boolean = false): boolean {
|
function stringToBool(val: string | undefined, defaultValue: boolean = false): boolean {
|
||||||
if (!val) return defaultValue;
|
if (!val) return defaultValue;
|
||||||
return /^true$/i.test(val.trim());
|
return /^true$/i.test(val.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// 1. Read file
|
// 1. Read file
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
|
|
||||||
// 2. Parse CSV
|
// 2. Parse CSV
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true,
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Map records to artefact input
|
// 3. Map records to artefact input
|
||||||
const artefacts = records.map((row) => ({
|
const artefacts = records.map((row) => ({
|
||||||
type: row.Type,
|
type: row.Type,
|
||||||
warehouseArea: row.WarehouseArea,
|
warehouseArea: row.WarehouseArea,
|
||||||
earthquakeId: parseInt(row.EarthquakeId, 10),
|
earthquakeId: parseInt(row.EarthquakeId, 10),
|
||||||
required: stringToBool(row.Required, true), // default TRUE
|
required: stringToBool(row.Required, true), // default TRUE
|
||||||
shopPrice: row.ShopPrice && row.ShopPrice !== ""
|
shopPrice: row.ShopPrice && row.ShopPrice !== "" ? parseFloat(row.ShopPrice) : null,
|
||||||
? parseFloat(row.ShopPrice)
|
pickedUp: stringToBool(row.PickedUp, false), // default FALSE
|
||||||
: null,
|
creatorId: null,
|
||||||
pickedUp: stringToBool(row.PickedUp, false), // default FALSE
|
purchasedById: null,
|
||||||
creatorId: null,
|
}));
|
||||||
purchasedById: null,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 4. Bulk insert
|
// 4. Bulk insert
|
||||||
await prisma.artefact.createMany({
|
await prisma.artefact.createMany({
|
||||||
data: artefacts,
|
data: artefacts,
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
count: artefacts.length,
|
count: artefacts.length,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json(
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
{ success: false, error: error.message },
|
} finally {
|
||||||
{ status: 500 }
|
await prisma.$disconnect();
|
||||||
);
|
}
|
||||||
} finally {
|
}
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,55 +1,56 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
import { parse } from "csv-parse/sync";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
// Path to your earthquakes.csv
|
// Path to your earthquakes.csv
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/earthquakes.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/earthquakes.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
Date: string;
|
Date: string;
|
||||||
Code: string;
|
Code: string;
|
||||||
Magnitude: string;
|
Magnitude: string;
|
||||||
Type: string;
|
Type: string;
|
||||||
Latitude: string;
|
Latitude: string;
|
||||||
Longitude: string;
|
Longitude: string;
|
||||||
Location: string;
|
Location: string;
|
||||||
Depth: string;
|
Depth: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// 1. Read the CSV file
|
// 1. Read the CSV file
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
// 2. Parse the CSV
|
// 2. Parse the CSV
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
// 3. Transform to fit Earthquake model
|
// 3. Transform to fit Earthquake model
|
||||||
const earthquakes = records.map(row => ({
|
const earthquakes = records.map((row) => ({
|
||||||
date: new Date(row.Date),
|
date: new Date(row.Date),
|
||||||
code: row.Code,
|
code: row.Code,
|
||||||
magnitude: parseFloat(row.Magnitude),
|
magnitude: parseFloat(row.Magnitude),
|
||||||
type: row.Type,
|
type: row.Type,
|
||||||
latitude: parseFloat(row.Latitude),
|
latitude: parseFloat(row.Latitude),
|
||||||
longitude: parseFloat(row.Longitude),
|
longitude: parseFloat(row.Longitude),
|
||||||
location: row.Location,
|
location: row.Location,
|
||||||
depth: row.Depth, // store as received
|
depth: row.Depth, // store as received
|
||||||
creatorId: null
|
creatorId: null,
|
||||||
}));
|
}));
|
||||||
// 4. Bulk create earthquakes in database:
|
// 4. Bulk create earthquakes in database:
|
||||||
await prisma.earthquake.createMany({
|
await prisma.earthquake.createMany({
|
||||||
data: earthquakes,
|
data: earthquakes,
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
});
|
});
|
||||||
return NextResponse.json({ success: true, count: earthquakes.length });
|
return NextResponse.json({ success: true, count: earthquakes.length });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
} finally {
|
} finally {
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,73 +1,67 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
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 (update filename as needed)
|
// CSV location (update filename as needed)
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/observatories.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/observatories.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
Name: string;
|
Name: string;
|
||||||
Location: string;
|
Location: string;
|
||||||
Latitude: string;
|
Latitude: string;
|
||||||
Longitude: string;
|
Longitude: string;
|
||||||
DateEstablished?: string;
|
DateEstablished?: string;
|
||||||
Functional: string;
|
Functional: string;
|
||||||
SeismicSensorOnline?: string;
|
SeismicSensorOnline?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function stringToBool(val: string | undefined): boolean {
|
function stringToBool(val: string | undefined): boolean {
|
||||||
// Accepts "TRUE", "true", "True", etc.
|
// Accepts "TRUE", "true", "True", etc.
|
||||||
if (!val) return false;
|
if (!val) return false;
|
||||||
return /^true$/i.test(val.trim());
|
return /^true$/i.test(val.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// 1. Read file
|
// 1. Read file
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
|
|
||||||
// 2. Parse CSV
|
// 2. Parse CSV
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true,
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Map records to Prisma inputs
|
// 3. Map records to Prisma inputs
|
||||||
const observatories = records.map((row) => ({
|
const observatories = records.map((row) => ({
|
||||||
name: row.Name,
|
name: row.Name,
|
||||||
location: row.Location,
|
location: row.Location,
|
||||||
latitude: row.Latitude,
|
latitude: row.Latitude,
|
||||||
longitude: row.Longitude,
|
longitude: row.Longitude,
|
||||||
dateEstablished: row.DateEstablished
|
dateEstablished: row.DateEstablished ? parseInt(row.DateEstablished, 10) : null,
|
||||||
? parseInt(row.DateEstablished, 10)
|
functional: stringToBool(row.Functional),
|
||||||
: null,
|
seismicSensorOnline: row.SeismicSensorOnline ? stringToBool(row.SeismicSensorOnline) : true, // default true per schema
|
||||||
functional: stringToBool(row.Functional),
|
creatorId: null,
|
||||||
seismicSensorOnline: row.SeismicSensorOnline
|
}));
|
||||||
? stringToBool(row.SeismicSensorOnline)
|
|
||||||
: true, // default true per schema
|
|
||||||
creatorId: null,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 4. Bulk insert
|
// 4. Bulk insert
|
||||||
await prisma.observatory.createMany({
|
await prisma.observatory.createMany({
|
||||||
data: observatories,
|
data: observatories,
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
count: observatories.length,
|
count: observatories.length,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json(
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
{ success: false, error: error.message },
|
} finally {
|
||||||
{ status: 500 }
|
await prisma.$disconnect();
|
||||||
);
|
}
|
||||||
} finally {
|
}
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
import { parse } from "csv-parse/sync";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/requests.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/requests.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
@ -11,58 +12,52 @@ type RequestType = "NEW_USER" | "CHANGE_LEVEL" | "DELETE";
|
|||||||
type RequestOutcome = "FULFILLED" | "REJECTED" | "IN_PROGRESS" | "CANCELLED" | "OTHER";
|
type RequestOutcome = "FULFILLED" | "REJECTED" | "IN_PROGRESS" | "CANCELLED" | "OTHER";
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
RequestType: string;
|
RequestType: string;
|
||||||
RequestingUserId: string;
|
RequestingUserId: string;
|
||||||
Outcome?: string;
|
Outcome?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const validRequestTypes: RequestType[] = ["NEW_USER", "CHANGE_LEVEL", "DELETE"];
|
const validRequestTypes: RequestType[] = ["NEW_USER", "CHANGE_LEVEL", "DELETE"];
|
||||||
const validOutcomes: RequestOutcome[] = [
|
const validOutcomes: RequestOutcome[] = ["FULFILLED", "REJECTED", "IN_PROGRESS", "CANCELLED", "OTHER"];
|
||||||
"FULFILLED",
|
|
||||||
"REJECTED",
|
|
||||||
"IN_PROGRESS",
|
|
||||||
"CANCELLED",
|
|
||||||
"OTHER",
|
|
||||||
];
|
|
||||||
|
|
||||||
function normalizeRequestType(type: string | undefined): RequestType {
|
function normalizeRequestType(type: string | undefined): RequestType {
|
||||||
if (!type) return "NEW_USER";
|
if (!type) return "NEW_USER";
|
||||||
const norm = type.trim().toUpperCase().replace(" ", "_");
|
const norm = type.trim().toUpperCase().replace(" ", "_");
|
||||||
return (validRequestTypes.includes(norm as RequestType) ? norm : "NEW_USER") as RequestType;
|
return (validRequestTypes.includes(norm as RequestType) ? norm : "NEW_USER") as RequestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeOutcome(outcome: string | undefined): RequestOutcome {
|
function normalizeOutcome(outcome: string | undefined): RequestOutcome {
|
||||||
if (!outcome) return "IN_PROGRESS";
|
if (!outcome) return "IN_PROGRESS";
|
||||||
const norm = outcome.trim().toUpperCase().replace(" ", "_");
|
const norm = outcome.trim().toUpperCase().replace(" ", "_");
|
||||||
return (validOutcomes.includes(norm as RequestOutcome) ? norm : "IN_PROGRESS") as RequestOutcome;
|
return (validOutcomes.includes(norm as RequestOutcome) ? norm : "IN_PROGRESS") as RequestOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true,
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const requests = records.map(row => ({
|
const requests = records.map((row) => ({
|
||||||
requestType: normalizeRequestType(row.RequestType),
|
requestType: normalizeRequestType(row.RequestType),
|
||||||
requestingUserId: parseInt(row.RequestingUserId, 10),
|
requestingUserId: parseInt(row.RequestingUserId, 10),
|
||||||
outcome: normalizeOutcome(row.Outcome),
|
outcome: normalizeOutcome(row.Outcome),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const filteredRequests = requests.filter(r => !isNaN(r.requestingUserId));
|
const filteredRequests = requests.filter((r) => !isNaN(r.requestingUserId));
|
||||||
|
|
||||||
await prisma.request.createMany({
|
await prisma.request.createMany({
|
||||||
data: filteredRequests,
|
data: filteredRequests,
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({ success: true, count: filteredRequests.length });
|
return NextResponse.json({ success: true, count: filteredRequests.length });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
} finally {
|
} finally {
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,57 +1,58 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
import { parse } from "csv-parse/sync";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
// Path to CSV file
|
// Path to CSV file
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/scientists.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/scientists.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
Name: string;
|
Name: string;
|
||||||
Level?: string;
|
Level?: string;
|
||||||
UserId: string;
|
UserId: string;
|
||||||
SuperiorId?: string;
|
SuperiorId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeLevel(level: string | undefined): string {
|
function normalizeLevel(level: string | undefined): string {
|
||||||
// Only allow JUNIOR, SENIOR; default JUNIOR
|
// Only allow JUNIOR, SENIOR; default JUNIOR
|
||||||
if (!level || !level.trim()) return "JUNIOR";
|
if (!level || !level.trim()) return "JUNIOR";
|
||||||
const lv = level.trim().toUpperCase();
|
const lv = level.trim().toUpperCase();
|
||||||
return ["JUNIOR", "SENIOR"].includes(lv) ? lv : "JUNIOR";
|
return ["JUNIOR", "SENIOR"].includes(lv) ? lv : "JUNIOR";
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// 1. Read the CSV file
|
// 1. Read the CSV file
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
|
|
||||||
// 2. Parse the CSV
|
// 2. Parse the CSV
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true,
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Transform each record for Prisma
|
// 3. Transform each record for Prisma
|
||||||
const scientists = records.map(row => ({
|
const scientists = records.map((row) => ({
|
||||||
name: row.Name,
|
name: row.Name,
|
||||||
level: normalizeLevel(row.Level),
|
level: normalizeLevel(row.Level),
|
||||||
userId: parseInt(row.UserId, 10),
|
userId: parseInt(row.UserId, 10),
|
||||||
superiorId: row.SuperiorId && row.SuperiorId.trim() !== "" ? parseInt(row.SuperiorId, 10) : null,
|
superiorId: row.SuperiorId && row.SuperiorId.trim() !== "" ? parseInt(row.SuperiorId, 10) : null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 4. Bulk create scientists in database
|
// 4. Bulk create scientists in database
|
||||||
await prisma.scientist.createMany({
|
await prisma.scientist.createMany({
|
||||||
data: scientists,
|
data: scientists,
|
||||||
skipDuplicates: true, // in case the scientist/userid combo already exists
|
skipDuplicates: true, // in case the scientist/userid combo already exists
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({ success: true, count: scientists.length });
|
return NextResponse.json({ success: true, count: scientists.length });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
} finally {
|
} finally {
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,57 +1,58 @@
|
|||||||
import { NextResponse } from "next/server";
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { parse } from "csv-parse/sync";
|
import { parse } from "csv-parse/sync";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
// Path to users.csv - adjust as needed
|
// Path to users.csv - adjust as needed
|
||||||
const csvFilePath = path.resolve(process.cwd(), "public/users.csv");
|
const csvFilePath = path.resolve(process.cwd(), "public/users.csv");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
type CsvRow = {
|
type CsvRow = {
|
||||||
Name: string;
|
Name: string;
|
||||||
Email: string;
|
Email: string;
|
||||||
PasswordHash: string;
|
PasswordHash: string;
|
||||||
Role?: string;
|
Role?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeRole(role: string | undefined): string {
|
function normalizeRole(role: string | undefined): string {
|
||||||
// Only allow ADMIN, SCIENTIST, GUEST; default GUEST
|
// Only allow ADMIN, SCIENTIST, GUEST; default GUEST
|
||||||
if (!role || !role.trim()) return "GUEST";
|
if (!role || !role.trim()) return "GUEST";
|
||||||
const r = role.trim().toUpperCase();
|
const r = role.trim().toUpperCase();
|
||||||
return ["ADMIN", "SCIENTIST", "GUEST"].includes(r) ? r : "GUEST";
|
return ["ADMIN", "SCIENTIST", "GUEST"].includes(r) ? r : "GUEST";
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// 1. Read the CSV file
|
// 1. Read the CSV file
|
||||||
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
const fileContent = await fs.readFile(csvFilePath, "utf8");
|
||||||
|
|
||||||
// 2. Parse the CSV
|
// 2. Parse the CSV
|
||||||
const records: CsvRow[] = parse(fileContent, {
|
const records: CsvRow[] = parse(fileContent, {
|
||||||
columns: true,
|
columns: true,
|
||||||
skip_empty_lines: true,
|
skip_empty_lines: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Transform each CSV row to User model format
|
// 3. Transform each CSV row to User model format
|
||||||
const users = records.map(row => ({
|
const users = records.map((row) => ({
|
||||||
name: row.Name,
|
name: row.Name,
|
||||||
email: row.Email,
|
email: row.Email,
|
||||||
passwordHash: row.PasswordHash,
|
passwordHash: row.PasswordHash,
|
||||||
role: normalizeRole(row.Role),
|
role: normalizeRole(row.Role),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 4. Bulk create users in database
|
// 4. Bulk create users in database
|
||||||
await prisma.user.createMany({
|
await prisma.user.createMany({
|
||||||
data: users,
|
data: users,
|
||||||
skipDuplicates: true, // because email is unique
|
skipDuplicates: true, // because email is unique
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({ success: true, count: users.length });
|
return NextResponse.json({ success: true, count: users.length });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||||
} finally {
|
} finally {
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import bcryptjs from 'bcryptjs';
|
import bcryptjs from "bcryptjs";
|
||||||
import { SignJWT } from 'jose';
|
import { SignJWT } from "jose";
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from "@prismaclient";
|
||||||
import { env } from '@utils/env';
|
import { env } from "@utils/env";
|
||||||
|
|
||||||
import { findUserByEmail, readUserCsv, User } from '../functions/csvReadWrite';
|
import { findUserByEmail, readUserCsv, User } from "../functions/csvReadWrite";
|
||||||
|
|
||||||
const usingPrisma = false;
|
const usingPrisma = false;
|
||||||
let prisma: PrismaClient;
|
let prisma: PrismaClient;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
const usingPrisma = false;
|
const usingPrisma = false;
|
||||||
let prisma: PrismaClient;
|
let prisma: PrismaClient;
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import bcryptjs from 'bcryptjs';
|
import bcryptjs from "bcryptjs";
|
||||||
import { SignJWT } from 'jose';
|
import { SignJWT } from "jose";
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from "@prismaclient";
|
||||||
import { env } from '@utils/env';
|
import { env } from "@utils/env";
|
||||||
|
|
||||||
import {
|
import { findUserByEmail, passwordStrengthCheck, readUserCsv, User, writeUserCsv } from "../functions/csvReadWrite";
|
||||||
findUserByEmail, passwordStrengthCheck, readUserCsv, User, writeUserCsv
|
|
||||||
} from '../functions/csvReadWrite';
|
|
||||||
|
|
||||||
const usingPrisma = false;
|
const usingPrisma = false;
|
||||||
let prisma: PrismaClient;
|
let prisma: PrismaClient;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { env } from "@utils/env";
|
|
||||||
|
|
||||||
import { PrismaClient } from "@prisma/client";
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
import { env } from "@utils/env";
|
||||||
import { verifyJwt } from "@utils/verifyJwt";
|
import { verifyJwt } from "@utils/verifyJwt";
|
||||||
|
|
||||||
const usingPrisma = false;
|
const usingPrisma = false;
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useMemo } from "react";
|
import { Dispatch, SetStateAction, useMemo, useState } from "react";
|
||||||
import { FaCalendarPlus, FaWarehouse, FaCartShopping } from "react-icons/fa6";
|
|
||||||
import { IoFilter, IoFilterCircleOutline, IoFilterOutline, IoToday } from "react-icons/io5";
|
|
||||||
import { FaTimes } from "react-icons/fa";
|
import { FaTimes } from "react-icons/fa";
|
||||||
import { SetStateAction, Dispatch } from "react";
|
import { FaCalendarPlus, FaCartShopping, FaWarehouse } from "react-icons/fa6";
|
||||||
// import type { Artefact } from "@prisma/client";
|
import { IoFilter, IoFilterCircleOutline, IoFilterOutline, IoToday } from "react-icons/io5";
|
||||||
import { Artefact } from "@appTypes/Prisma";
|
|
||||||
|
// import { Artefact } from "@appTypes/Prisma";
|
||||||
|
|
||||||
|
import type { Artefact } from "@prismaclient";
|
||||||
|
|
||||||
// Warehouse Artefacts Data
|
// Warehouse Artefacts Data
|
||||||
const warehouseArtefacts: Artefact[] = [
|
const warehouseArtefacts: Artefact[] = [
|
||||||
@ -14,7 +15,7 @@ const warehouseArtefacts: Artefact[] = [
|
|||||||
name: "Solidified Lava Chunk",
|
name: "Solidified Lava Chunk",
|
||||||
description: "A chunk of solidified lava from the 2023 Iceland eruption.",
|
description: "A chunk of solidified lava from the 2023 Iceland eruption.",
|
||||||
location: "Reykjanes, Iceland",
|
location: "Reykjanes, Iceland",
|
||||||
earthquakeId: "EQ2023ICL",
|
code: "EQ2023ICL",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
isSold: false,
|
isSold: false,
|
||||||
isCollected: false,
|
isCollected: false,
|
||||||
@ -25,7 +26,7 @@ const warehouseArtefacts: Artefact[] = [
|
|||||||
name: "Tephra Sample",
|
name: "Tephra Sample",
|
||||||
description: "Foreign debris from the 2022 Tonga volcanic eruption.",
|
description: "Foreign debris from the 2022 Tonga volcanic eruption.",
|
||||||
location: "Tonga",
|
location: "Tonga",
|
||||||
earthquakeId: "EQ2022TGA",
|
code: "EQ2022TGA",
|
||||||
isRequired: false,
|
isRequired: false,
|
||||||
isSold: true,
|
isSold: true,
|
||||||
isCollected: true,
|
isCollected: true,
|
||||||
@ -36,7 +37,7 @@ const warehouseArtefacts: Artefact[] = [
|
|||||||
name: "Ash Sample",
|
name: "Ash Sample",
|
||||||
description: "Volcanic ash from the 2021 La Palma eruption.",
|
description: "Volcanic ash from the 2021 La Palma eruption.",
|
||||||
location: "La Palma, Spain",
|
location: "La Palma, Spain",
|
||||||
earthquakeId: "EQ2021LPA",
|
code: "EQ2021LPA",
|
||||||
isRequired: false,
|
isRequired: false,
|
||||||
isSold: false,
|
isSold: false,
|
||||||
isCollected: false,
|
isCollected: false,
|
||||||
@ -47,7 +48,7 @@ const warehouseArtefacts: Artefact[] = [
|
|||||||
name: "Ground Soil",
|
name: "Ground Soil",
|
||||||
description: "Soil sample from the 2020 Croatia earthquake site.",
|
description: "Soil sample from the 2020 Croatia earthquake site.",
|
||||||
location: "Zagreb, Croatia",
|
location: "Zagreb, Croatia",
|
||||||
earthquakeId: "EQ2020CRO",
|
code: "EQ2020CRO",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
isSold: false,
|
isSold: false,
|
||||||
isCollected: false,
|
isCollected: false,
|
||||||
@ -58,7 +59,7 @@ const warehouseArtefacts: Artefact[] = [
|
|||||||
name: "Basalt Fragment",
|
name: "Basalt Fragment",
|
||||||
description: "Basalt rock from the 2019 New Zealand eruption.",
|
description: "Basalt rock from the 2019 New Zealand eruption.",
|
||||||
location: "White Island, New Zealand",
|
location: "White Island, New Zealand",
|
||||||
earthquakeId: "EQ2019NZL",
|
code: "EQ2019NZL",
|
||||||
isRequired: false,
|
isRequired: false,
|
||||||
isSold: true,
|
isSold: true,
|
||||||
isCollected: false,
|
isCollected: false,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { PrismaClient } from "@prisma/client";
|
import { PrismaClient } from "@prismaclient";
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
"@utils/*": ["./src/utils/*"],
|
"@utils/*": ["./src/utils/*"],
|
||||||
"@appTypes/*": ["./src/types/*"],
|
"@appTypes/*": ["./src/types/*"],
|
||||||
"@zod/*": ["./src/zod/*"],
|
"@zod/*": ["./src/zod/*"],
|
||||||
|
"@prismaclient": ["./src/generated/prisma/client"],
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user