65 lines
2.7 KiB
TypeScript
65 lines
2.7 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
||
import { requireAuth } from '@/lib/auth'
|
||
import { readConfig } from '@/lib/config'
|
||
import { getCloudConnection } from '@/lib/appDb'
|
||
import { createDbDumpBuffer, uploadToDropbox, uploadToGoogleDriveOAuth, uploadToGCS, backupFilename } from '@/lib/backup'
|
||
import pool from '@/lib/appDb'
|
||
|
||
export async function POST(req: NextRequest) {
|
||
const authErr = await requireAuth(req)
|
||
if (authErr) return authErr
|
||
|
||
const body = await req.json()
|
||
const { db_id, connection_id, cloud_type: inlineType, credentials: inlineCredentials, gdrive_folder_id } = body
|
||
|
||
const config = await readConfig()
|
||
const db = config.databases.find(d => d.id === db_id)
|
||
if (!db) return NextResponse.json({ ok: false, error: 'Veritabanı bulunamadı.' })
|
||
|
||
// Bağlantı kaynağı: global connection veya inline
|
||
let type: string, credentials: string, target: string
|
||
if (connection_id) {
|
||
const conn = await getCloudConnection(connection_id)
|
||
if (!conn) return NextResponse.json({ ok: false, error: 'Cloud bağlantısı bulunamadı.' })
|
||
type = conn.type
|
||
credentials = conn.credentials
|
||
target = gdrive_folder_id || conn.default_target || ''
|
||
} else {
|
||
if (!inlineCredentials?.trim()) return NextResponse.json({ ok: false, error: 'Credentials boş.' })
|
||
type = inlineType
|
||
credentials = inlineCredentials
|
||
target = gdrive_folder_id || ''
|
||
}
|
||
|
||
const filename = type === 'gdrive' ? backupFilename() : backupFilename(db.name)
|
||
|
||
try {
|
||
const buffer = await createDbDumpBuffer(db)
|
||
|
||
if (type === 'dropbox') {
|
||
await uploadToDropbox(credentials.trim(), db.name, filename, buffer)
|
||
} else if (type === 'gcs') {
|
||
await uploadToGCS(credentials, target, db.name, filename, buffer)
|
||
} else if (type === 'gdrive') {
|
||
await uploadToGoogleDriveOAuth(credentials, db.name, filename, buffer, target || undefined)
|
||
} else {
|
||
return NextResponse.json({ ok: false, error: 'Desteklenmeyen cloud türü.' })
|
||
}
|
||
|
||
await pool.query(
|
||
`INSERT INTO backup_logs (db_id, status, message, file_size) VALUES ($1, $2, $3, $4)`,
|
||
[db_id, 'success', `Manuel yedek — ${type}`, buffer.length]
|
||
)
|
||
|
||
const sizeStr = buffer.length > 1024 * 1024
|
||
? `${(buffer.length / (1024 * 1024)).toFixed(2)} MB`
|
||
: `${(buffer.length / 1024).toFixed(1)} KB`
|
||
|
||
const pathStr = type === 'gdrive' ? `${db.name}/${filename}` : filename
|
||
return NextResponse.json({ ok: true, detail: `✓ Yüklendi — ${pathStr} (${sizeStr})` })
|
||
} catch (e: any) {
|
||
await pool.query(`INSERT INTO backup_logs (db_id, status, message, file_size) VALUES ($1, $2, $3, $4)`, [db_id, 'error', e.message, 0]).catch(() => {})
|
||
return NextResponse.json({ ok: false, error: e.message })
|
||
}
|
||
}
|