🚀 Features Implemented: - Full-stack SvelteKit application with Express backend - Role-based authentication (Admin, Fuel Manager, Goods Manager) - Real-time notifications with Socket.IO - SQLite database with auto-initialization in /db directory - Comprehensive user management and fuel slip tracking - Responsive design with Turkish language support 🏗️ Architecture: - Frontend: Svelte + SvelteKit + Vite - Backend: Node.js + Express + Socket.IO - Database: SQLite3 with automatic schema creation - Security: bcrypt password hashing + session management - Real-time: Socket.IO for instant notifications 📁 Project Structure: - Organized documentation in /docs directory - Database files in /db directory with auto-setup - Clean separation of API routes and UI components - Comprehensive documentation including processes, architecture, and user guides 📚 Documentation: - PROJECT_PROCESSES.md: Comprehensive project documentation - KNOWLEDGE_BASE.md: Quick reference and user guide - TEST_GUIDE.md: Testing and quality assurance guide - README_ADMIN_FEATURES.md: Admin functionality guide - Full API documentation and system architecture 🔒 Security Features: - Role-based authorization system - Encrypted password storage with bcrypt - Session-based authentication - SQL injection protection with parameterized queries - CORS configuration and input validation 🎯 Key Features: - Fuel slip creation and approval workflow - Real-time notifications between users - PDF generation for fuel slips - User and vehicle management - Comprehensive audit logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
190 lines
5.2 KiB
JavaScript
190 lines
5.2 KiB
JavaScript
import { json } from '@sveltejs/kit';
|
||
|
||
// Geçici veritabanı simülasyonu
|
||
let fuelPersonnel = [
|
||
{
|
||
id: 1,
|
||
full_name: 'Ahmet Demir',
|
||
rank: 'Üsteğmen',
|
||
registration_number: '111222',
|
||
tc_kimlik: '11111111111',
|
||
phone: '05321112233',
|
||
is_active: true,
|
||
created_at: new Date().toISOString()
|
||
},
|
||
{
|
||
id: 2,
|
||
full_name: 'Mustafa Çelik',
|
||
rank: 'Astsubay',
|
||
registration_number: '333444',
|
||
tc_kimlik: '22222222222',
|
||
phone: '05334455566',
|
||
is_active: true,
|
||
created_at: new Date().toISOString()
|
||
}
|
||
];
|
||
|
||
let nextId = 3;
|
||
|
||
// GET - Tüm yakıt personelini listele
|
||
export async function GET({ request }) {
|
||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||
return json({ fuelPersonnel });
|
||
}
|
||
|
||
// POST - Yeni yakıt personeli ekle
|
||
export async function POST({ request }) {
|
||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||
|
||
try {
|
||
const {
|
||
full_name,
|
||
rank,
|
||
registration_number,
|
||
tc_kimlik,
|
||
phone
|
||
} = await request.json();
|
||
|
||
// Validasyon
|
||
if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
|
||
return json({ message: 'Tüm alanlar zorunludur.' }, { status: 400 });
|
||
}
|
||
|
||
// TC Kimlik numarası validasyonu
|
||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||
return json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' }, { status: 400 });
|
||
}
|
||
|
||
// Sicil numarası tekrar kontrolü
|
||
const existingPersonnel = fuelPersonnel.find(p =>
|
||
p.registration_number.toLowerCase() === registration_number.toLowerCase()
|
||
);
|
||
if (existingPersonnel) {
|
||
return json({ message: 'Bu sicil numarası zaten kayıtlı.' }, { status: 400 });
|
||
}
|
||
|
||
// TC Kimlik numarası tekrar kontrolü
|
||
const existingTC = fuelPersonnel.find(p => p.tc_kimlik === tc_kimlik);
|
||
if (existingTC) {
|
||
return json({ message: 'Bu TC Kimlik numarası zaten kayıtlı.' }, { status: 400 });
|
||
}
|
||
|
||
// Yeni personel oluştur
|
||
const newPersonnel = {
|
||
id: nextId++,
|
||
full_name: full_name.trim(),
|
||
rank: rank.trim(),
|
||
registration_number: registration_number.trim().toUpperCase(),
|
||
tc_kimlik: tc_kimlik.trim(),
|
||
phone: phone.trim(),
|
||
is_active: true,
|
||
created_at: new Date().toISOString()
|
||
};
|
||
|
||
fuelPersonnel.push(newPersonnel);
|
||
|
||
return json({
|
||
message: 'Yakıt personeli başarıyla eklendi.',
|
||
personnel: newPersonnel
|
||
});
|
||
|
||
} catch (error) {
|
||
return json({ message: 'Sunucu hatası.' }, { status: 500 });
|
||
}
|
||
}
|
||
|
||
// PUT - Yakıt personeli güncelle
|
||
export async function PUT({ request }) {
|
||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||
|
||
try {
|
||
const {
|
||
id,
|
||
full_name,
|
||
rank,
|
||
registration_number,
|
||
tc_kimlik,
|
||
phone,
|
||
is_active
|
||
} = await request.json();
|
||
|
||
// Validasyon
|
||
if (!id || !full_name || !rank || !registration_number || !tc_kimlik || !phone) {
|
||
return json({ message: 'Tüm alanlar zorunludur.' }, { status: 400 });
|
||
}
|
||
|
||
// TC Kimlik numarası validasyonu
|
||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||
return json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' }, { status: 400 });
|
||
}
|
||
|
||
// Personnel bul
|
||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||
if (personnelIndex === -1) {
|
||
return json({ message: 'Yakıt personeli bulunamadı.' }, { status: 404 });
|
||
}
|
||
|
||
// Sicil numarası tekrar kontrolü (diğer personeller için)
|
||
const existingPersonnel = fuelPersonnel.find(p =>
|
||
p.id !== parseInt(id) && p.registration_number.toLowerCase() === registration_number.toLowerCase()
|
||
);
|
||
if (existingPersonnel) {
|
||
return json({ message: 'Bu sicil numarası başka bir personelde kullanılıyor.' }, { status: 400 });
|
||
}
|
||
|
||
// TC Kimlik numarası tekrar kontrolü (diğer personeller için)
|
||
const existingTC = fuelPersonnel.find(p => p.id !== parseInt(id) && p.tc_kimlik === tc_kimlik);
|
||
if (existingTC) {
|
||
return json({ message: 'Bu TC Kimlik numarası başka bir personelde kullanılıyor.' }, { status: 400 });
|
||
}
|
||
|
||
// Personnel güncelle
|
||
fuelPersonnel[personnelIndex] = {
|
||
...fuelPersonnel[personnelIndex],
|
||
full_name: full_name.trim(),
|
||
rank: rank.trim(),
|
||
registration_number: registration_number.trim().toUpperCase(),
|
||
tc_kimlik: tc_kimlik.trim(),
|
||
phone: phone.trim(),
|
||
is_active: is_active !== undefined ? Boolean(is_active) : fuelPersonnel[personnelIndex].is_active
|
||
};
|
||
|
||
return json({
|
||
message: 'Yakıt personeli başarıyla güncellendi.',
|
||
personnel: fuelPersonnel[personnelIndex]
|
||
});
|
||
|
||
} catch (error) {
|
||
return json({ message: 'Sunucu hatası.' }, { status: 500 });
|
||
}
|
||
}
|
||
|
||
// DELETE - Yakıt personeli sil
|
||
export async function DELETE({ request }) {
|
||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||
|
||
try {
|
||
const { id } = await request.json();
|
||
|
||
if (!id) {
|
||
return json({ message: 'Personel ID zorunludur.' }, { status: 400 });
|
||
}
|
||
|
||
// Personnel bul
|
||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||
if (personnelIndex === -1) {
|
||
return json({ message: 'Yakıt personeli bulunamadı.' }, { status: 404 });
|
||
}
|
||
|
||
// Personnel sil
|
||
const deletedPersonnel = fuelPersonnel.splice(personnelIndex, 1)[0];
|
||
|
||
return json({
|
||
message: 'Yakıt personeli başarıyla silindi.',
|
||
personnel: deletedPersonnel
|
||
});
|
||
|
||
} catch (error) {
|
||
return json({ message: 'Sunucu hatası.' }, { status: 500 });
|
||
}
|
||
} |