189 lines
4.8 KiB
TypeScript
189 lines
4.8 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { MongoClient, Db, Collection, ObjectId } from 'mongodb';
|
|
|
|
// MongoDB connection
|
|
let client: MongoClient | null = null;
|
|
let db: Db | null = null;
|
|
|
|
async function getDatabase(): Promise<Db> {
|
|
if (!client) {
|
|
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017';
|
|
client = new MongoClient(uri);
|
|
await client.connect();
|
|
db = client.db('beanstalk');
|
|
}
|
|
return db!;
|
|
}
|
|
|
|
function convertMongoExtendedJSON(obj: any): any {
|
|
if (obj === null || obj === undefined) {
|
|
return obj;
|
|
}
|
|
|
|
if (Array.isArray(obj)) {
|
|
return obj.map(item => convertMongoExtendedJSON(item));
|
|
}
|
|
|
|
if (typeof obj === 'object') {
|
|
const converted: any = {};
|
|
|
|
for (const [key, value] of Object.entries(obj)) {
|
|
if (key === '$oid' && typeof value === 'string') {
|
|
return new ObjectId(value);
|
|
} else if (key === '$date' && typeof value === 'string') {
|
|
return new Date(value);
|
|
} else {
|
|
converted[key] = convertMongoExtendedJSON(value);
|
|
}
|
|
}
|
|
|
|
return converted;
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const filename = searchParams.get('file');
|
|
|
|
if (!filename) {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'file parameter is required',
|
|
message: 'Usage: /api/import-json?file=db_prod.akademyObservations.json'
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Read JSON file
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const filePath = path.join(process.cwd(), '..', filename);
|
|
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
const rawDocuments = JSON.parse(fileContent);
|
|
|
|
// Convert MongoDB extended JSON to proper MongoDB documents
|
|
const documents = rawDocuments.map((doc: any) => convertMongoExtendedJSON(doc));
|
|
|
|
// Get MongoDB collection
|
|
const db = await getDatabase();
|
|
const collection = db.collection('observations');
|
|
|
|
// Insert documents
|
|
const result = await collection.insertMany(documents);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: `Successfully imported ${result.insertedCount} observations`,
|
|
inserted_count: result.insertedCount,
|
|
inserted_ids: Object.values(result.insertedIds)
|
|
});
|
|
|
|
} catch (error: any) {
|
|
console.error('Import error:', error);
|
|
|
|
if (error.code === 'ENOENT') {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'File not found',
|
|
message: `The file was not found`
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
if (error.name === 'SyntaxError') {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to parse JSON',
|
|
message: error.message
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to import data',
|
|
message: error.message
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const formData = await request.formData();
|
|
const file = formData.get('file') as File;
|
|
|
|
if (!file) {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'No file provided',
|
|
message: 'Please select a JSON file to upload'
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Validate file type
|
|
if (!file.type.includes('json')) {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Invalid file type',
|
|
message: 'Please upload a JSON file'
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Read file content
|
|
const fileContent = await file.text();
|
|
const rawDocuments = JSON.parse(fileContent);
|
|
|
|
// Convert MongoDB extended JSON to proper MongoDB documents
|
|
const documents = rawDocuments.map((doc: any) => convertMongoExtendedJSON(doc));
|
|
|
|
// Get MongoDB collection
|
|
const db = await getDatabase();
|
|
const collection = db.collection('observations');
|
|
|
|
// Insert documents
|
|
const result = await collection.insertMany(documents);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: `Successfully imported ${result.insertedCount} observations from ${file.name}`,
|
|
inserted_count: result.insertedCount,
|
|
inserted_ids: Object.values(result.insertedIds),
|
|
filename: file.name,
|
|
size: `${(file.size / 1024).toFixed(2)} KB`
|
|
});
|
|
|
|
} catch (error: any) {
|
|
console.error('Import error:', error);
|
|
|
|
if (error.name === 'SyntaxError') {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to parse JSON',
|
|
message: error.message
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to import data',
|
|
message: error.message
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|