45 KiB
Yakıt Takip Uygulaması - Kapsamlı Proje Dokümantasyonu
📋 İçerik Tablosu
- Proje Genel Bakış
- Proje Süreçleri
- Sistem Mimarisi
- Kullanıcı Rolleri ve Yetkileri
- İş Akışları
- Teknoloji Stack
- Geliştirme Süreçleri
- Deployment ve Yönetim
- Veritabanı Şeması
- API Dokümantasyonu
- Güvenlik
- Sorun Giderme
🎯 Proje Genel Bakış
Yakıt Takip Uygulaması, akaryakıt istasyonları için geliştirilmiş, modern ve kullanıcı dostu bir yönetim sistemidir. Sistem, yakıt ikmal süreçlerini dijitalleştirerek verimliliği artırmayı ve süreç takibini kolaylaştırmayı hedefler.
Ana Hedefler
- Dijital Dönüşüm: Kağıt bazlı süreçlerin dijitalleştirilmesi
- Verimlilik Artışı: İş süreçlerinin otomasyonu ve hızlandırılması
- Şeffaflık: Tüm işlemlerin kayıt altına alınması ve takip edilebilirliği
- Rol Bazlı Erişim: Kullanıcı yetkilendirme ile güvenlik ve düzenleme
Temel Özellikler
- Kullanıcı Rolleri: Admin, Yakıt Sorumlusu, Mal Sorumlusu
- Modern Arayüz: Svelte tabanlı, responsive tasarım
- Güvenli Oturum Yönetimi: Şifrelenmiş veri saklama
- Real-time Bildirimler: Socket.IO ile anlık iletişim
- PDF Raporlama: Otomatik fiş ve rapor oluşturma
- Veritabanı Yönetimi: SQLite ile hafif ve verimli depolama
🔄 Proje Süreçleri
1. Geliştirme Süreçleri
1.1 Development Ortamı Kurulumu
# 1. Proje klonlama
git clone <repository-url>
cd ytp-glm
# 2. Bağımlılık yükleme
npm install
# 3. Geliştirme sunucusu başlatma
npm run dev
# 4. Tarayıcıda açma
# Frontend: http://localhost:5173
# Backend API: http://localhost:3000
1.2 Development Workflow
1. Özellik Geliştirme
├── Branch oluşturma: git checkout -b feature/ozellik-adi
├── Kod geliştirme
├── Test etme
├── Commit: git commit -m "feat: yeni özellik eklendi"
└── Push: git push origin feature/ozellik-adi
2. Code Review
├── Pull Request oluşturma
├── Review süreci
├── Değişiklikler (gerekirse)
└── Merge to main
3. Deployment
├── Build: npm run build
├── Test: npm run preview
└── Production'a gönderme
2. İş Süreçleri
2.1 Kullanıcı Yönetimi Süreci (Admin)
Başlangıç
↓
Admin Girişi
↓
Kullanıcı Yönetimi Ekranı
↓
Kullanıcı Seçimi:
├── Yeni Kullanıcı Ekle
├── Mevcut Kullanıcı Düzenle
└── Kullanıcı Sil
↓
Form Doldurma:
├── Kullanıcı Adı
├── Şifre
├── Rol Seçimi
└── Ad Soyad
↓
Validasyon ve Kaydetme
↓
Sistem Bildirimi
↓
Bitiş
2.2 Yakıt Fişi Oluşturma Süreci
Başlangıç
↓
Yakıt Sorumlusu Girişi
↓
Ana Panel → "Yeni Fiş"
↓
Form Doldurma:
├─ Tarih ve Saat Seçimi
├─ Kuvvet Komutanlığı Seçimi
├─ Birlik/Bölük Seçimi
├─ Araç Seçimi
│ ├─ Plaka
│ ├─ Araç Tipi
│ └─ Araç Kimlik No
├─ Yakıt Bilgileri
│ ├─ Yakıt Tipi (Motorin/Benzin)
│ ├─ Miktar (LT)
│ └─ Birim Fiyat
├─ Personel Bilgileri
│ ├─ Yakıt Alan Personel
│ └─ Birlik bilgileri
└─ Mal Sorumlusu Atama
↓
Validasyon Kontrolü
↓
Veritabanı Kaydı
↓
Mal Sorumlusuna Bildirim
↓
PDF Fiş Oluşturma (Otomatik)
↓
Yakıt Sorumlusuna Onay
↓
Sistem Kaydı Tamamla
↓
Bitiş
2.3 Fiş Onay Süreci (Mal Sorumlusu)
Başlangıç
↓
Mal Sorumlusu Girişi
↓
"Atanan Fişler" Listesi
↓
Fiş Seçimi ve Detay İnceleme
↓
Bilgi Kontrolü:
├─ Araç Bilgileri
├─ Yakıt Miktarı
├─ Tarih ve Saat
├─ Personel Bilgileri
└─ Maliyet Bilgileri
↓
Karar Verme:
├─ ✅ Onayla
│ ├─ Durum: approved
│ ├─ Stok düşürme
│ ├─ Kayıt güncelleme
│ └─ Yakıt sorumlusuna bildirim
└─ ❌ Reddet
├─ Gerekçe girme
├─ Durum: rejected
├─ Kayıt güncelleme
└─ Yakıt sorumlusuna bildirim
↓
İşlem Kaydı Oluşturma
↓
Real-time Bildirim Gönderme
↓
Bitiş
2.4 Real-time Bildirim Süreci
Olay Tetiklenir
├─ Yeni fiş oluşturuldu
├─ Fiş onaylandı/reddedildi
├─ Kullanıcı eklendi/güncellendi
└─ Sistem hatası oluştu
↓
Server Event Oluştur
↓
Socket.IO Event Emit
├─ ilgili kullanıcılara gönder
├─ rol bazlı filtreleme
└─ client-side güncelleme
↓
Client Güncellenmesi
├─ UI güncelleme
├─ Bildirim gösterme
├─ Liste yenileme
└─ Sayfa yönlendirme
↓
Kullanıcı Bilgilendirme
↓
Event Log Kaydı
↓
Bitiş
3. Veri Yönetimi Süreçleri
3.1 Veritabanı Yedekleme Süreci
Otomatik Yedekleme (Günlük)
↓
Veritabanı Kopyala
↓
Tarihli Klasöre Taşı
↓
30 Günlük Saklama Politikası
↓
Eski Yedekleri Sil
3.2 Veri Sintileme Süreci
Dönemsel Raporlama (Aylık)
↓
Toplam Yakıt Miktarı
↓
Maliyet Analizi
↓
Kullanıcı Bazlı İstatistikler
↓
Excel/PDF Rapor Oluşturma
↓
Yönetim Raporu
🏗️ Sistem Mimarisi
Mimari Diyagram
┌─────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Admin │ │ Fuel │ │ Goods │ │
│ │ Interface │ │ Manager │ │ Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│ HTTP/WebSocket
┌─────────────────────┴───────────────────────────────────────┐
│ APPLICATION LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SvelteKit │ │ Express.js │ │ Socket.IO │ │
│ │ Frontend │ │ Backend │ │ Real-time │ │
│ │ SPA │ │ REST API │ │ Events │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────┴───────────────────────────────────────┐
│ DATA LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SQLite3 │ │ bcrypt │ │ PDFKit │ │
│ │ Database │ │ Password │ │ Document │ │
│ │ Storage │ │ Hashing │ │ Generation │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Katmanların Sorumlulukları
Client Layer (İstemci Katmanı)
- UI Components: Kullanıcı arayüz bileşenleri
- State Management: Uygulama durumu yönetimi
- Routing: Sayfa yönlendirme
- API Client: Backend ile iletişim
- Socket Client: Real-time bildirimler
Application Layer (Uygulama Katmanı)
- Authentication: Kullanıcı kimlik doğrulama
- Authorization: Rol bazlı yetkilendirme
- Business Logic: İş kuralları ve süreçler
- API Endpoints: REST servisi
- Real-time Events: Socket.IO olay yönetimi
Data Layer (Veri Katmanı)
- Data Storage: Veri kalıcılığı
- Data Validation: Veri doğrulama
- Security: Şifreleme ve güvenlik
- Document Generation: PDF oluşturma
👥 Kullanıcı Rolleri ve Yetkileri
1. Admin (Sistem Yöneticisi)
Kullanıcı Kodu: admin / admin123
Yetkileri:
- ✅ Kullanıcı Yönetimi: Tüm kullanıcıları ekleme/güncelleme/silme
- ✅ Rol Atama: Kullanıcı rollerini belirleme
- ✅ Araç Yönetimi: Araç kayıtlarını ekleme/güncelleme/silme
- ✅ Birlik Yönetimi: Askeri birlik bilgilerini yönetme
- ✅ Personel Yönetimi: Personel kayıtlarını yönetme
- ✅ Sistem Ayarları: Konfigürasyon yönetimi
- ✅ Raporlama: Tüm verilere erişim ve raporlama
- ✅ Veritabanı: Sistem veritabanı yönetimi
- ❌ Yakıt Fişi: Fiş oluşturma yetkisi yok
- ❌ Onay Süreci: Fiş onaylama yetkisi yok
Kullanım Alanları:
- Sistem kurulum ve bakım
- Kullanıcı hesap yönetimi
- Temel veri girişi ve güncelleme
- Sistem analizi ve raporlama
- Yedekleme ve güvenlik yönetimi
2. Yakıt Sorumlusu (Fuel Manager)
Kullanıcı Kodu: fuel / fuel123
Yetkileri:
- ✅ Yakıt Fişi Oluşturma: Yeni yakıt fişleri oluşturma
- ✅ Fiş Takibi: Oluşturulan fişlerin durumunu izleme
- ✅ PDF İndirme: Fişlerin PDF kopyasını indirme
- ✅ Kaynak Görüntüleme: Araç, birlik, personel bilgilerini görme
- ✅ Tarihçe Geçmişi: Önceki işlemleri görüntüleme
- ✅ Dashboard: Kendi istatistiklerini görme
- ❌ Kullanıcı Yönetimi: Kullanıcı işlemleri yapamaz
- ❌ Onaylama: Fişleri onaylama yetkisi yok
- ❌ Veri Düzenleme: Temel verileri düzenleyemez
- ❌ Diğer Kullanıcılar: Başka kullanıcıların verilerini göremez
Kullanım Alanları:
- Günlük yakıt ikmal işlemleri
- Yakıt fişi oluşturma ve takip
- Raporlama ve stok takibi
- Araç kullanım kayıtları
3. Mal Sorumlusu (Goods Manager)
Kullanıcı Kodu: goods / goods123
Yetkileri:
- ✅ Atanan Fişler: Sadece kendisine atanan fişleri görme
- ✅ Onaylama: Fişleri onaylama/reddetme
- ✅ Gerekçe Ekleme: Reddetme gerekçesi belirleme
- ✅ Arşivleme: Onaylanan/reddedilen fişleri arşivleme
- ✅ Bildirim Yönetimi: Bildirimleri görüntüleme
- ✅ Raporlama: Kendi işlem geçmişini görme
- ❌ Fiş Oluşturma: Yeni fiş oluşturamaz
- ❌ Kullanıcı Yönetimi: Kullanıcı işlemleri yapamaz
- ❌ Genel Erişim: Atanmamış fişleri göremez
- ❌ Veri Düzenleme: Sistem verilerini düzenleyemez
Kullanım Alanları:
- Yakıt ikmal onay süreçleri
- Stok takibi ve yönetimi
- Mal kontrolü ve doğrulama
- Raporlama ve analiz
🔄 İş Akışları
1. Kullanıcı Giriş ve Oturum Yönetimi
Kullanıcı Girişi
↓
Kullanıcı Adı/Şifre Kontrolü
↓
Veritabanı Doğrulaması
↓
bcrypt Şifre Karşılaştırma
↓
Session Oluşturma
↓
Role Bazlı Yönlendirme
↓
Dashboard Ekrani
2. Yakıt Fişi Oluşturma Akışı (Detaylı)
Yakıt Sorumlusu Girişi
↓
Dashboard → "Yeni Yakıt Fişi"
↓
ADIM 1: Temel Bilgiler
├─ Tarih ve Saat seçimi (otomatik/mevcut)
├─ Kuvvet Komutanlığı seçimi
└─ Birlik/Bölük seçimi
↓
ADIM 2: Araç Bilgileri
├─ Araç seçimi (dropdown)
├─ Plaka bilgisi (otomatik doldur)
├─ Araç tipi (otomatik)
└─ Araç kimlik no (otomatik)
↓
ADIM 3: Yakıt Bilgileri
├─ Yakıt tipi seçimi (Motorin/Benzin)
├─ Miktar girme (LT cinsinden)
├─ Birim fiyat (otomatik/sistem)
└─ Toplam tutar (hesaplanan)
↓
ADIM 4: Personel Bilgileri
├─ Yakıt alan personel seçimi
├─ Personel kimlik no
├─ Rütbe ve unvan
└─ Birlik bilgileri
↓
ADIM 5: Atama ve Onay
├─ Mal sorumlusu seçimi
├─ Açıklama/Not girme
└─ Önizleme
↓
Validasyon Kontrolleri
├─ Zorunlu alanlar
├─ Veri formatları
├─ Mantıksal kontroller
└─ Stok durumu
↓
"Kaydet ve Onaya Gönder"
↓
Veritabanı Kayıt
├─ fuel_slips tablosuna ekle
├─ Durum: pending
├─ Oluşturulma zamanı
└─ Atanan kişi bilgisi
↓
Socket.IO Bildirim
├─ Mal sorumlusuna bildirim
├─ Real-time update
└─ Dashboard güncelleme
↓
PDF Fiş Oluşturma
├─ PDFKit kullanarak
├─ Standart formatta
├─ Sayaç no oluştur
└─ Kaydet ve indirme linki
↓
Başarılı Bildirimi
└─ Listeye yönlendirme
3. Mal Sorumlusu Onay Akışı (Detaylı)
Mal Sorumlusu Girişi
↓
Dashboard → "Atanan Fişler"
↓
Bekleyen Fişler Listesi
├─ Fiş no
├─ Araç plakası
├─ Tarih
├─ Miktar
├─ Durum: pending
└─ Detay butonu
↓
Fiş Detayı İnceleme
├─ Araç bilgileri kontrolü
├─ Personel doğrulaması
├─ Yakıt miktarı kontrolü
├─ Tarih ve saat kontrolü
└─ Maliyet bilgileri
↓
Karar Verme
↓
SEÇENEK A: ONAYLA
├─ "Onayla" butonuna tıkla
├─ Onay penceresi (isteğe bağlı not)
├─ fuel_slips.status = approved
├─ Sayaç güncelleme
├─ Stok düşürme (loglama)
├─ İşlem kaydı oluştur
└─ Yakıt sorumlusuna bildirim
SEÇENEK B: REDDET
├─ "Reddet" butonuna tıkla
├─ Gerekçe girme zorunlu
├─ fuel_slips.status = rejected
├─ Gerekçe kaydetme
├─ İşlem kaydı oluştur
└─ Yakıt sorumlusuna bildirim
↓
Real-time Bildirim
├─ Socket.IO event
├─ İlgili kullanıcıya gönder
├─ Dashboard güncelleme
└─ Bildirim göster
↓
Liste Güncellemesi
├─ Fişi "bekleyen" listeden çıkar
├─ "işlenmiş" listesine ekle
├─ Sayfa yenileme
└─ Filtreleme
4. Real-time İletişim Akışı
Olay Oluşur
├─ Kullanıcı login/logout
├─ Yeni fiş oluşturulur
├─ Fiş onaylanır/reddedilir
├─ Sistem hatası oluşur
└─ Bakım modu aktif/pasif
↓
Server-Side Event Handler
├─ Event tipi belirleme
├─ Hedef kitleyi belirle
├─ Data hazırlama
└─ Security kontrolü
↓
Socket.IO Emit
├─ io.to(socketId).emit()
├─ io.to(room).emit()
├─ io.broadcast.emit()
└─ Event formatlama
↓
Client-Side Receiver
├─ Socket listener
├─ Event parsing
├─ UI güncelleme
├─ Bildirim gösterme
├─ Storage güncelleme
└─ Navigation (gerekirse)
↓
Kullanıcı Etkileşimi
├─ Bildirimi görür
├─ Link tıklarsa yönlendirme
├─ İşlem yapar
└─ Event log kaydı
🛠️ Teknoloji Stack
Frontend Stack
| Teknoloji | Sürüm | Kullanım Amacı |
|---|---|---|
| Svelte | 4.2.20 | Reactive UI components, State management |
| SvelteKit | 1.30.4 | Full-stack framework, Routing, SSR |
| Vite | 4.4.2 | Build tool, Development server |
| CSS3 | - | Custom styling, Responsive design |
Backend Stack
| Teknoloji | Sürüm | Kullanım Amacı |
|---|---|---|
| Node.js | 18+ | Runtime environment |
| Express.js | 4.18.2 | Web framework, API server |
| Socket.IO | 4.7.2 | Real-time communication |
| SQLite3 | 5.1.6 | Database engine |
Security & Utils
| Teknoloji | Sürüm | Kullanım Amacı |
|---|---|---|
| bcrypt | 5.1.0 | Password hashing |
| express-session | 1.17.3 | Session management |
| PDFKit | - | PDF document generation |
Development Tools
| Teknoloji | Sürüm | Kullanım Amacı |
|---|---|---|
| nodemon | 3.0.1 | Development server auto-restart |
| concurrently | 8.2.0 | Run multiple scripts together |
🚀 Geliştirme Süreçleri
1. Development Ortamı
Gereksinimler
# Sistem gereksinimleri
Node.js >= 18.0.0
npm >= 8.0.0 veya yarn >= 1.22.0
# Opsiyonel geliştirme araçları
VS Code + Svelte Extension
Postman (API testing)
SQLite Browser (Database viewer)
Kurulum Adımları
# 1. Proje klonlama
git clone <repository-url>
cd ytp-glm
# 2. Bağımlılık yükleme
npm install
# 3. Environment variables (isteğe bağlı)
cp .env.example .env
# .env dosyasını düzenle
# 4. Development sunucusunu başlatma
npm run dev
2. Proje Yapısı ve Organizasyonu
ytp-glm/
├── src/ # Kaynak kodları
│ ├── lib/ # Svelte kitaplıkları
│ │ ├── components/ # Paylaşılan bileşenler
│ │ ├── stores/ # State management (writable)
│ │ ├── utils/ # Yardımcı fonksiyonlar
│ │ └── api/ # API client fonksiyonları
│ ├── routes/ # SvelteKit sayfa route'ları
│ │ ├── +layout.svelte # Ana layout
│ │ ├── +page.svelte # Login sayfası
│ │ ├── dashboard/ # Dashboard pages
│ │ │ ├── +page.svelte # Dashboard ana
│ │ │ ├── vehicles/ # Araç yönetimi
│ │ │ ├── units/ # Birlik yönetimi
│ │ │ ├── personnel/ # Personel yönetimi
│ │ │ └── goods-managers/ # Mal sorumluları
│ │ ├── fuel-slips/ # Yakıt fişleri
│ │ ├── goods-manager/ # Mal sorumlusu paneli
│ │ └── api/ # API route'ları
│ │ ├── login/+server.js
│ │ ├── logout/+server.js
│ │ ├── user/+server.js
│ │ ├── fuel-slips/+server.js
│ │ ├── vehicles/+server.js
│ │ ├── units/+server.js
│ │ ├── fuel-personnel/+server.js
│ │ └── goods-managers/+server.js
│ ├── app.html # Ana HTML template
│ ├── app.css # Global stiller
│ ├── hooks.server.js # Server-side hooks
│ └── server.js # Express sunucusu
├── static/ # Statik dosyalar
│ ├── favicon.ico # Favicon
│ └── assets/ # Assets (images, icons)
├── db/ # Veritabanı dosyaları
│ └── yakit_takip.db # SQLite veritabanı
├── docs/ # Dokümantasyon
│ ├── PROJECT_PROCESSES.md # Proje süreçleri
│ ├── API_DOCUMENTATION.md # API dokümantasyonu
│ └── USER_GUIDE.md # Kullanıcı rehberi
├── package.json # Proje bağımlılıkları
├── package-lock.json # Bağımlılık kilit dosyası
├── svelte.config.js # Svelte konfigürasyonu
├── vite.config.js # Vite konfigürasyonu
├── .gitignore # Git ignore dosyası
├── README.md # Proje dokümantasyonu
└── KNOWLEDGE_BASE.md # Bilgi bankası
3. Code Conventions ve Standartlar
Svelte Component Yapısı
<script>
// 1. Import statements
import { onMount } from 'svelte';
// 2. Props tanımlama
export let prop1;
// 3. State variables
let localVariable = 'value';
// 4. Reactive statements
$: computedValue = prop1 * 2;
// 5. Functions
function handleClick() {
// Event handler
}
// 6. Lifecycle
onMount(() => {
// Component mount edildiğinde
});
</script>
<!-- 1. Main structure -->
<div class="container">
<!-- 2. Conditional rendering -->
{#if condition}
<p>Koşul doğru</p>
{:else}
<p>Koşul yanlış</p>
{/if}
<!-- 3. Loops -->
{#each items as item (item.id)}
<p>{item.name}</p>
{/each}
</div>
<!-- 4. Event handlers -->
<button on:click={handleClick}>
Click me
</button>
<!-- 5. Styles -->
<style>
.container {
padding: 1rem;
}
</style>
JavaScript/TypeScript Standartları
// 1. ES6+ syntax kullanımı
// Template literals, arrow functions, destructuring
// 2. Async/await error handling
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Data fetch error:', error);
throw error;
}
}
// 3. Validasyon fonksiyonları
function validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// 4. API client structure
export const apiClient = {
get: async (endpoint) => {
const response = await fetch(`/api${endpoint}`);
return response.json();
},
post: async (endpoint, data) => {
const response = await fetch(`/api${endpoint}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
return response.json();
}
};
4. Testing ve Quality Assurance
Test Katmanları
Testing Pyramid
↓
E2E Tests (End-to-End) ← Playwright
├─ User workflows
├─ Critical paths
└─ Browser testing
↓
Integration Tests ← API Testing
├─ API endpoints
├─ Database operations
└─ Socket.IO events
↓
Unit Tests ← Jest/Vitest
├─ Utility functions
├─ Component logic
└─ Business rules
Quality Checklist
- Code review tamamlanmış
- Unit tests geçiyor
- Integration tests geçiyor
- Browser compatibility kontrolü
- Performance testleri
- Security audit
- Documentation güncel
- Build başarılı
🌐 Deployment ve Yönetim
1. Production Deployment
Build Süreci
# 1. Production build
npm run build
# 2. Preview test
npm run preview
# 3. Production start
npm start
Environment Configuration
# .env.production
NODE_ENV=production
PORT=3000
SESSION_SECRET=your-production-secret
DB_PATH=./production_yakit_takip.db
CORS_ORIGIN=https://your-domain.com
2. Docker Deployment (Opsiyonel)
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
# docker-compose.yml
version: '3.8'
services:
ytp-app:
build: .
ports:
- "3000:3000"
volumes:
- ./data:/app/data
- ./logs:/app/logs
environment:
- NODE_ENV=production
- PORT=3000
restart: unless-stopped
3. Monitoring ve Maintenance
Log Management
// log structure
const logger = {
info: (message, meta) => {
console.log(JSON.stringify({
level: 'info',
message,
timestamp: new Date().toISOString(),
...meta
}));
},
error: (message, error) => {
console.error(JSON.stringify({
level: 'error',
message,
stack: error.stack,
timestamp: new Date().toISOString()
}));
}
};
Performance Monitoring
- Response time tracking
- Memory usage monitoring
- Database query performance
- Socket.IO connection health
- Error rate tracking
4. Backup ve Disaster Recovery
Database Backup Strategy
#!/bin/bash
# backup.sh - Daily backup script
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/ytp"
DB_FILE="./yakit_takip.db"
# Create backup directory
mkdir -p $BACKUP_DIR
# Create backup
sqlite3 $DB_FILE ".backup $BACKUP_DIR/yakit_backup_$DATE.db"
# Keep only last 30 days
find $BACKUP_DIR -name "yakit_backup_*.db" -mtime +30 -delete
echo "Backup completed: $BACKUP_DIR/yakit_backup_$DATE.db"
Recovery Procedures
- Veritabanı Kurtarma: Yedek dosyasından geri yükleme
- Session Recovery: Oturum bilgilerini yeniden oluşturma
- File System Recovery: Dosya sistemi kontrolü ve onarımı
- Service Recovery: Servislerin yeniden başlatılması
🗄️ Veritabanı Şeması
1. Tablo Yapıları
users (Kullanıcılar)
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL, -- bcrypt hash
role TEXT NOT NULL, -- admin, fuel_manager, goods_manager
full_name TEXT,
email TEXT,
phone TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_login DATETIME,
is_active BOOLEAN DEFAULT 1
);
vehicles (Araçlar)
CREATE TABLE vehicles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
plate TEXT UNIQUE NOT NULL, -- Plaka
vehicle_type TEXT NOT NULL, -- Araç tipi
brand TEXT, -- Marka
model TEXT, -- Model
year INTEGER, -- Üretim yılı
fuel_capacity INTEGER, -- Yakıt kapasitesi
unit_id INTEGER, -- Birlik ID
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (unit_id) REFERENCES units(id)
);
units (Birlikler)
CREATE TABLE units (
id INTEGER PRIMARY KEY AUTOINCREMENT,
unit_name TEXT UNIQUE NOT NULL, -- Birlik adı
unit_type TEXT NOT NULL, -- Birlik tipi
command_id INTEGER, -- Üst birlik
location TEXT, -- Konum
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (command_id) REFERENCES commands(id)
);
commands (Kuvvet Komutanlıkları)
CREATE TABLE commands (
id INTEGER PRIMARY KEY AUTOINCREMENT,
command_name TEXT UNIQUE NOT NULL, -- Kuvvet adı
command_type TEXT NOT NULL, -- Kuvvet tipi
headquarters TEXT, -- Karargah
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1
);
fuel_personnel (Yakıt Personeli)
CREATE TABLE fuel_personnel (
id INTEGER PRIMARY KEY AUTOINCREMENT,
personnel_id TEXT UNIQUE NOT NULL, -- Personel kimlik no
rank TEXT, -- Rütbe
full_name TEXT NOT NULL, -- Ad soyad
position TEXT, -- Görev
unit_id INTEGER, -- Birlik
contact_info TEXT, -- İletişim bilgileri
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (unit_id) REFERENCES units(id)
);
fuel_slips (Yakıt Fişleri)
CREATE TABLE fuel_slips (
id INTEGER PRIMARY KEY AUTOINCREMENT,
slip_number TEXT UNIQUE NOT NULL, -- Fiş numarası
slip_date DATETIME NOT NULL, -- Fiş tarihi
vehicle_id INTEGER NOT NULL, -- Araç
fuel_type TEXT NOT NULL, -- Yakıt tipi (motorin/benzin)
quantity REAL NOT NULL, -- Miktar (LT)
unit_price REAL NOT NULL, -- Birim fiyat
total_amount REAL NOT NULL, -- Toplam tutar
odometer_reading INTEGER, -- Km göstergesi
fuel_personnel_id INTEGER NOT NULL, -- Yakıt alan personel
created_by INTEGER NOT NULL, -- Oluşturan kullanıcı
assigned_to INTEGER, -- Atanan mal sorumlusu
status TEXT DEFAULT 'pending', -- pending/approved/rejected
notes TEXT, -- Notlar
approval_reason TEXT, -- Onay/red gerekçesi
approved_by INTEGER, -- Onaylayan/red eden
approved_at DATETIME, -- Onay/red zamanı
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (vehicle_id) REFERENCES vehicles(id),
FOREIGN KEY (fuel_personnel_id) REFERENCES fuel_personnel(id),
FOREIGN KEY (created_by) REFERENCES users(id),
FOREIGN KEY (assigned_to) REFERENCES users(id),
FOREIGN KEY (approved_by) REFERENCES users(id)
);
goods_managers (Mal Sorumluları)
CREATE TABLE goods_managers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL, -- Kullanıcı ID'si
personnel_id TEXT UNIQUE NOT NULL, -- Personel kimlik no
rank TEXT, -- Rütbe
full_name TEXT NOT NULL, -- Ad soyad
unit_id INTEGER, -- Sorumlu olduğu birlik
appointment_date DATE, -- Atama tarihi
contact_info TEXT, -- İletişim bilgileri
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (unit_id) REFERENCES units(id)
);
audit_logs (Denetim Kayıtları)
CREATE TABLE audit_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER, -- İşlem yapan kullanıcı
action TEXT NOT NULL, -- İşlem tipi
table_name TEXT, -- Etkilenen tablo
record_id INTEGER, -- Etkilenen kayıt ID
old_values TEXT, -- Eski değerler (JSON)
new_values TEXT, -- Yeni değerler (JSON)
ip_address TEXT, -- IP adresi
user_agent TEXT, -- User agent
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
2. İlişkiler ve Indexler
Foreign Key Constraints
-- Cascade delete rules
ALTER TABLE fuel_slips
ADD CONSTRAINT fk_vehicle
FOREIGN KEY (vehicle_id) REFERENCES vehicles(id)
ON DELETE RESTRICT;
ALTER TABLE fuel_slips
ADD CONSTRAINT fk_created_by
FOREIGN KEY (created_by) REFERENCES users(id)
ON DELETE CASCADE;
Index Optimization
-- Performance için indexler
CREATE INDEX idx_fuel_slips_date ON fuel_slips(slip_date);
CREATE INDEX idx_fuel_slips_status ON fuel_slips(status);
CREATE INDEX idx_fuel_slips_assigned_to ON fuel_slips(assigned_to);
CREATE INDEX idx_vehicles_plate ON vehicles(plate);
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_audit_logs_user_created ON audit_logs(user_id, created_at);
3. Veri Bütünlüğü ve Validasyon
Trigger'lar ve Constraints
-- Tarih validasyonu
CREATE TRIGGER validate_fuel_slip_date
BEFORE INSERT ON fuel_slips
BEGIN
SELECT CASE
WHEN NEW.slip_date > CURRENT_DATE
THEN RAISE(ABORT, 'Fiş tarihi gelecekte olamaz')
END;
END;
-- Miktar validasyonu
CREATE TRIGGER validate_fuel_quantity
BEFORE INSERT ON fuel_slips
BEGIN
SELECT CASE
WHEN NEW.quantity <= 0 OR NEW.quantity > 1000
THEN RAISE(ABORT, 'Yakıt miktarı 1-1000 LT aralığında olmalı')
END;
END;
🔌 API Dokümantasyonu
1. Authentication Endpoints
POST /api/login
Açıklama: Kullanıcı girişi yapar
Request Body:
{
"username": "string",
"password": "string"
}
Response (200 OK):
{
"message": "Giriş başarılı.",
"user": {
"id": 1,
"username": "fuel",
"role": "fuel_manager",
"full_name": "Yakıt Sorumlusu"
}
}
Error Responses:
400 Bad Request: Kullanıcı adı ve şifre gerekli401 Unauthorized: Kullanıcı bulunamadı veya şifre hatalı500 Internal Server Error: Veritabanı hatası
POST /api/logout
Açıklama: Kullanıcı çıkışı yapar
Response (200 OK):
{
"message": "Çıkış başarılı."
}
GET /api/user
Açıklama: Mevcut kullanıcı bilgilerini getirir
Headers: Requires valid session
Response (200 OK):
{
"user": {
"id": 1,
"username": "fuel",
"role": "fuel_manager",
"full_name": "Yakıt Sorumlusu"
}
}
2. Vehicle Management Endpoints
GET /api/vehicles
Açıklama: Tüm araçları listeler (Admin ve Fuel Manager)
Response (200 OK):
{
"vehicles": [
{
"id": 1,
"plate": "34 ABC 123",
"vehicle_type": "Car",
"brand": "Toyota",
"model": "Corolla",
"year": 2022,
"unit_name": "1. Birlik",
"is_active": true
}
]
}
POST /api/vehicles
Açıklama: Yeni araç ekler (Admin only)
Request Body:
{
"plate": "34 XYZ 789",
"vehicle_type": "Truck",
"brand": "Mercedes",
"model": "Actros",
"year": 2023,
"unit_id": 2
}
PUT /api/vehicles/:id
Açıklama: Araç bilgilerini günceller (Admin only)
DELETE /api/vehicles/:id
Açıklama: Araç siler (Admin only)
3. Fuel Slip Management Endpoints
GET /api/fuel-slips
Açıklama: Yakıt fişlerini listeler (Role bazlı filtreleme)
Query Parameters:
status: pending, approved, rejecteddate_from: Başlangıç tarihidate_to: Bitiş tarihi
Response (200 OK):
{
"fuel_slips": [
{
"id": 1,
"slip_number": "YS-2024-001",
"slip_date": "2024-01-15T10:30:00Z",
"vehicle_plate": "34 ABC 123",
"fuel_type": "motorin",
"quantity": 50.5,
"total_amount": 2500.00,
"status": "pending",
"assigned_to_name": "Mal Sorumlusu",
"created_by_name": "Yakıt Sorumlusu"
}
],
"total": 1,
"page": 1,
"limit": 20
}
POST /api/fuel-slips
Açıklama: Yeni yakıt fişi oluşturur (Fuel Manager only)
Request Body:
{
"slip_date": "2024-01-15T10:30:00Z",
"vehicle_id": 1,
"fuel_type": "motorin",
"quantity": 50.5,
"unit_price": 49.50,
"assigned_to": 3,
"notes": "Günlük yakıt ikmali"
}
POST /api/fuel-slips/:id/approve
Açıklama: Yakıt fişini onaylar (Goods Manager only)
Request Body:
{
"approval_reason": "Belgeler tamam ve doğru"
}
POST /api/fuel-slips/:id/reject
Açıklama: Yakıt fişini reddeder (Goods Manager only)
Request Body:
{
"rejection_reason": "Yakıt miktarı uyuşmuyor"
}
4. User Management Endpoints
GET /api/users
Açıklama: Tüm kullanıcıları listeler (Admin only)
POST /api/users
Açıklama: Yeni kullanıcı ekler (Admin only)
Request Body:
{
"username": "new_fuel_manager",
"password": "newpassword123",
"role": "fuel_manager",
"full_name": "Yeni Yakıt Sorumlusu"
}
PUT /api/users/:id
Açıklama: Kullanıcı bilgilerini günceller (Admin only)
DELETE /api/users/:id
Açıklama: Kullanıcı siler (Admin only)
5. Socket.IO Events
Client-Side Events
// Connection events
socket.on('connect', () => {
console.log('Connected to server');
});
socket.on('disconnect', () => {
console.log('Disconnected from server');
});
// Fuel slip events
socket.on('fuel_slip_created', (data) => {
// Mal sorumlusuna yeni fiş bildirimi
console.log('Yeni yakıt fişi:', data);
});
socket.on('fuel_slip_approved', (data) => {
// Yakıt sorumlusuna onay bildirimi
console.log('Fiş onaylandı:', data);
});
socket.on('fuel_slip_rejected', (data) => {
// Yakıt sorumlusuna red bildirimi
console.log('Fiş reddedildi:', data);
});
Server-Side Events
// User connection management
io.on('connection', (socket) => {
socket.on('join_user_room', (userId) => {
socket.join(`user_${userId}`);
});
socket.on('disconnect', () => {
// Cleanup
});
});
// Notification functions
function notifyFuelSlipCreated(fuelSlip) {
io.to(`user_${fuelSlip.assigned_to}`).emit('fuel_slip_created', fuelSlip);
}
function notifyFuelSlipApproved(fuelSlip) {
io.to(`user_${fuelSlip.created_by}`).emit('fuel_slip_approved', fuelSlip);
}
🔒 Güvenlik
1. Authentication Security
Password Security
// bcrypt configuration
const saltRounds = 10;
async function hashPassword(password) {
return await bcrypt.hash(password, saltRounds);
}
async function comparePassword(password, hashedPassword) {
return await bcrypt.compare(password, hashedPassword);
}
// Password validation
function validatePassword(password) {
const minLength = 8;
const hasUpperCase = /[A-Z]/.test(password);
const hasLowerCase = /[a-z]/.test(password);
const hasNumbers = /\d/.test(password);
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
return password.length >= minLength &&
hasUpperCase &&
hasLowerCase &&
hasNumbers &&
hasSpecialChar;
}
Session Security
// Secure session configuration
app.use(session({
secret: process.env.SESSION_SECRET || 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production', // HTTPS only in production
httpOnly: true, // Prevent XSS
maxAge: 24 * 60 * 60 * 1000, // 24 hours
sameSite: 'strict' // CSRF protection
}
}));
// Session middleware
function requireAuth(req, res, next) {
if (!req.session || !req.session.user) {
return res.status(401).json({ message: 'Authentication required' });
}
next();
}
function requireRole(role) {
return (req, res, next) => {
if (!req.session.user || req.session.user.role !== role) {
return res.status(403).json({ message: 'Insufficient permissions' });
}
next();
}
}
2. API Security
Rate Limiting
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});
app.use('/api/', limiter);
// Stricter limit for login
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 5 login attempts
skipSuccessfulRequests: true
});
app.post('/api/login', loginLimiter, loginHandler);
Input Validation
// Validation middleware
function validateFuelSlip(req, res, next) {
const { vehicle_id, fuel_type, quantity, unit_price } = req.body;
const errors = [];
if (!vehicle_id || !Number.isInteger(vehicle_id)) {
errors.push('Valid vehicle ID is required');
}
if (!['motorin', 'benzin'].includes(fuel_type)) {
errors.push('Invalid fuel type');
}
if (!quantity || quantity <= 0 || quantity > 1000) {
errors.push('Quantity must be between 1 and 1000 liters');
}
if (!unit_price || unit_price <= 0) {
errors.push('Valid unit price is required');
}
if (errors.length > 0) {
return res.status(400).json({ errors });
}
next();
}
app.post('/api/fuel-slips', requireAuth, requireRole('fuel_manager'), validateFuelSlip, createFuelSlip);
3. Database Security
SQL Injection Prevention
// Use parameterized queries
const getFuelSlips = (userId, status) => {
return new Promise((resolve, reject) => {
const query = `
SELECT fs.*, v.plate, u.full_name as created_by_name
FROM fuel_slips fs
JOIN vehicles v ON fs.vehicle_id = v.id
JOIN users u ON fs.created_by = u.id
WHERE fs.assigned_to = ? AND fs.status = ?
ORDER BY fs.created_at DESC
`;
db.all(query, [userId, status], (err, rows) => {
if (err) reject(err);
else resolve(rows);
});
});
};
// Never use string concatenation
// ❌ WRONG: `SELECT * FROM users WHERE id = ${userId}`
// ✅ RIGHT: `SELECT * FROM users WHERE id = ?`
4. CORS Security
// CORS configuration
const corsOptions = {
origin: process.env.NODE_ENV === 'production'
? 'https://your-domain.com'
: ['http://localhost:5173', 'http://localhost:4173'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
optionsSuccessStatus: 200
};
app.use(cors(corsOptions));
🛠️ Sorun Giderme (Troubleshooting)
1. Common Issues and Solutions
Giriş Problemleri
Sorun: Kullanıcı girişi başarısız oluyor Çözüm Adımları:
# 1. Veritabanı bağlantısını kontrol et
sqlite3 yakit_takip.db ".tables"
# 2. Kullanıcı varlığını kontrol et
sqlite3 yakit_takip.db "SELECT * FROM users WHERE username='admin';"
# 3. Şifreyi güncelle
node -e "
const bcrypt = require('bcrypt');
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync('admin123', salt);
console.log('New hash:', hash);
"
Session Problemleri
Sorun: Oturumlar erken sonlanıyor Çözüm:
// Session store kontrolü
app.use(session({
store: new SQLiteStore({ db: 'sessions.db' }),
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
}
}));
Socket.IO Bağlantı Problemleri
Sorun: Real-time bildirimler çalışmıyor Çözüm:
// Client-side debug
socket.on('connect_error', (error) => {
console.error('Connection error:', error);
});
// Server-side debug
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
console.log('Handshake data:', socket.handshake);
});
2. Performance Optimization
Database Queries
-- Slow query analysis
EXPLAIN QUERY PLAN
SELECT fs.*, v.plate, u.full_name
FROM fuel_slips fs
JOIN vehicles v ON fs.vehicle_id = v.id
JOIN users u ON fs.created_by = u.id
WHERE fs.status = 'pending';
-- Index optimization
CREATE INDEX idx_fuel_slips_composite ON fuel_slips(status, created_at, assigned_to);
Memory Management
// Memory leak prevention
setInterval(() => {
// Clean up inactive sockets
const connectedSockets = io.sockets.sockets.size;
console.log('Active connections:', connectedSockets);
// Force garbage collection (development only)
if (process.env.NODE_ENV === 'development') {
global.gc();
}
}, 30000);
3. Debugging Tools
Logging Configuration
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
Health Check Endpoint
app.get('/health', (req, res) => {
const health = {
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
database: 'connected', // Check actual connection
socket_connections: io.engine.clientsCount
};
res.json(health);
});
4. Emergency Procedures
Database Corruption Recovery
# 1. Database integrity check
sqlite3 yakit_takip.db "PRAGMA integrity_check;"
# 2. Backup'tan geri yükleme
cp backups/yakit_backup_latest.db yakit_takip.db
# 3. Rebuild indexes
sqlite3 yakit_takip.db "REINDEX;"
Service Recovery
#!/bin/bash
# recovery.sh - Emergency service recovery script
echo "Starting emergency recovery..."
# Kill existing processes
pkill -f "node.*server.js"
pkill -f "vite"
# Wait for processes to stop
sleep 5
# Clear locks
rm -f /tmp/ytp_*.lock
# Restart services
npm run server &
npm run client &
echo "Recovery completed. Services restarting..."
📚 Ek Kaynaklar
1. Documentation Links
- Svelte Documentation
- Express.js Guide
- SQLite Documentation
- Socket.IO Documentation
- bcrypt Documentation
2. Best Practices
3. Training Materials
Bu dokümantasyon Yakıt Takip Uygulaması projesinin kapsamlı süreçlerini ve teknik detaylarını içermektedir. Güncel kalmak için düzenli olarak gözden geçirilmeli ve güncellenmelidir.
Son güncelleme: 2024-11-05