diff --git a/lib/db-optimizations.ts b/lib/db-optimizations.ts new file mode 100644 index 0000000..d4beeb7 --- /dev/null +++ b/lib/db-optimizations.ts @@ -0,0 +1,99 @@ +import sqlite3 from 'sqlite3' +import path from 'path' + +export async function optimizeDatabase(): Promise { + const dbPath = path.join(process.cwd(), 'database', 'antihoax.db') + const db = new sqlite3.Database(dbPath) + + try { + // Create performance indexes + const indexes = [ + 'CREATE INDEX IF NOT EXISTS idx_sources_domain ON sources(domain)', + 'CREATE INDEX IF NOT EXISTS idx_sources_status_risk ON sources(status, risk_level)', + 'CREATE INDEX IF NOT EXISTS idx_sources_created ON sources(created_at)', + 'CREATE INDEX IF NOT EXISTS idx_reports_status ON reports(status)', + 'CREATE INDEX IF NOT EXISTS idx_reports_created ON reports(created_at)', + 'CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash)', + 'CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs(created_at)', + 'CREATE INDEX IF NOT EXISTS idx_source_categories ON source_categories(source_id, category_id)' + ] + + for (const indexQuery of indexes) { + await new Promise((resolve, reject) => { + db.run(indexQuery, (err) => { + if (err) reject(err) + else resolve() + }) + }) + } + + // Analyze tables for query optimization + const analyzeTables = [ + 'ANALYZE sources', + 'ANALYZE reports', + 'ANALYZE api_keys', + 'ANALYZE audit_logs', + 'ANALYZE source_categories' + ] + + for (const analyzeQuery of analyzeTables) { + await new Promise((resolve, reject) => { + db.run(analyzeQuery, (err) => { + if (err) reject(err) + else resolve() + }) + }) + } + + // Vacuum database to optimize storage + await new Promise((resolve, reject) => { + db.run('VACUUM', (err) => { + if (err) reject(err) + else resolve() + }) + }) + + console.log('Database optimization completed successfully') + + } catch (error) { + console.error('Database optimization failed:', error) + throw error + } finally { + db.close() + } +} + +export async function getDatabaseStats(): Promise { + const dbPath = path.join(process.cwd(), 'database', 'antihoax.db') + const db = new sqlite3.Database(dbPath) + + try { + const stats = await new Promise((resolve, reject) => { + db.all(` + SELECT + name as table_name, + COUNT(*) as row_count + FROM ( + SELECT 'sources' as name UNION + SELECT 'reports' as name UNION + SELECT 'api_keys' as name UNION + SELECT 'audit_logs' as name + ) tables + `, (err, rows) => { + if (err) reject(err) + else resolve(rows) + }) + }) + + return { + tables: stats, + optimized_at: new Date().toISOString() + } + + } catch (error) { + console.error('Failed to get database stats:', error) + throw error + } finally { + db.close() + } +} \ No newline at end of file diff --git a/pages/api/admin/optimize.ts b/pages/api/admin/optimize.ts new file mode 100644 index 0000000..3f23e77 --- /dev/null +++ b/pages/api/admin/optimize.ts @@ -0,0 +1,28 @@ +import type { NextApiRequest, NextApiResponse } from "next" +import { optimizeDatabase, getDatabaseStats } from "../../../lib/db-optimizations" + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method === "POST") { + try { + await optimizeDatabase() + res.json({ + success: true, + message: "Database optimized successfully", + optimized_at: new Date().toISOString() + }) + } catch (error) { + console.error('Optimization error:', error) + res.status(500).json({ error: "Optimization failed" }) + } + } else if (req.method === "GET") { + try { + const stats = await getDatabaseStats() + res.json(stats) + } catch (error) { + console.error('Stats error:', error) + res.status(500).json({ error: "Failed to get database stats" }) + } + } else { + res.status(405).json({ error: "Method not allowed" }) + } +} \ No newline at end of file