1737 lines
45 KiB
Markdown
1737 lines
45 KiB
Markdown
# Yakıt Takip Modülü - Kapsamlı Proje Dokümantasyonu
|
||
|
||
## 📋 İçerik Tablosu
|
||
1. [Proje Genel Bakış](#proje-genel-bakış)
|
||
2. [Proje Süreçleri](#proje-süreçleri)
|
||
3. [Sistem Mimarisi](#sistem-mimarisi)
|
||
4. [Kullanıcı Rolleri ve Yetkileri](#kullanıcı-rolleri-ve-yetkileri)
|
||
5. [İş Akışları](#iş-akışları)
|
||
6. [Teknoloji Stack](#teknoloji-stack)
|
||
7. [Geliştirme Süreçleri](#geliştirme-süreçleri)
|
||
8. [Deployment ve Yönetim](#deployment-ve-yönetim)
|
||
9. [Veritabanı Şeması](#veritabanı-şeması)
|
||
10. [API Dokümantasyonu](#api-dokümantasyonu)
|
||
11. [Güvenlik](#güvenlik)
|
||
12. [Sorun Giderme](#sorun-giderme)
|
||
|
||
---
|
||
|
||
## 🎯 Proje Genel Bakış
|
||
|
||
Yakıt Takip Modülü, 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
|
||
```bash
|
||
# 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:5005
|
||
# Backend API: http://localhost:3005
|
||
```
|
||
|
||
#### 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
|
||
```bash
|
||
# 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ı
|
||
```bash
|
||
# 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ı
|
||
```svelte
|
||
<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ı
|
||
```javascript
|
||
// 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
|
||
```bash
|
||
# 1. Production build
|
||
npm run build
|
||
|
||
# 2. Preview test
|
||
npm run preview
|
||
|
||
# 3. Production start
|
||
npm start
|
||
```
|
||
|
||
#### Environment Configuration
|
||
```bash
|
||
# .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
|
||
# 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"]
|
||
```
|
||
|
||
```yaml
|
||
# 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
|
||
```javascript
|
||
// 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
|
||
```bash
|
||
#!/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
|
||
1. **Veritabanı Kurtarma**: Yedek dosyasından geri yükleme
|
||
2. **Session Recovery**: Oturum bilgilerini yeniden oluşturma
|
||
3. **File System Recovery**: Dosya sistemi kontrolü ve onarımı
|
||
4. **Service Recovery**: Servislerin yeniden başlatılması
|
||
|
||
---
|
||
|
||
## 🗄️ Veritabanı Şeması
|
||
|
||
### 1. Tablo Yapıları
|
||
|
||
#### users (Kullanıcılar)
|
||
```sql
|
||
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)
|
||
```sql
|
||
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)
|
||
```sql
|
||
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ı)
|
||
```sql
|
||
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)
|
||
```sql
|
||
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)
|
||
```sql
|
||
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ı)
|
||
```sql
|
||
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ı)
|
||
```sql
|
||
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
|
||
```sql
|
||
-- 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
|
||
```sql
|
||
-- 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
|
||
```sql
|
||
-- 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**:
|
||
```json
|
||
{
|
||
"username": "string",
|
||
"password": "string"
|
||
}
|
||
```
|
||
|
||
**Response** (200 OK):
|
||
```json
|
||
{
|
||
"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 gerekli
|
||
- `401 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):
|
||
```json
|
||
{
|
||
"message": "Çıkış başarılı."
|
||
}
|
||
```
|
||
|
||
#### GET /api/user
|
||
**Açıklama**: Mevcut kullanıcı bilgilerini getirir
|
||
|
||
**Headers**: Requires valid session
|
||
|
||
**Response** (200 OK):
|
||
```json
|
||
{
|
||
"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):
|
||
```json
|
||
{
|
||
"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**:
|
||
```json
|
||
{
|
||
"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, rejected
|
||
- `date_from`: Başlangıç tarihi
|
||
- `date_to`: Bitiş tarihi
|
||
|
||
**Response** (200 OK):
|
||
```json
|
||
{
|
||
"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**:
|
||
```json
|
||
{
|
||
"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**:
|
||
```json
|
||
{
|
||
"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**:
|
||
```json
|
||
{
|
||
"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**:
|
||
```json
|
||
{
|
||
"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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
// CORS configuration
|
||
const corsOptions = {
|
||
origin: process.env.NODE_ENV === 'production'
|
||
? 'https://your-domain.com'
|
||
: ['http://localhost:5005', 'http://localhost:4005'],
|
||
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ı**:
|
||
```bash
|
||
# 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**:
|
||
```javascript
|
||
// 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**:
|
||
```javascript
|
||
// 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
|
||
```sql
|
||
-- 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
|
||
```javascript
|
||
// 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
|
||
```javascript
|
||
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
|
||
```javascript
|
||
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
|
||
```bash
|
||
# 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
|
||
```bash
|
||
#!/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](https://svelte.dev/docs)
|
||
- [Express.js Guide](https://expressjs.com/en/guide/)
|
||
- [SQLite Documentation](https://sqlite.org/docs.html)
|
||
- [Socket.IO Documentation](https://socket.io/docs/)
|
||
- [bcrypt Documentation](https://github.com/kelektiv/node.bcrypt.js)
|
||
|
||
### 2. Best Practices
|
||
- [Svelte Best Practices](https://svelte.dev/blog/svelte-best-practices)
|
||
- [Node.js Security Best Practices](https://github.com/goldbergyoni/nodebestpractices)
|
||
- [Database Design Patterns](https://gist.github.com/hemangn/2485125)
|
||
|
||
### 3. Training Materials
|
||
- [Internal user training guide](docs/USER_TRAINING.md)
|
||
- [Admin configuration manual](docs/ADMIN_MANUAL.md)
|
||
- [API development standards](docs/API_STANDARDS.md)
|
||
|
||
---
|
||
|
||
**Bu dokümantasyon Yakıt Takip Modülü 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* |