From bb9031fb317f7bc47a4efce651aa300f67ac7e5c Mon Sep 17 00:00:00 2001 From: sbilketay Date: Thu, 6 Nov 2025 19:57:42 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20Yak=C4=B1t=20fi=C5=9Fleri=20SQLite?= =?UTF-8?q?=20veritaban=C4=B1=20ba=C4=9Flant=C4=B1s=C4=B1=20kuruldu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Yakıt fişleri tablosu oluşturuldu (fuel_slips) - API tamamen SQLite veritabanı ile çalışacak şekilde güncellendi - Geçici mock data verileri tamamen kaldırıldı - Veritabanı dosyası temizlendi, proje temiz başlatılacak - Tüm CRUD operasyonları (CREATE, READ, UPDATE, DELETE) veritabanı ile entegre - JSON alanlar veritabanında TEXT olarak saklanıyor ve parse ediliyor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/routes/api/fuel-slips/+server.js | 359 +++++++++++++++++++-------- src/server.js | 27 ++ 2 files changed, 278 insertions(+), 108 deletions(-) diff --git a/src/routes/api/fuel-slips/+server.js b/src/routes/api/fuel-slips/+server.js index 3e11f1a..3f07993 100644 --- a/src/routes/api/fuel-slips/+server.js +++ b/src/routes/api/fuel-slips/+server.js @@ -1,10 +1,14 @@ import { json } from '@sveltejs/kit'; import { emitSocketEvent } from '$lib/server/socketClient.js'; -// Geçici veritabanı simülasyonu - Tüm veriler temizlendi -let fuelSlips = []; +// Veritabanı bağlantısı +const dbPath = 'db/yakit_takip.db'; +import sqlite3 from 'sqlite3'; -let nextId = 1; +// Veritabanı bağlantısı al +function getDatabase() { + return new sqlite3.Database(dbPath); +} // GET - Yakıt fişlerini listele export async function GET({ request, url }) { @@ -13,27 +17,54 @@ export async function GET({ request, url }) { const manager_id = searchParams.get('manager_id'); const fuel_manager_id = searchParams.get('fuel_manager_id'); - let filteredSlips = [...fuelSlips]; + return new Promise((resolve) => { + const db = getDatabase(); - // Status filtreleme - if (status) { - filteredSlips = filteredSlips.filter(slip => slip.status === status); - } + let query = 'SELECT * FROM fuel_slips WHERE 1=1'; + const params = []; - // Mal sorumlusu filtreleme - if (manager_id) { - filteredSlips = filteredSlips.filter(slip => slip.goods_manager_id == manager_id); - } + // Status filtreleme + if (status) { + query += ' AND status = ?'; + params.push(status); + } - // Yakıt sorumlusu filtreleme - if (fuel_manager_id) { - filteredSlips = filteredSlips.filter(slip => slip.fuel_manager_id == fuel_manager_id); - } + // Mal sorumlusu filtreleme + if (manager_id) { + query += ' AND goods_manager_id = ?'; + params.push(manager_id); + } - // Tarihe göre ters sırala - filteredSlips.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); + // Yakıt sorumlusu filtreleme + if (fuel_manager_id) { + query += ' AND fuel_manager_id = ?'; + params.push(fuel_manager_id); + } - return json({ fuelSlips: filteredSlips }); + // Tarihe göre ters sırala + query += ' ORDER BY created_at DESC'; + + db.all(query, params, (err, rows) => { + db.close(); + + if (err) { + console.error('GET fuel slips error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } + + // JSON string olarak saklanan alanları parse et + const fuelSlips = rows.map(row => ({ + ...row, + vehicle_info: row.vehicle_info ? JSON.parse(row.vehicle_info) : null, + personnel_info: row.personnel_info ? JSON.parse(row.personnel_info) : null, + goods_manager_info: row.goods_manager_info ? JSON.parse(row.goods_manager_info) : null, + fuel_manager_info: row.fuel_manager_info ? JSON.parse(row.fuel_manager_info) : null + })); + + resolve(json({ fuelSlips })); + }); + }); } // POST - Yeni yakıt fişi oluştur @@ -62,7 +93,7 @@ export async function POST({ request }) { // Araç, personel ve mal sorumlusu bilgilerini getir const baseUrl = request.url.split('/api/')[0]; - + const [vehiclesRes, unitsRes, personnelRes, goodsManagersRes] = await Promise.all([ fetch(`${baseUrl}/api/vehicles`).catch(() => null), fetch(`${baseUrl}/api/units`).catch(() => null), @@ -80,15 +111,10 @@ export async function POST({ request }) { const person = personnel.fuelPersonnel?.find(p => p.id === slipData.personnel_id); const goodsManager = goodsManagers.goodsManagers?.find(gm => gm.id === slipData.goods_manager_id); - // Yeni fiş oluştur - const newSlip = { - id: nextId++, - date: slipData.date, - force_command: slipData.force_command, - unit_id: slipData.unit_id, - unit_name: unit?.name || `Birim ${slipData.unit_id}`, - vehicle_id: slipData.vehicle_id, - vehicle_info: vehicle ? { + return new Promise((resolve) => { + const db = getDatabase(); + + const vehicleInfo = vehicle ? { brand: vehicle.brand, model: vehicle.model, plate: vehicle.plate, @@ -98,54 +124,106 @@ export async function POST({ request }) { model: 'Araç', plate: 'Bilinmiyor', year: 0 - }, - fuel_type: slipData.fuel_type, - liters: parseFloat(slipData.liters), - km: parseInt(slipData.km), - personnel_id: slipData.personnel_id, - personnel_info: person ? { + }; + + const personnelInfo = person ? { full_name: person.full_name, rank: person.rank } : { full_name: 'Bilinmeyen Personel', rank: '' - }, - goods_manager_id: slipData.goods_manager_id, - goods_manager_info: goodsManager ? { + }; + + const goodsManagerInfo = goodsManager ? { full_name: goodsManager.full_name, rank: goodsManager.rank } : { full_name: 'Bilinmeyen Mal Sorumlusu', rank: '' - }, - fuel_manager_id: slipData.fuel_manager_id, - fuel_manager_info: { full_name: 'Yakıt Sorumlusu', rank: 'Yüzbaşı' }, - status: 'pending', - notes: slipData.notes || '', - created_at: new Date().toISOString() - }; + }; - fuelSlips.push(newSlip); - console.log('✅ Fuel slip created:', newSlip); - console.log('📊 Total slips now:', fuelSlips.length); + const fuelManagerInfo = { full_name: 'Yakıt Sorumlusu', rank: 'Yüzbaşı' }; - // Socket.IO ile mal sorumlusuna bildirim gönder - const socketData = { - goods_manager_id: newSlip.goods_manager_id, - fuel_slip_id: newSlip.id, - message: `${newSlip.vehicle_info.plate} plakalı araç için yeni yakıt fişi` - }; - console.log('📢 Sending socket notification: fuel-slip-assigned', socketData); + const query = ` + INSERT INTO fuel_slips ( + date, force_command, unit_id, unit_name, vehicle_id, vehicle_info, + fuel_type, liters, km, personnel_id, personnel_info, goods_manager_id, + goods_manager_info, fuel_manager_id, fuel_manager_info, status, notes + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `; - // Socket client kullanarak bildirim gönder - const sent = emitSocketEvent('fuel-slip-assigned', socketData); - if (!sent) { - console.warn('⚠️ Socket notification could not be sent'); - } + const params = [ + slipData.date, + slipData.force_command, + slipData.unit_id, + unit?.name || `Birim ${slipData.unit_id}`, + slipData.vehicle_id, + JSON.stringify(vehicleInfo), + slipData.fuel_type, + parseFloat(slipData.liters), + parseInt(slipData.km), + slipData.personnel_id, + JSON.stringify(personnelInfo), + slipData.goods_manager_id, + JSON.stringify(goodsManagerInfo), + slipData.fuel_manager_id, + JSON.stringify(fuelManagerInfo), + 'pending', + slipData.notes || '' + ]; - return json({ - message: 'Yakıt fişi başarıyla oluşturuldu.', - fuelSlip: newSlip + db.run(query, params, function(err) { + db.close(); + + if (err) { + console.error('Create fuel slip error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } + + const newSlip = { + id: this.lastID, + date: slipData.date, + force_command: slipData.force_command, + unit_id: slipData.unit_id, + unit_name: unit?.name || `Birim ${slipData.unit_id}`, + vehicle_id: slipData.vehicle_id, + vehicle_info: vehicleInfo, + fuel_type: slipData.fuel_type, + liters: parseFloat(slipData.liters), + km: parseInt(slipData.km), + personnel_id: slipData.personnel_id, + personnel_info: personnelInfo, + goods_manager_id: slipData.goods_manager_id, + goods_manager_info: goodsManagerInfo, + fuel_manager_id: slipData.fuel_manager_id, + fuel_manager_info: fuelManagerInfo, + status: 'pending', + notes: slipData.notes || '', + created_at: new Date().toISOString() + }; + + console.log('✅ Fuel slip created:', newSlip); + + // Socket.IO ile mal sorumlusuna bildirim gönder + const socketData = { + goods_manager_id: newSlip.goods_manager_id, + fuel_slip_id: newSlip.id, + message: `${newSlip.vehicle_info.plate} plakalı araç için yeni yakıt fişi` + }; + console.log('📢 Sending socket notification: fuel-slip-assigned', socketData); + + // Socket client kullanarak bildirim gönder + const sent = emitSocketEvent('fuel-slip-assigned', socketData); + if (!sent) { + console.warn('⚠️ Socket notification could not be sent'); + } + + resolve(json({ + message: 'Yakıt fişi başarıyla oluşturuldu.', + fuelSlip: newSlip + })); + }); }); } catch (error) { @@ -167,42 +245,78 @@ export async function PUT({ request }) { return json({ message: 'Geçersiz durum.' }, { status: 400 }); } - // Fiş bul - const slipIndex = fuelSlips.findIndex(slip => slip.id === parseInt(id)); - if (slipIndex === -1) { - return json({ message: 'Fiş bulunamadı.' }, { status: 404 }); - } + return new Promise((resolve) => { + const db = getDatabase(); - // Fiş güncelle - const updatedSlip = { - ...fuelSlips[slipIndex], - status, - approval_date: new Date().toISOString(), - approval_notes: approval_notes || '' - }; + const query = ` + UPDATE fuel_slips + SET status = ?, approval_date = ?, approval_notes = ? + WHERE id = ? + `; - fuelSlips[slipIndex] = updatedSlip; - console.log('✅ Fuel slip updated:', updatedSlip); + const params = [ + status, + new Date().toISOString(), + approval_notes || '', + parseInt(id) + ]; - // Socket.IO ile yakıt sorumlusuna bildirim gönder - const socketData = { - goods_manager_id: updatedSlip.goods_manager_id, - fuel_manager_id: updatedSlip.fuel_manager_id, - fuel_slip_id: updatedSlip.id, - status: updatedSlip.status, - approval_notes: updatedSlip.approval_notes - }; - console.log('📢 Sending socket notification: fuel-slip-updated', socketData); + db.run(query, params, function(err) { + if (err) { + db.close(); + console.error('Update fuel slip error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } - // Socket client kullanarak bildirim gönder - const sent = emitSocketEvent('fuel-slip-updated', socketData); - if (!sent) { - console.warn('⚠️ Socket notification could not be sent'); - } + if (this.changes === 0) { + db.close(); + resolve(json({ message: 'Fiş bulunamadı.' }, { status: 404 })); + return; + } - return json({ - message: `Fiş başarıyla ${status === 'approved' ? 'onaylandı' : 'reddedildi'}.`, - fuelSlip: updatedSlip + // Güncellenmiş fişi getir + db.get('SELECT * FROM fuel_slips WHERE id = ?', [id], (err, row) => { + db.close(); + + if (err) { + console.error('Get updated fuel slip error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } + + const updatedSlip = { + ...row, + vehicle_info: row.vehicle_info ? JSON.parse(row.vehicle_info) : null, + personnel_info: row.personnel_info ? JSON.parse(row.personnel_info) : null, + goods_manager_info: row.goods_manager_info ? JSON.parse(row.goods_manager_info) : null, + fuel_manager_info: row.fuel_manager_info ? JSON.parse(row.fuel_manager_info) : null + }; + + console.log('✅ Fuel slip updated:', updatedSlip); + + // Socket.IO ile yakıt sorumlusuna bildirim gönder + const socketData = { + goods_manager_id: updatedSlip.goods_manager_id, + fuel_manager_id: updatedSlip.fuel_manager_id, + fuel_slip_id: updatedSlip.id, + status: updatedSlip.status, + approval_notes: updatedSlip.approval_notes + }; + console.log('📢 Sending socket notification: fuel-slip-updated', socketData); + + // Socket client kullanarak bildirim gönder + const sent = emitSocketEvent('fuel-slip-updated', socketData); + if (!sent) { + console.warn('⚠️ Socket notification could not be sent'); + } + + resolve(json({ + message: `Fiş başarıyla ${status === 'approved' ? 'onaylandı' : 'reddedildi'}.`, + fuelSlip: updatedSlip + })); + }); + }); }); } catch (error) { @@ -220,23 +334,52 @@ export async function DELETE({ request }) { return json({ message: 'Fiş ID zorunludur.' }, { status: 400 }); } - // Fiş bul - const slipIndex = fuelSlips.findIndex(slip => slip.id === parseInt(id)); - if (slipIndex === -1) { - return json({ message: 'Fiş bulunamadı.' }, { status: 404 }); - } + return new Promise((resolve) => { + const db = getDatabase(); - // Sadece pending olan fişler silinebilir - if (fuelSlips[slipIndex].status !== 'pending') { - return json({ message: 'Sadece bekleyen fişler silinebilir.' }, { status: 400 }); - } + // Önce fişin durumunu kontrol et + db.get('SELECT status FROM fuel_slips WHERE id = ?', [id], (err, row) => { + if (err) { + db.close(); + console.error('Check fuel slip error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } - // Fiş sil - const deletedSlip = fuelSlips.splice(slipIndex, 1)[0]; + if (!row) { + db.close(); + resolve(json({ message: 'Fiş bulunamadı.' }, { status: 404 })); + return; + } - return json({ - message: 'Fiş başarıyla silindi.', - fuelSlip: deletedSlip + // Sadece pending olan fişler silinebilir + if (row.status !== 'pending') { + db.close(); + resolve(json({ message: 'Sadece bekleyen fişler silinebilir.' }, { status: 400 })); + return; + } + + // Fiş sil + db.run('DELETE FROM fuel_slips WHERE id = ?', [id], function(err) { + db.close(); + + if (err) { + console.error('Delete fuel slip error:', err); + resolve(json({ message: 'Veritabanı hatası.' }, { status: 500 })); + return; + } + + if (this.changes === 0) { + resolve(json({ message: 'Fiş bulunamadı.' }, { status: 404 })); + return; + } + + resolve(json({ + message: 'Fiş başarıyla silindi.', + fuelSlipId: parseInt(id) + })); + }); + }); }); } catch (error) { diff --git a/src/server.js b/src/server.js index 04a10fd..33555ec 100644 --- a/src/server.js +++ b/src/server.js @@ -100,6 +100,33 @@ async function initializeDatabase() { { username: 'ibrahim_kara', password: 'kara123', role: 'goods_manager', full_name: 'İbrahim Kara' } ]; + // Yakıt fişleri tablosu + db.run(`CREATE TABLE IF NOT EXISTS fuel_slips ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + date TEXT NOT NULL, + force_command TEXT NOT NULL, + unit_id INTEGER, + unit_name TEXT, + vehicle_id INTEGER, + vehicle_info TEXT, + fuel_type TEXT NOT NULL, + liters REAL NOT NULL, + km INTEGER, + personnel_id INTEGER, + personnel_info TEXT, + goods_manager_id INTEGER, + goods_manager_info TEXT, + fuel_manager_id INTEGER, + fuel_manager_info TEXT, + status TEXT DEFAULT 'pending', + notes TEXT, + approval_date TEXT, + approval_notes TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + )`, (err) => { + if (err) reject(err); + }); + // Her kullanıcıyı kontrol et ve yoksa ekle users.forEach(async (user) => { const hashedPassword = await bcrypt.hash(user.password, 10);