migrate from SQLite to PostgreSQL with Drizzle ORM

- Updated all packages to latest versions (React 19, Next.js 14.2.32)
- Replaced sqlite3 with pg and drizzle-orm dependencies
- Created complete PostgreSQL schema with relationships and indexes
- Migrated all API endpoints from SQLite to Drizzle queries
- Added database seeding with sample data
- Updated authentication to use bcrypt instead of pbkdf2
- Configured connection pooling for PostgreSQL
- Updated app version to 1.0.0
- All endpoints tested and working correctly
This commit is contained in:
2025-09-06 12:56:33 +02:00
parent 52bde64e7f
commit 860070a302
26 changed files with 2526 additions and 2403 deletions

View File

@@ -1,10 +1,10 @@
import type { NextApiRequest, NextApiResponse } from "next"
import sqlite3 from "sqlite3"
import path from "path"
import { db, schema } from "../../../lib/db/connection"
import { eq } from "drizzle-orm"
interface BulkImportItem {
domain: string
risk_level: number
riskLevel: number
categories: string[]
description?: string
}
@@ -18,63 +18,57 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
return res.status(400).json({ error: "Sources array required" })
}
const dbPath = path.join(process.cwd(), "database", "antihoax.db")
const db = new sqlite3.Database(dbPath)
try {
let imported = 0
let skipped = 0
for (const source of sources) {
if (!source.domain || !source.risk_level) {
if (!source.domain || !source.riskLevel) {
skipped++
continue
}
// Check if domain already exists
const existing = await new Promise<any>((resolve, reject) => {
db.get(
"SELECT id FROM sources WHERE domain = ?",
[source.domain],
(err, row) => {
if (err) reject(err)
else resolve(row)
}
)
})
// Check if source already exists
const existing = await db.select()
.from(schema.sources)
.where(eq(schema.sources.domain, source.domain))
.limit(1)
if (existing) {
if (existing.length > 0) {
skipped++
continue
}
// Insert new source
await new Promise<void>((resolve, reject) => {
db.run(
`INSERT INTO sources (domain, title, risk_level, status, description, created_at)
VALUES (?, ?, ?, 'verified', ?, datetime('now'))`,
[source.domain, source.domain, source.risk_level, source.description || ''],
function(err) {
if (err) reject(err)
else resolve()
}
)
})
imported++
try {
const url = `https://${source.domain}`
await db.insert(schema.sources).values({
url,
domain: source.domain,
title: source.domain,
description: source.description || `Imported source: ${source.domain}`,
type: 'website',
status: 'pending',
riskLevel: source.riskLevel,
language: 'sk',
reportedBy: 'bulk-import'
})
imported++
} catch (error) {
console.error('Failed to import source:', source.domain, error)
skipped++
}
}
res.json({
success: true,
success: true,
imported,
skipped,
total: sources.length
message: `Imported ${imported} sources, skipped ${skipped}`
})
} catch (error) {
} catch (error: any) {
console.error('Bulk import error:', error)
res.status(500).json({ error: "Import failed" })
} finally {
db.close()
}
}